From: Maciej Ciemborowicz Date: Sat, 19 Sep 2026 13:34:15 GMT Subject: [BUG] reference-transaction reports zero OIDs for branch and tag deletion Message-ID: Since Git 2.31, the reference-transaction hook receives all-zero old and new object IDs when a branch or tag is deleted with a high-level command. For example, `git branch -d topic` produces: 0000000000000000000000000000000000000000 \ 0000000000000000000000000000000000000000 \ refs/heads/topic The same happens with `git branch -D`, `git tag -d`, and deletion of a remote-tracking ref by `git remote prune`. Git 2.28 through 2.30 reported the previous object ID followed by the all-zero object ID. Starting with Git 2.31, that information is lost. The behavior is still present in Git 2.55 with both the files and reftable backends. A direct deletion with: git update-ref -d refs/heads/topic "$old_oid" continues to report the useful payload: 0000000000000000000000000000000000000000 refs/heads/topic Minimal reproducer: #!/bin/sh set -eu root=$(mktemp -d) trap 'rm -rf "$root"' EXIT repo=$root/repo hooks=$root/hooks log=$root/transactions git init -q "$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 topic git -C "$repo" tag v1 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 -d topic git -C "$repo" tag -d v1 cat "$log" Actual output for the committed transactions is equivalent to: 0000000000000000000000000000000000000000 \ 0000000000000000000000000000000000000000 \ refs/heads/topic 0000000000000000000000000000000000000000 \ 0000000000000000000000000000000000000000 \ refs/tags/v1 I expected: 0000000000000000000000000000000000000000 refs/heads/topic 0000000000000000000000000000000000000000 refs/tags/v1 I understand that the reference-transaction documentation permits an all-zero old value when a ref is force-updated without checking its current value. However, `git branch -d` is a safety-checked deletion, Git has already resolved the branch being deleted, and Git 2.28–2.30 provided its old object ID. Was this loss of information intentional? If not, could the previous object ID be restored for these deletion paths? If it is intentional, the documentation may need to clarify that high-level deletion commands can provide a zero-to-zero record. The behavior was tested across Git 2.28–2.55. The compatibility results and test implementation are available here: https://github.com/ciembor/git-hooks-ext/blob/v0.2.0/tests/compat/README.md https://github.com/ciembor/git-hooks-ext/blob/v0.2.0/tests/compat/e2e.sh Thanks, Maciej Ciemborowicz