I spent a lot of time today trying to figure out why notes I was adding were getting removed at seemingly random points. Even notes that I pushed to remote with a non-default ref weren’t showing up after I added another local-only commit note. This turned out to be another case in the “two different tools working fine individually combine to create weird behaviour” phenomenon.
For a long time now I had the following setting in my main gitconfig file:
At a very high level, pruning ensure that all the local refs are
maintained 1=1 with the configured remotes, and any remote branch that
doesn’t exist locally gets removed from local.
pruneTags does the same
thing for tags. The PRUNING section of git-fetch manpage has more
information on this.
This, with a combination of my shell configuration drove me mad for a bit.
Pruning and notes behaviour
I completely missed this part: the local notes refs will get pruned if they’re not explicitly synced1 to the remote:
refs/notes/commits item? This is the default reference under
which notes get added. This behaviour was surprising in hindsight
because another local-first annotation mechanism that similarly needs
explicit syncing is Git’s tagging system, and that has a specific flag
git fetch --prune won’t prune local tags that weren’t
pushed to remote.
I use the excellent pure prompt
in my main (zsh) shell. The plugin also comes with a script that
frequently syncs the state of the git repostory, using
--all. This way, the prompt can show helpful arrows as and when it
knows that there are some changes on the remote, or perhaps when you
switch to a new branch that has diverged from the remote upstream.
Without this script, you’d have to periodically run
git fetch --all or
git fetch, inorder for git to know the difference between the
local and remote branches.
Needless to say, a combination of auto-running
git fetch, with pruning
turned on wreaked havoc!
How this manifested
I had a branch on the remote and local that had a note on the last
commit. On running
git log the first time in a new shell, the remote
note showed up. When I tried to add a local note using
git note add -m
'some message', that didn’t show up sometimes. This got very confusing
and I ended up spending lots of time debugging this thinking the issue
might be in the git config or git itself. Only when I tried this out in
a VM did I realized the problem.
So the moral of the story is, avoid running
prune or configuring it
globally unless you’re absolutely sure you’re not adding any local-only
The bright side of all this, though, is our team now has a very rudimentary build information tagging workflow without requiring another layer of abstraction (think: a website that maintains the build <-> commit mappings).