Subject: Re: [PATCH v2 4/8] builtin/reflog: implement subcommand to write new entries

From: Patrick Steinhardt <[email-masked]>
Date: Tue, 29 Jul 2025 08:51:29 +0200

On Mon, Jul 28, 2025 at 08:25:43PM -0400, Ben Knoble wrote:
> > Le 28 juil. 2025 à 11:37, Kristoffer Haugsbakk <[email-masked]> a écrit :
> > On Fri, Jul 25, 2025, at 08:58, Patrick Steinhardt wrote:
> >> diff --git a/Documentation/git-reflog.adoc
> >> b/Documentation/git-reflog.adoc
> >> index c3801b82fb6..c8389810273 100644
> >> --- a/Documentation/git-reflog.adoc
> >> +++ b/Documentation/git-reflog.adoc
> >> @@ -12,6 +12,7 @@ SYNOPSIS
> >> git reflog [show] [<log-options>] [<ref>]
> >> git reflog list
> >> git reflog exists <ref>
> >> +git reflog write <ref> <old-oid> <new-oid> <message>
> >> git reflog delete [--rewrite] [--updateref]
> >>   [--dry-run | -n] [--verbose] <ref>@{<specifier>}...
> >> git reflog drop [--all [--single-worktree] | <refs>...]
> >> @@ -47,6 +48,12 @@ The "exists" subcommand checks whether a ref has a
> >> reflog.  It exits
> >> with zero status if the reflog exists, and non-zero status if it does
> >> not.
> >> +The "write" subcommand writes a single entry to the reflog of a given
> >> +reference. This new entry is appended to the reflog and will thus become
> >> +the most recent entry. Both the old and new object IDs must not be
> >> +abbreviated and must point to existing objects. The reflog message gets
> >> +normalized.
> >> +
> > 
> > You have to give the full refname to this subcommand.  `git reflog write
> > ... branch <msg>` will update the reflog for the one-level ref `branch`.
> > But I’m used to using git-reflog(1) with a name like `branch` and it
> > using `refs/heads/branch` if it exists.  At least that’s how the default
> > `git reflog show` behaves.
> > 
> > Which means that
> > 
> >   git reflog write ... refs/heads/branch <msg>
> >   git reflog branch
> > 
> > Will show that written reflog.
> > 
> > Whereas this
> > 
> >   git reflog write ... branch <msg>
> >   git reflog branch
> > 
> > Will show one entry since `branch` is the one-level ref `branch`, not
> > `refs/heads/branch`.  Now it looks like `write` truncated the reflog and
> > wrote a new reflog message (if you mistakenly think that `branch` is a
> > branch).
> 
> This quirk of update-ref bit me the first few times I used it, too. I
> think it’s at least documented there though.
> 
> > 
> > It isn’t clear to me how the current doc guides me in the correct
> > direction here.
> > 
> > I tried `git reflog drop`[1] and it can deal with a branch like
> > `branch`.  It doesn’t need to be told `refs/heads/branch`.
> 
> (Partly responding to comments about what to do with this) I think
> consistency would be best, and since “git reflog branch” is not
> abnormal we should continue to allow that. 

There's a big difference though: `git reflog drop` won't ever do
anything for a reflog that doesn't exist. Consequently, we know that our
DWIM mechanism can kick in and resolve the reference properly if such a
reflog exists.

But for `git reflog write` that's not the case, as you can write a
reflog message for a yet-nonexistent reflog. The DWIM mechanism cannot
kick in here as there is no reflog. So what do we do in that case? We
could of course just pick the first DWIM rule, which would be that we
decide to write the reflog for "refs/heads/$REFNAME". But... I dunno,
that feels too magicky to m