On Wed, Sep 03, 2025 at 04:11:05PM +0200, elhmn wrote: > Then ran `git update-ref refs/heads/master A` which logged: > ``` > 0000000000000000000000000000000000000000 > 01077b2840db5baea0084921d8f3158a240e8d85 refs/heads/master > ``` > > But I expected: > ``` > 9b18557013105bb7a7bf681f18757084ada9d948 > 01077b2840db5baea0084921d8f3158a240e8d85 refs/heads/master > ``` I don't think the first value is the old value of the ref; it's the old value that was passed in to the transaction. From githooks(5): For each reference update that was added to the transaction, the hook receives on standard input a line of the format: <old-value> SP <new-value> SP <ref-name> LF where <old-value> is the old object name passed into the reference transaction, <new-value> is the new object name to be stored in the ref and <ref-name> is the full name of the ref. You didn't specify an old value, since your "update-ref" command only gave the refname and the new value. So you are "force updating" the ref in the sense that it will be overwritten regardless of the previous value. The same doc goes on to say: When force updating the reference regardless of its current value or when the reference is to be created anew, <old-value> is the all-zeroes object name. To distinguish these cases, you can inspect the current value of <ref-name> via git rev-parse. So I think it is behaving as documented. It is a little unfortunate that a transaction hook cannot tell the difference between "the ref must not currently exist" versus "the caller did not specify the old value". An empty string or something for the latter would have allowed that. But it is too late to adjust the interface now. Possibly we could pass an extra bit of information to say whether an old value was passed, but I think it's tricky to do it in a backwards compatible way (e.g., we cannot just do so in an environment variable, because the value may be different for each ref that comes over stdin). -Peff