If you are like me and use the Git command-line a lot, you will probably grow your own list of Git aliases sooner or later. This article won’t be about simple standard aliases which most of us will probably have anyways (ci -> commit
, co -> checkout
, etc.). I’d rather like to show some advanced tricks you may find useful.
Overcome the Limitations
Simple Git aliases are quite limited. Git replaces the command you typed with whatever you alias it for. This means you cannot use positional parameters or call external programs. However, there are ways around this. One way would be to create custom Git commands. These are separate files. They must be on your PATH
, start with git-
, and not have a file extension. This is useful for more extensive scripting. Most of the time, it is just easier to stick with normal Git aliases. The trick is to start the alias with an exclamation mark ‘!
‘. Git will then shell out the command, i. e. you can use shell expansion, pipes, etc.
Make the Git Log Nicer
The standard Git log command is not really that useful. It is very verbose creating multiple lines per commit. It is fairly straightforward to create your own alias for a better log output.
1l = log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%ci) %C(bold blue)<%an>%Creset'
That was easy. But my actual point is that you can now build upon this alias and create further aliases that are based on it. Here are two examples that enhance the output to draw a graphical representation.
1# graphical representation for all refs 2lga = !git l --graph --all 3 4# graphical representation for branches only 5lgb = !git l --graph --branches
The following alias shows incoming commits for your current branch. The branch must be configured to track a remote branch for the special ref @{upstream}
to work. Conversely, the same is possible to show outgoing commits you have not yet pushed.
1# log incoming commits 2li = !git l HEAD..@{upstream} 3 4# log outgoing commits 5lo = !git l @{upstream}..HEAD
Make Branch Handling Easier
From time to time, you may have to clean-up your repo removing outdated branches. Here’s a few tricks to better identify them. You can run git branch -avv
to list branches and show the latest commit messages. But this does not tell you how old they are and who made the last commit on the branch. In order to fix that we first need an alias that lists refs sorted by date and also displays the relative date, the author, and the subject.
1refs = for-each-ref --sort=-committerdate --format='%(color:red bold)%(refname:short)%(color:reset) %(color:yellow)%(committerdate:relative)%(color:reset) %(color:magenta bold)%(authorname)%(color:reset) %(color:green)%(objectname:short)%(color:reset) %(contents:subject)'
Based on this alias, we can now create two more aliases, one to show local branches and another one to show remote branches.
1# list all local branches sorted by commit date (lbs = local branches sorted) 2lbs = !git refs refs/heads 3 4# list all remote tracking branches sorted by commit date (rbs = remote branches sorted) 5rbs = !git refs refs/remotes
Here’s a sample screenshot of a git rbs
output:
The following alias is useful for listing branches that track remote branches which no longer exist. This can happen when a pull request is merged and you still have your local branch around. In most cases, these branches can just be deleted, which can also be done with an alias.
1# list outdated branches that track a branch which no longer exists 2lob = !git branch -vv | grep ': gone' | cut -d ' ' -f 3 3 4# delete outdated branches 5dob = !git lob | xargs git branch -D
Make Your Open-source Life Easier
If you are like me and enjoy contributing to open-source projects, you can make your life a little bit easier. Being a member of the Helm charts maintainers team, I test pull requests on a regular basis. This requires fetching them in the first place. Of course, I don’t want to clone the PR owner’s repo each time. That’s unnecessary because PRs also live in special branches in the target repo which Github does not really show you. The following alias fetches a PR and checks out its HEAD
directly. You need to pass the pull request ID as parameter. You’ll then end up with a detached HEAD
but that’s perfectly fine in this case.
1# fetch and checkout a Github pull request 2fp = "!f() { git fetch upstream "pull/$1/head" && git checkout FETCH_HEAD; }; f"
The alias is based on the assumption that a remote named upstream
exists. This is how I configure the repos I contribute to. Here’s what this looks like in my .git/config
for the Helm Charts repo:
1remote.upstream.url=git@github.com:kubernetes/charts.git 2remote.upstream.fetch=+refs/heads/*:refs/remotes/upstream/* 3remote.origin.url=git@github.com:unguiculus/charts.git 4remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
Here comes one last goodie. When working with open-source repos you may want to configure an e-mail address other than that in your global Git config. However, it is easy to forget that. In case you have committed something with the wrong address, here’s an alias that allows you to fix the commit (after fixing the e-mail address in the repo’s local Git config, of course).
1# re-commit resetting the author and re-using the commit message 2rci = "!f() { ref=$(git rev-parse HEAD); git reset --soft HEAD^; git commit --reset-author -C "$ref"; }; f"
More articles
fromReinhard Nägele
Your job at codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
More articles in this subject area
Discover exciting further topics and let the codecentric world inspire you.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog author
Reinhard Nägele
Do you still have questions? Just send me a message.
Do you still have questions? Just send me a message.