Re: [PATCH v2 1/1] replay: make atomic ref updates the default behavior
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Oct 2, 2025, 18:27 UTC
- Message-ID
- <xmqq7bxdw44y.fsf@gitster.g>
- In-Reply-To
- <CABPp-BEh7VEM6UQjkK3CxJcv54vEmueTmh9+-SyTKUxgy7Mkcg@mail.gmail.com>
Elijah Newren <newren@gmail.com> writes:
Show 9 quoted lines
> * it provided a natural low-level tool for the suite of hash-object, > mktree, commit-tree, mktag, merge-tree, and update-ref, allowing users > to have another building block for experimentation and making new > tools. > > I was particularly focused on the last of those items for the intial > version at the time, but it should be noted that all three of these > are somewhat special cases, and the most common user desire is going > to be replaying commits and updating the references at the end.
Yes. We could even tweak the stream in the middle with "sed" or "grep", I presume? ;-)
> Sure, but it's quite trivial to add, right -- as shown above with the > extra "start", "prepare", "commit" directives?
Very true.
Completely a tangent but, isn't requiring "prepare" at this layer, and possibly in the form of ref_transaction_prepare() at the C layer, not so ergonomic API design? Once you "start" a transaction and threw a bunch of instruction, "commit" can notice that you are in a transaction and should do whatever necessary (including whatever "prepare" does). I am not advocating to simplify the API by making end-user/program facing "prepare" a no-op, but just wondering why we decided to have "prepare" a so prominent API element.
> ... > Might I suggest a rewrite of the text of the commit message to this point?
I do think it makes more sense to the reader to know the reasoning behind the _current_ design, and what its strengths are.
Show 25 quoted lines
> ===== > The git replay command currently outputs update commands that can be > piped to update-ref to achieve a rebase, e.g. > > git replay --onto main topic1..topic2 | git update-ref --stdin > > This separation had advantages for three special cases: > * it made testing easy (when state isn't modified from one step to > the next, you don't need to make temporary branches or have undo > commands, or try to track the changes) > * it provided a natural can-it-rebase-cleanly (and what would it > rebase to) capability without automatically updating refs, I guess > kind of like a --dry-run > * it provided a natural low-level tool for the suite of hash-object, > mktree, commit-tree, mktag, merge-tree, and update-ref, allowing users > to have another building block for experimentation and making new > tools. > > However, it should be noted that all three of these are somewhat > special cases; users, whether on the client or server side, would > almost certainly find it more ergonomical to simply have the updating > of refs be the default. Change the default behavior to update refs > directly, and atomically (at least to the extent supported by the refs > backend in use). > ====
This reads very well.
Show 11 quoted lines
> Why is --allow-partial helpful? You discussed at length why you > wanted atomic transactions, but you introduce this option with no > rationale and instead just discuss that you implemented it and some > design choices once you presuppose that someone wants to use it. > > Is there a usecase? I asked for it last time, and suggested > discarding the modes without one, but you only discarded one of the > extras while leaving this one in. I'd recommend discarding this one > too and just having the two modes -- the output commands that get fed > to update-ref, or the automatic transactional update of all or no > refs.
I know there are people who like "best effort", but I too want to learn a concrete use case where the "best effort" mode, which updates only 3 refs among 30 that were to be updated, would give us a better result than "all or none" transaction that fails.