My git aliases

new & master

git new creates a new branch based on current (i.e., up-to-date) origin/master:

git fetch -q origin master
git branch ${1:?} origin/master
git checkout ${1:?}

git master checks out current origin/master (as a detached head). (See also “Don’t checkout master locally”.)

git fetch -q origin master
git checkout origin/master

Copy/paste:

git config --global alias.new '!f(){ git fetch -q origin master && git branch ${1:?} origin/master && git checkout ${1:?};};f'
git config --global alias.master '!f(){ git fetch -q origin master && git checkout origin/master;};f'

stow/unstow

Like a branch-specific “stash”. I think many people initially assume git stash will behave kind of like this, but the stash is shared across all branches.

git stow either saves your pending changes in a commit with message “stow”, or, if you’ve already stowed changes, ammends the stow commit with your new changes.

if [[ $(git log -1 --format=%B) == stowed ]]; then
  git commit -a --amend --no-edit
else
  git commit -a -m stowed
fi

git unstow undoes a stowed commit (by resetting to the commit before it):

if [[ $(git log -1 --format=%B) == stowed ]]; then
  git reset @^
else
  echo "Nothing to unstow"
fi

Copy/paste:

git config --global alias.stow '!f(){ if [[ $(git log -1 --format=%B) == "stowed" ]]; then git commit -a --amend --no-edit; else git commit -a -m stowed; fi;};f'
git config --global alias.unstow '!f(){ if [[ $(git log -1 --format=%B) == stowed ]]; then git reset @^; else echo \"Nothing to unstow\"; fi;};f'

changes

What changes have been made from origin/master?

git config --global alias.changes 'diff origin/master...'

update

Rebase your commit(s) onto master:

git config --global alias.update "pull origin master --rebase"

save

This is kind of similar to stow. If you don’t currently have a change “in progress”, it creates a new commit. Otherwise, it just ammends the “in progress” commit. “In progress” is defined as “not an ancestor of origin/master”.

if git merge-base --is-ancestor HEAD origin/master; then
  git commit -va
else
  git commit -va --amend --no-edit
fi

Copy/paste:

git config --global alias.save '!f(){ if git merge-base --is-ancestor HEAD origin/master; then git commit -va; else git commit -va --amend --no-edit; fi;};f'

TODO: Make this work better with branch pipeling.

branch-cleanup

(Technically a bash script and not an alias)

Deletes any branches that have already been merged onto master, where “merged” means either that the branch has no delta from master, or that a commit equivalent to the branch’s latest is already on master:

#!/bin/bash
set -u

git fetch --all --quiet
for b in $(git for-each-ref refs/heads --format="%(refname:short)"); do
  if [[ ! $(git cherry -v origin/master $b | grep "^+") ]]; then
    git branch -D $b
  elif git diff --exit-code --quiet "origin/master...${b}"; then
    git branch -D $b
  fi
done

Copy/paste:

# Assuming ~/bin is on your $PATH:
curl https://alecb.me/git-branch-cleanup > ~/bin/git-branch-cleanup && chmod +x ~/bin/git-branch-cleanup

 ·  April 27, 2019