Git Find

Posted on Feb 20, 2021

I’ve made a cool thing this week that is going to save me time at work.

I’ve realized that it is more often when I try to find out which software version a feature has been released. It is natural that when the product grows there is more features to be curious about and with a growing number of releases it is easier to loose a track of what and when.

So far, my process on finding out what and when was rather simple yet manual and I like to automate manual and repetitive tasks. First, find the commit in the log that introduced the change. It is fairly easy by either using git log or more advanced pager such as tig. Then use this commit has as an input to git tag --contains <commit hash> | head -1 and you will get the first tag that contains this commit.

I kind of a like Bash scripting and I do write tons of small scripts that help me navigate through, usually, all the boring tasks that I need to do over and over.

On this note I have pretty quickly came up with this piece:

$ cat ~/bin/git-find
#!/bin/bash

PHRASE="$1"

COMMITS=$(git log --abbrev-commit --pretty=oneline | grep "$PHRASE")

IFS=$'\n'
for c in $COMMITS; do
	hash=`echo $c | awk '{print $1}'`
	tag=`git tag --contains "$hash" | head -1`
	if [ ! -z "$tag" ]; then
		printf "%-10s" "$tag"
	else
		printf "%-10s" "None"
	fi
	echo "$c"
done

It takes a phrase as an argument and looks through the git log to find out which commit messages contain it. Then iterates through the commit ids and finds a tag for each one of them using the aforementioned git tag command.

The cool thing about git is that if there is a file called git-<command> in PATH then it can be called as git <command>. I’ve saved my script as ~/bin/git-find and so a new git command has been born.

For example if I would like to find future in Rust’s Tokio repository, I could do

➜  tokio git:(master) git find future
tokio-0.2.161121a8eb sync: ensure Mutex, RwLock, and Semaphore futures are Send + Sync (#2375)
tokio-0.2.1264e75ad1 time: Add comment about cancelation of timed out futures (#2206)
tokio-0.2.12be832f20 util: add futures-io/tokio::io compatibility layer (#2117)
tokio-0.2.115bf06f2b future: provide try_join! macro (#2169)
tokio-0.2.117079bcd6 future: provide join! macro (#2158)
(...)

One thing to know is that the better commit messages the better this command works. They have to be somewhat sane and not something like “fix” followed by “major refactoring”, etc… It must be something meaningful and I can recommend looking at conventional commits as an example.

If you are curious you’ll find git-find here

I was not aware until after I’ve written this script that it is possible to list tags along commit ids using standard git log command: git log --tags --pretty="%h %d %s" --decorate=full. However, I like my script more - obviously.