more uses for git notes, and hidden treasures in Gerrit

By , October 2, 2013 2:05 pm

I recently blogged about some tools I wrote which harness the notes feature of git to help with the process of porting commits from one branch to another. Since then I’ve discovered a couple more consumers of this functionality which are pretty interesting: palaver, and Gerrit.


It seems the tireless Mark McLoughlin, one of the leading lights of the OpenStack project, was already thinking along similar lines, and wrote a tool called palaver, which also aims to streamline the porting process, and also uses git notes to persist state pertaining to backporting projects. Upon first glance, the main differences between our tools seem to be as follows:

  • git-cherry-menu is a slightly overgrown shell-script (yuk), whereas palaver is Python (yay).
  • palaver has a nice CLI with numerous non-interactive sub-commands like palaver list merged, and palaver review which provides an interactive mode. git-cherry-menu only offers an interactive mode (which is very similar in concept to palaver review); for non-interactive querying of the current state, you have to use a separate command git-icing. Personally I prefer palaver‘s unified approach to UI design, even though it doesn’t yet have the pretty ANSI colour-coding of git-icing and git-cherry-menu.
  • Since git-icing wraps around git cherry, it can automatically detect some (but not all) commits which have already been ported to the target branch. As the name suggests, git-cherry-menu enables cherry-picking of commits, whereas that’s still on the TODO list for palaver.
  • palaver persists state by writing notes which are JSON blobs, whereas git-cherry-menu uses plain text where lines beginning with skip: are treated specially. Not much difference here: obviously JSON allows more sophisticated structuring of metadata, but has the disadvantage of being less readable if you view the notes branch via standard git tools such as git log or gitk.
  • palaver “manually” classifies commits into the following states: pass / defer / pick / proposed / merged, whereas my tools have fewer “manual” states – conceptually just skip and todo. merged is either automatically detected via git cherry, or manually flagged via a skip. I’d say my approach is marginally uglier but the automatic detection is quite a big advantage.
  • git-rnotes allows merging of someone else’s notes. That’s also on palaver‘s TODO list.

Perhaps the best way forward might be to port the remaining functionality which git-icing and git-cherry-menu offer to palaver, since the latter has a nicer interface, and is pure Python. None of this is rocket science, so hopefully it wouldn’t take too long.

It probably makes sense to keep git-rnotes separate, since it is a very simple shell-script which is useful for sharing any git notes, not just those generated during a commit porting project.

Gerrit review notes

Secondly, it turns out that Gerrit also uses git-notes, in order to annotate each reviewed change with a bunch of very useful metadata, and GitHub is clever enough to expose this metadata in its web UI, e.g.

screenshot of github web UI showing git notes

In Gerrit 2.6 and newer, this functionality was moved out from the core into a reviewnotes plugin. As a result, AFAICS its documentation seems to be buried inside a separate git repository rather than exposed as a nice web page like it used to be. However, it’s very easy to use, and OpenStack’s Gerrit instance certainly has the feature enabled.

For example, simply cd into any OpenStack git repository you happen to have checked out (or clone one first if not). Then type the following:

git fetch origin refs/notes/review:refs/notes/review
export GIT_NOTES_REF=refs/notes/review
git log

You’ll see that each non-merge commit now shows annotations like the ones in the image above, explaining how the commit made its way through the review process before getting merged by Jenkins. Perhaps the most useful piece of data in the note is the link to the relevant review on, so you can quickly navigate to it in your browser and review the er, review.

If you don’t want git log to default to showing the notes, you can omit the export GIT_NOTES_REF, and instead do:

git log --notes=refs/notes/review

If you don’t want to have to remember the slightly cryptic method for fetching notes, my git-rnotes wrapper offers simpler syntax:

git rnotes fetch origin

However, this currently requires GIT_NOTES_REF to have the right value exported.


2 Responses to “more uses for git notes, and hidden treasures in Gerrit”

Leave a Reply


Panorama Theme by Themocracy