Overview

Get the Most out of Git Aliases

No Comments

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.

l = log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%ci) %C(bold blue)<%an>%Creset'

git l

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.

# graphical representation for all refs	 	 
lga = !git l --graph --all
 
# graphical representation for branches only	 	 
lgb = !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.

# log incoming commits
li = !git l HEAD..@{upstream}
 
# log outgoing commits
lo = !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.

refs = 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.

# list all local branches sorted by commit date (lbs = local branches sorted)
lbs = !git refs refs/heads
 
# list all remote tracking branches sorted by commit date (rbs = remote branches sorted)
rbs = !git refs refs/remotes

Here’s a sample screenshot of a git rbs output:
git rbs

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.

# list outdated branches that track a branch which no longer exists
lob = !git branch -vv | grep ': gone' | cut -d ' ' -f 3
 
# delete outdated branches
dob = !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.

# fetch and checkout a Github pull request
fp = "!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:

remote.upstream.url=git@github.com:kubernetes/charts.git
remote.upstream.fetch=+refs/heads/*:refs/remotes/upstream/*
remote.origin.url=git@github.com:unguiculus/charts.git
remote.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).

# re-commit resetting the author and re-using the commit message
rci = "!f() { ref=$(git rev-parse HEAD); git reset --soft HEAD^; git commit --reset-author -C "$ref"; }; f"
Reinhard Nägele

Reinhard is a Senior IT Consultant at codecentric’s Munich office. He can look back on about 18 years in Java development. In his projects, he is a strong proponent of automation. In recent years, he has gained substantial knowledge in infrastructure topics around Maven, Git, Jenkins, Docker, and has also spread his knowledge in trainings. Currently, he is busy looking into cluster platforms such as Kubernetes and DCOS and is excited about the new possibilities they offer. Reinhard enjoys contributing to open-source projects. He is a member of the maintainers team for Kubernetes Helm Charts.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Post by Reinhard Nägele

Continuous Integration

Deploying Pull Requests with Docker

Pull-Requests mit Docker deployen

More content about Git

Comment

Your email address will not be published. Required fields are marked *