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-menuis a slightly overgrown shell-script (yuk), whereas
palaveris Python (yay).
palaverhas a nice CLI with numerous non-interactive sub-commands like
palaver list merged, and
palaver reviewwhich provides an interactive mode.
git-cherry-menuonly 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 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 for
palaverpersists state by writing notes which are JSON blobs, whereas
git-cherry-menuuses 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
palaver“manually” classifies commits into the following states:
merged, whereas my tools have fewer “manual” states – conceptually just
mergedis 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-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.