more uses for git notes, and hidden treasures in Gerrit
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.
palaver
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-menuis a slightly overgrown shell-script (yuk), whereaspalaveris Python (yay).palaverhas a nice CLI with numerous non-interactive sub-commands likepalaver list merged, andpalaver reviewwhich provides an interactive mode.git-cherry-menuonly offers an interactive mode (which is very similar in concept topalaver review); for non-interactive querying of the current state, you have to use a separate commandgit-icing. Personally I preferpalaver‘s unified approach to UI design, even though it doesn’t yet have the pretty ANSI colour-coding ofgit-icingandgit-cherry-menu.- Since
git-icingwraps aroundgit 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-menuenables cherry-picking of commits, whereas that’s still on the TODO list forpalaver. palaverpersists state by writing notes which are JSON blobs, whereasgit-cherry-menuuses plain text where lines beginning withskip: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 asgit logorgitk.palaver“manually” classifies commits into the following states:pass/defer/pick/proposed/merged, whereas my tools have fewer “manual” states – conceptually justskipandtodo.mergedis either automatically detected viagit cherry, or manually flagged via askip. 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.
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 http://review.openstack.org, 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.

[…] 有关Git notes的更多用法 […]
[…] 有关Git notes的更多用法 […]