I use a lot of git aliases because I work in the terminal and aliases give me short commands for common operations. They are defined in my global git config file and range from simple to powerful but twisty.
First, some basic aliases for operations I do often:
[alias]
br = branch
co = checkout
sw = switch
d = diff
di = diff
s = status -s -b --show-stash
These are simple, but others could use some explanation.
Committing
I have a few aliases for committing code. The “ci” alias provides the default option “--edit” so that even if I provide a message on the command line with “git ci -m”, it will pop me into the editor to provide more detail. “git amend” is for updating the last commit with the latest file edits I’ve made, and “git edit” is for updating the commit message on the latest commit:
[alias]
ci = commit --edit
amend = commit --amend --no-edit
edit = commit --amend --only
Returning home
I work in many repos. Many have a primary branch called “main” but in some it’s called “master”. I don’t want to have to remember which is which, so I have an alias “git ma” that returns me to the primary branch however it’s named. It uses a helper alias to find the name of the primary branch:
[alias]
# Find the name of the primary branch, either "main" or "master".
primary = "!f() { \
git branch -a | \
sed -n -E -e '/remotes.origin.ma(in|ster)$/s@remotes/origin/@@p'; \
}; f"
If you haven’t seen this style of alias before, the initial exclamation point
means it’s a shell command not a git command. Then we use shell
f() {···}; f
syntax to define a function and immediately invoke
it. This lets us use shell commands in a pipeline, access arguments with
$1
, and so on. (Fetching GitHub pull requests has
more about this technique.)
This alias uses the “git branch -a” command to list all the branches, then pipes it into the Unix sed command to find the remote one named either “main” or “master”.
With “git primary” defined, we can define the “ma” alias to switch to the primary branch and pull the latest code. I like “ma” because it’s short for both main and master, and because it feels like coming home (“Hi ma!”):
[alias]
# Switch to main or master, whichever exists, and update it.
ma = "!f() { \
git checkout $(git primary) && \
git pull; \
}; f"
For repos with an upstream, I need to pull their latest code and also push to my fork to get everything in sync. For that I have “git mma” (like ma but more):
[alias]
# Pull the upstream main/master branch and update our fork.
mma = "!f() { \
git ma && \
git pull upstream $(git primary) --ff-only && \
git push; \
}; f"
Merging and finishing branches
For personal projects, I don’t use pull requests to make changes. I work on a branch and then merge it to main. The “brmerge” alias merges a branch and then deletes the merged branch:
[alias]
# Merge a branch, and delete it here and on the origin.
brmerge = "!f() { \
: git show; \
git merge $1 && \
git branch -d $1 && \
git push origin --delete $1; \
}; f"
This shows another technique: the : git show;
command does
nothing but instructs zsh’s tab completion that this command takes the same
arguments as “git show”. In other words, the name of a branch. That argument
is available as $1
so we can use it in the aliased shell commands.
Often what I want to do is switch from my branch to main, then merge the branch. The “brmerge-” alias does that. The “-” is similar to “git switch -” which switches to the branch you last left:
[alias]
# Merge the branch we just switched from.
brmerge- = "!f() { \
git brmerge $(git rev-parse --abbrev-ref @{-1}); \
}; f"
Finally, “git brdone” is what I use from a branch that has already been merged in a pull request. I return to the main branch, and delete the work branch:
[alias]
# I'm done with this merged branch, ready to switch back to another one.
brdone = "!f() { \
: git show; \
local brname=\"$(git symbolic-ref --short HEAD)\" && \
local primary=\"$(git primary)\" && \
git checkout ${1:-$primary} && \
git pull && \
git branch -d $brname && \
git push origin --delete $brname; \
}; f"
This one is a monster, and uses “local” to define shell variables I can use in a few places.
There are other aliases in my git config file, some of which I’d even forgotten I had. Maybe you’ll find other useful pieces there.
Comments
I have ‘ci’ aliased to ‘commit –verbose’, which shows the diff in the editor. I find it useful to remind me what I did, and as a last-chance code review.
Nice, I didn’t know about
--verbose
. I’ve added it to my alias.Thank you for sharing these. It gives me some keepers for my git shortcuts, but also clarifies some git operations I was fuzzy on.
So now I’ve added branch juggling to the balls and clubs!
Add a comment: