Git development
 help / color / mirror / Atom feed
* [BUG] reference-transaction reports zero OIDs for branch and tag deletion
@ 2026-09-19 13:34 Maciej Ciemborowicz
  2026-09-19 14:59 ` D. Ben Knoble
  0 siblings, 1 reply; 52+ messages in thread
From: Maciej Ciemborowicz @ 2026-09-19 13:34 UTC (permalink / raw)
  To: git

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:

    <old-oid> 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:

    <old-oid> 0000000000000000000000000000000000000000 refs/heads/topic
    <old-oid> 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

^ permalink raw reply	[flat|nested] 52+ messages in thread

end of thread, other threads:[~2026-10-01 17:37 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-19 13:34 [BUG] reference-transaction reports zero OIDs for branch and tag deletion Maciej Ciemborowicz
2026-09-19 14:59 ` D. Ben Knoble
2026-09-19 15:42   ` Maciej Ciemborowicz
2026-09-19 20:11     ` [PATCH 0/3] refs: report old OIDs for batched deletions Maciej Ciemborowicz
2026-09-19 20:11       ` [PATCH 1/3] refs: allow callers to supply old OIDs for batch deletion Maciej Ciemborowicz
2026-09-19 20:41         ` Karthik Nayak
2026-09-20 10:38           ` Maciej Ciemborowicz
2026-09-20 10:54           ` [PATCH v2 0/3] refs: report old OIDs for batched deletions Maciej Ciemborowicz
2026-09-20 10:54             ` [PATCH v2 1/3] refs: allow callers to supply old OIDs for batch deletion Maciej Ciemborowicz
2026-09-21 13:12               ` Karthik Nayak
2026-09-21 23:55               ` Junio C Hamano
2026-09-20 10:54             ` [PATCH v2 2/3] branch, tag: retain old OIDs in batched deletions Maciej Ciemborowicz
2026-09-21 13:19               ` Karthik Nayak
2026-09-20 10:54             ` [PATCH v2 3/3] fetch, remote: retain old OIDs when pruning refs Maciej Ciemborowicz
2026-09-21 13:56               ` Karthik Nayak
2026-09-21 13:57             ` [PATCH v2 0/3] refs: report old OIDs for batched deletions Karthik Nayak
2026-09-21 20:01               ` Maciej Ciemborowicz
2026-09-22 12:26             ` [PATCH v3 " Maciej Ciemborowicz
2026-09-22 12:26               ` [PATCH v3 1/3] refs: allow callers to supply old OIDs for batch deletion Maciej Ciemborowicz
2026-09-22 18:55                 ` Junio C Hamano
2026-09-22 19:21                   ` Maciej Ciemborowicz
2026-09-22 23:31                     ` Junio C Hamano
2026-09-22 12:26               ` [PATCH v3 2/3] branch, tag: retain old OIDs in batched deletions Maciej Ciemborowicz
2026-09-22 12:26               ` [PATCH v3 3/3] fetch, remote: retain old OIDs when pruning refs Maciej Ciemborowicz
2026-09-22 19:16                 ` Junio C Hamano
2026-09-22 22:29               ` [PATCH v4 0/3] refs: report old OIDs for batched deletions Maciej Ciemborowicz
2026-09-22 22:31                 ` [PATCH v4 1/3] refs: allow callers to supply old OIDs for batch deletion Maciej Ciemborowicz
2026-09-22 22:31                 ` [PATCH v4 2/3] branch, tag: retain old OIDs in batched deletions Maciej Ciemborowicz
2026-09-22 22:31                 ` [PATCH v4 3/3] fetch, remote: retain old OIDs when pruning refs Maciej Ciemborowicz
2026-09-23 20:03                   ` Junio C Hamano
2026-09-23 21:02                     ` Maciej Ciemborowicz
2026-09-23 21:04                 ` [PATCH v5 0/3] refs: report old OIDs for batched deletions Maciej Ciemborowicz
2026-09-23 21:04                   ` [PATCH v5 1/3] refs: allow callers to supply old OIDs for batch deletion Maciej Ciemborowicz
2026-09-24 10:04                     ` Karthik Nayak
2026-09-24 16:34                       ` Junio C Hamano
2026-09-24 19:43                       ` Maciej Ciemborowicz
2026-09-24 11:07                     ` Patrick Steinhardt
2026-09-24 16:45                       ` Junio C Hamano
2026-09-24 20:13                         ` Maciej Ciemborowicz
2026-09-28  6:44                           ` Patrick Steinhardt
2026-09-28  6:43                         ` Patrick Steinhardt
2026-09-24 19:56                       ` Maciej Ciemborowicz
2026-09-23 21:04                   ` [PATCH v5 2/3] branch, tag: retain old OIDs in batched deletions Maciej Ciemborowicz
2026-09-24 11:08                     ` Patrick Steinhardt
2026-09-23 21:04                   ` [PATCH v5 3/3] fetch, remote: retain old OIDs when pruning refs Maciej Ciemborowicz
2026-09-23 21:55                   ` [PATCH v5 0/3] refs: report old OIDs for batched deletions Junio C Hamano
2026-09-24 22:33                   ` [PATCH v6 0/1] refs: report old values to transaction hooks Maciej Ciemborowicz
2026-09-24 22:33                     ` [PATCH v6 1/1] " Maciej Ciemborowicz
2026-09-30  3:11                       ` Maciej Ciemborowicz
2026-10-01 17:37                         ` Maciej Ciemborowicz
2026-09-19 20:11       ` [PATCH 2/3] branch, tag: retain old OIDs in batched deletions Maciej Ciemborowicz
2026-09-19 20:11       ` [PATCH 3/3] fetch, remote: retain old OIDs when pruning refs Maciej Ciemborowicz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox