Re: [BUG] reference-transaction hook misses destination of git branch -m
From: Karthik Nayak <hidden>
Date: 2026-09-19 20:52:24
Maciej Ciemborowicz [off-list ref] writes:
Hello, `git branch -m old new` changes refs/heads/old into refs/heads/new, but the reference-transaction hook does not report both ref changes.
My understanding without digging too deep is that both 'copy' and 'rename' do not use a transaction, as such they don't trigger the 'reference-transaction' hook. This is definitely absurd, since we would expect that all reference operations should use the transaction and trigger the hook.
Observed with Git 2.55: * files backend: the hook reports deletion of refs/heads/old, but does not report creation of refs/heads/new;
Yeah, because the files backend calls `refs_delete_ref()` on the old reference which is done within a transaction.
* reftable backend: the hook reports no usable rename payload.
Reftable doesn't call `refs_delete_ref()` and simply writes a TOMBSTONE entry to delete the old reference.
The equivalent atomic operation performed with `git update-ref --stdin` reports both updates correctly.
By equivalent atomic operation do you a 'delete' and 'create' command?
I expected the transaction to include:
<oid> <zero> refs/heads/old
<zero> <oid> refs/heads/new
Minimal reproducer:
#!/bin/sh
set -eu
format=${1:-files}
root=$(mktemp -d)
trap 'rm -rf "$root"' EXIT
repo=$root/repo
hooks=$root/hooks
log=$root/transactions
git init -q --ref-format="$format" "$repo"
git -C "$repo" config user.name Reproducer
git -C "$repo" config user.email repro@example.com
git -C "$repo" commit --allow-empty -qm initial
git -C "$repo" branch old
mkdir "$hooks"
cat >"$hooks/reference-transaction" <<'HOOK'
#!/bin/sh
printf '%s\n' "--- $1" >>"$HOOK_LOG"
cat >>"$HOOK_LOG"
HOOK
chmod +x "$hooks/reference-transaction"
git -C "$repo" config core.hooksPath "$hooks"
export HOOK_LOG=$log
: >"$log"
git -C "$repo" branch -m old new
cat "$log"
The behavior was also tested across Git 2.28–2.55:
https://github.com/ciembor/git-hooks-ext/blob/v0.2.0/tests/compat/README.md
The reference-transaction documentation says that the hook is invoked by
Git commands performing reference updates. A branch rename changes two refs,
but the destination update is not visible to the hook.Either ways, I think we should fix this, I could have a look if you aren't submitting a patch yourself :)
Thanks, Maciej Ciemborowicz
Attachments
- signature.asc [application/pgp-signature] 690 bytes