Git branch filtering
How to make git branch filtering more palatable


If you have more than one git branch up in the air at the same time, having a system to track them and filter them is essential. Here are the stages I went through with git branch.

xkcd reminds us that we're insane


Prefixes:

My first tip involves using a memorable prefix. For new features I name my branches with feat/. For example feat/my-new-feature. Yes the slash and the dashes are treated like any regular character. I also commonly use bug/. You can see all of the branches with git branch -a.


Sorting:

I found I wanted the most recently used branches at the bottom. Let’s add an alias to do that. In your ~/.gitconfig file, in the [alias] section, add:

rbranch = for-each-ref --sort='committerdate' --format="%20%20%(refname:short)" refs/heads/

This even adds the two spaces that you normally see with git branch.


Aliases:

I then improved things with a git alias. I use r for that, since I list all my branches fairly often.

r = rbranch

Filtering:

I previously wanted to filter things with grep. Many years ago I couldn’t get this working. I eventually ended up with:

rbranch = for-each-ref --sort='committerdate' --format="%20%20%(refname:short)" --exclude 'refs/heads/delete/*' --exclude 'refs/heads/old/*' refs/heads/

The above command filters out branches that have a short name starting with old/ or delete/, which are two prefixes I use temporarily for old branches and ones I plan to eventually delete.

Git matches on the actual ref name. Keep in mind that it uses the full refname, so if you added a --format option, remove that to see what it’s actually matching against when debugging.


Maximum count:

I don’t like filling my whole terminal when I usually only care about the last 20 or so active branches. You can use the --count option to filter this down. Unfortunately for me, I want to see the newest ones at the bottom.


Finally:

It was at this point, that I dug back into my git alias issues, and got bash pipes working. I decided to rewrite it all in terms of a shell command which is enclosed in the git alias. I also swapped out the --exclude matching for grep which can be more succinct. I’m now left with:

rbranch = ! git for-each-ref --sort='-committerdate' --format='%20%20%(refname:short)' refs/heads/ | grep -v --max-count 20 -E '^  (delete|old)/' | tac

Note that including the dash as a prefix in sort, we get this in the reverse order. We then filter those through grep, matching with -v for excludes, and also limiting the number to 20. We finally run everything through tac (which is like cat but does things in reverse order, get it?) to finish things off.


Example:

Combined with my ability to show the current git branch in PS1 I now have a pretty nifty setup.

james@hostname:~/code/mgmt (feat/new-magic)$ git r
  bug/race-condition
  feat/world-peace
  feat/remote-resource
  bug/off-by-one-error
  master
  feat/world-domination
  feat/graph-shape
  feat/mcl-provisioner

Conclusion:

I hope that makes your git filtering easier!

Happy Hacking,

James


You can follow James on Mastodon for more frequent updates and other random thoughts.
You can follow James on Twitter for more frequent updates and other random thoughts.
You can support James on GitHub if you'd like to help sustain this kind of content.
You can support James on Patreon if you'd like to help sustain this kind of content.

January 28, 2024
544 words


Categories
Tags
bash branch git linux planetfedora

Links...

M

Comments

Nothing yet.


Post a comment



(sorry but the spammers were getting too crazy!)

Thank you

Your comment has been submitted and will be published if it gets approved.

Click here to see the patch you generated.

OK