Do you use git from the command line as I do? Then you might face a case when you need to jump between branches quickly. Maybe you need to merge your changes to the staging branch. Or you might have multiple active tickets: one - in review, another - under active development, and some - in QA.
If you face such cases, you know how hard it could be to remember all the fancy branch names, like JRABBR-123_feature/awesome-login
and similar. However, even with autocomplete, there is still a lot of typing for such a small thing as a branch switch. To solve this problem, git has some cool functionality: we can see all branches where we made changes recently. Let's discover it with the following one-liner as an example:
git for-each-ref --sort=-committerdate \
--format='%(refname) %(objectname:short) %(committerdate)' \
refs/heads/
And the output will be something like:
refs/heads/bugfix/another-sample 575a855 Mon Jun 27 23:16:45 2022 +0200
refs/heads/master 575a855 Mon Jun 27 23:16:45 2022 +0200
refs/heads/staging 575a855 Mon Jun 27 23:16:45 2022 +0200
refs/heads/feature/sample-branch 9c7a4e5 Mon Jun 27 15:09:00 2022 +0200
First of all, we see the for-each-ref command. Suppose not the most often git command you use. According to the documentation, the purpose of the command is to "iterate all refs that match [a provided] pattern." I won't stop much here. You can take a look at the specs if you wish.
Immediately after the command itself, we see the sort
option. Anyone who is at least a little bit familiar with programming has already guessed what is happening here: it allows us to see git references by commit date in the reverse order - precisely what we need to jump between branches. Some people might want to use authordate
here instead of committerdate
. The difference between those two is:
authordate
means a timestamp when the commit was created by the authorcommitterdate
means the last modified timestamp. This timestamp could be different fromauthordate
on your branch when you use rebase, cherry-pick or amend. I'd argue forcommitterdate
because if something changes within your branch, this value will be changed too whileauthordate
will remain the same.
The next part of the command is format
option. It is also essential as it gives us an output to work with. Thanks to nicely formatted results, we can remember a branch name and use it in the git checkout
command.
However, the process is still long. It would be great to select variants git for-each-ref
gives us directly. With programming, we can achieve that. I made git-last-branch
CLI utility for it. Here is how it works:
You can select the branch you want to switch to right in your terminal. Thanks to promptui go package navigation works both with arrows and vim-like j
k
bindings. No more boring branch name typing. No more dealing with autocomplete. Everything works smoothly and easily.
You can grab a binary from the latest release or compile from source with git clone + make. The only real pre-requirement then is golang. With asdf version manager it would be easy to setup it.
I hope to find some good build tools in the future to make automatic binary releases for you.
If you want to help enhance it, here are some todos to start with.