Patch changelogs with git-notes
Git notes  is a neat function that has been around since v1.6.6. Notes is a kind of metadata that belongs to a certain commit but is stored separately (different git object) from the commit itself. The fact that it is a separate git object is important, it will therefor keep the commit hash intact, and as a bonus - it has its own diff log.
git-notes has support for add, append, copy edit, list, prune, remove and show subcommands. These subcommands is rather self-explanatory, so I will not describe them any further.
add and edit fits allmost all my needs, so I will stick to them.
First, create a git repository
mkdir gitnotes cd gitnotes/ git init echo testfile > test git add test git commit --signoff -m "Initial commit" echo add-more-stuff >> test git commit --signoff -a -m "Feature X"
We now have two commits:
commit bce22657cb5fd8353d43537e6b64422a8ce1107d (HEAD -> master) Author: Marcus Folkesson <email@example.com> Date: Sun Feb 11 21:56:17 2018 +0100 Feature X Signed-off-by: Marcus Folkesson <firstname.lastname@example.org> commit 93726c3f6bf5c95faf969f040966b15d58d6fd0b Author: Marcus Folkesson <email@example.com> Date: Sun Feb 11 21:55:21 2018 +0100 Initial commit Signed-off-by: Marcus Folkesson <firstname.lastname@example.org>
Add a note
Add a note is simple:
git notes add -m "v2: update locking handling for Feature X"
We now have a note appended to our git log HEAD -1
commit bce22657cb5fd8353d43537e6b64422a8ce1107d (HEAD -> master) Author: Marcus Folkesson <email@example.com> Date: Sun Feb 11 21:56:17 2018 +0100 Feature X Signed-off-by: Marcus Folkesson <firstname.lastname@example.org> Notes: v2: update locking handling for Feature X
Note that the SHA, bce22657cb5fd8353d43537e6b64422a8ce1107d, has not changed.
Edit a note
Edit a note is as simple as adding one:
git notes edit HEAD
When to use notes?
The first field of application is obvious, keep notes about individual commits. The kind of notes I usually use is comments during log reviews.
For the last year I have been using notes for a more practical use; patch changelog history, which is an incredible powerful but undocumented (try to google it yourself) area of use for notes.
Patch format and changelogs
When talking about patches, the --- marker line serves the essential purpose of marking for patch handling tools where the commit message ends. One good use for the additional comments after the --- marker is for patch changelogs, which describe what has changed between the v1 and v2 version of the patch.
Rebase and amend
When working with patches, it is not unusual that it will take a few iterations until the patchset is in a ready-to-merge state. The way to rework patches is with an interactive rebase and amending.
A note is linked to a certain git object and this will be a problem with rebase and amend since it will overwrite that git object. With that said; if you amend your commit, the notes will disappear... unless... you configure git to rewrite the note upon amend and rebase.
notes.rewrite.<command>When rewriting commits with <command> (currently amend or rebase) and this variable is set to true, Git automatically copies your notes from the original to the rewritten commit. Defaults to true, but see notes.rewriteRef below.
When copying notes during a rewrite, specifies the (fully qualified) ref whose notes should be copied. The ref may be a glob, in which case notes in all matching refs will be copied. You may also specify this configuration several times.
Does not have a default value; you must configure this variable to enable note rewriting. Set it to refs/notes/commits to enable rewriting for the default commit notes.
This setting can be overridden with the GIT_NOTES_REWRITE_REF environment variable, which must be a colon separated list of refs or globs.
The manpage simply tells you to add these lines to your ~/.gitconfig or .git/config
[notes "rewrite"] amend = true rebase = true [notes] rewriteRef = refs/notes/commits
To make amend and rebase rewrite the notes.
The best part is that git format-patch --notes will generate patches with appended notes after the --- marker.
For example: git format-patch --notes -1 -v2 will generate v2-0001-Feature-X.patch:
From bce22657cb5fd8353d43537e6b64422a8ce1107d Mon Sep 17 00:00:00 2001 From: Marcus Folkesson <email@example.com> Date: Mon, 19 Feb 2018 21:42:45 +0100 Subject: [PATCH v2] Feature X Signed-off-by: Marcus Folkesson <firstname.lastname@example.org> --- Notes: v2: update locking handling for Feature X test | 1 + 1 file changed, 1 insertion(+) diff --git a/test b/test index 2691857..066c37d 100644 --- a/test +++ b/test @@ -1 +1,2 @@ testfile +add-more-stuff -- 2.15.1
This makes the patch workflow real smooth instead of manually track and update your patch changelogs.
My typical workflow
Even notes has a log (all objects in refs/XXX has), and it could be useful to see how your notes has evolved over time:
git log -p notes/commits
Push and fetch notes
The notes itself is stored as git object in .git/refs/notes. A thing to keep in mind is that refs/notes is not pushed by default, but that is not a problem - my opinion is that notes should be local only anyway.
If you really want to push your notes, you can to that with
git push <remote> refs/notes/*
and fetch them with
git fetch origin refs/notes/*:refs/notes/*