Re: [BUG] reference-transaction hook misses destination of git branch -m
- From
Karthik Nayak <karthik.188@gmail.com>
- Date
- Sep 19, 2026, 20:52 UTC
- Message-ID
- <CAOLa=ZTN1TU2A1sgEhiw=ymMYr6Ge11cMEubSaeKqr4WNU=2EQ@mail.gmail.com>
- In-Reply-To
- <CACQ=SRHCOCcmVCgHqd+sjMsZ9LCdSHuXdCo0gkwxXwYgF7iwig@mail.gmail.com>
Maciej Ciemborowicz <maciej.ciemborowicz@gmail.com> writes:
Show 5 quoted lines
> 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?
Show 46 quoted lines
> 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