Thread (8 messages) flat view 8 messages, 3 authors, 13h ago

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

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help