git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Bug report: Strange behavior with `git gc` and `reference-transaction` hook

From
Jeff King <peff@peff.net>
Date
Nov 18, 2021, 18:08 UTC
Message-ID
<YZaWqTwPOyQz0/mu@coredump.intra.peff.net>
In-Reply-To
<CAGyf7-FoRyVtQHa2ETQtRA6fD7x0GDhKVPg+eAajhgPNrsw_OQ@mail.gmail.com>
[+cc pks]
On Wed, Nov 17, 2021 at 04:52:46PM -0800, Bryan Turner wrote:
Show 14 quoted lines
> > The expected behavior would be that the latest reference transaction
> > hook refers to the state of the references on disk. That is, either
> > `master` should point to 0 (be deleted), or it should have said that
> > `master` pointed to `e197d1`.
> >
> > But if we actually examine `master`, it's set to `e197d1`, just as you
> > would expect. The GC should have been a no-op overall.
> 
> One of the subtasks of "git gc" is "git pack-refs". If you inspect in
> more detail, I suspect you'll find that "refs/heads/master" was loose
> before "git gc" ran (as in, there was a file
> "$GIT_DIR/refs/heads/master") and "packed-refs" either didn't have a
> "refs/heads/master" entry or had a different hash. (Loose refs always
> "win" over packed, since ref updates only write loose refs.)

It seems totally broken to me that we'd trigger the reference-transaction hook for ref packing. The point of the hook is to track logical updates to the refs. But during ref packing that does not change at all; the value remains the same. So I don't think we should be triggering the hook at all, let alone with confusing values.

This snippet shows a simple case that I think is wrong:

-- >8 -- git init -q repo cd repo

cat >.git/hooks/reference-transaction <<\EOF #!/bin/sh echo >&2 "==> reference-transaction $*" sed 's/^/ /' EOF chmod +x .git/hooks/reference-transaction

echo >&2 "running commit..." git commit --allow-empty -qm foo echo >&2 "running pack-refs..." git pack-refs --all --prune -- >8 --

It produces:
  running commit...
  ==> reference-transaction prepared
    0000000000000000000000000000000000000000 77bcab0d950aee3021e8aa13a15d40e7a9a5f71b HEAD
    0000000000000000000000000000000000000000 77bcab0d950aee3021e8aa13a15d40e7a9a5f71b refs/heads/main
  ==> reference-transaction committed
    0000000000000000000000000000000000000000 77bcab0d950aee3021e8aa13a15d40e7a9a5f71b HEAD
    0000000000000000000000000000000000000000 77bcab0d950aee3021e8aa13a15d40e7a9a5f71b refs/heads/main
  running pack-refs...
  ==> reference-transaction prepared
    0000000000000000000000000000000000000000 77bcab0d950aee3021e8aa13a15d40e7a9a5f71b refs/heads/main
  ==> reference-transaction committed
    0000000000000000000000000000000000000000 77bcab0d950aee3021e8aa13a15d40e7a9a5f71b refs/heads/main
  ==> reference-transaction prepared
    77bcab0d950aee3021e8aa13a15d40e7a9a5f71b 0000000000000000000000000000000000000000 refs/heads/main
  ==> reference-transaction committed
    77bcab0d950aee3021e8aa13a15d40e7a9a5f71b 0000000000000000000000000000000000000000 refs/heads/main

I think the final four invocations should be skipped entirely. They're pointless at best (nothing actually changed), and extremely misleading at worst (they look like the ref ended up deleted!).

-Peff
Previous: Bryan TurnerNext: Patrick Steinhardt
Message 3 of 5 in “Bug report: Strange behavior with `git gc` and `reference-transaction` hook”
  1. Waleed KhanNov 18, 2021
  2. Bryan TurnerNov 18, 2021
  3. Jeff KingNov 18, 2021
  4. Patrick SteinhardtDec 7, 2021
  5. Bryan TurnerNov 18, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.