From: Siddharth Asthana Date: Tue, 09 Sep 2025 06:36:32 GMT Subject: Re: [PATCH 2/2] replay: document --update-refs and --batch options Message-ID: <7f90e1b6-acba-40f2-9e51-ad09c2bf6999@gmail.com> In-Reply-To: On 08/09/25 11:30, Christian Couder wrote: > On Mon, Sep 8, 2025 at 6:36 AM Siddharth Asthana > wrote: >> Add documentation for the new --update-refs option which performs >> ref updates directly using Git's ref transaction API, eliminating >> the need for users to pipe output to git update-ref --stdin. Hi Christian, Thanks for the detailed review. > Most of the time, the documentation should be part of the patch that > introduces the documented behavior, not in a separate patch. You are right I will combine them in v2. > >> Also document the --batch option which can be used with --update-refs >> to allow partial failures in ref updates. > It looks like a --update option was also added by the previous patch. > Is it documented here too? > > Why was this [--update | --update-refs [--batch]] set of options > selected over other possibilities like for example > [--update-iteratively | --update-atomically | --update-batch]? I was trying to provide both simple and advanced modes. --update for users who just want "make it work like piping to git update-ref --stdin" and --update-refs for those who want control over transaction modes. But I see this creates confusion. Would you prefer a single option like --update-refs with an optional mode parameter? Something like --update-refs[=batch] where default is atomic? > > Also how does this --update-refs option compare to the --update-refs > option in git rebase? Is it working in the same way? No, they are different. git rebase --update-refs updates refs that point to commits being rebased. --update-refs updates the target branches from the replay operation itself. The naming collision is unfortunate should I use a different name? > >> Signed-off-by: Siddharth Asthana >> --- >> Documentation/git-replay.adoc | 62 +++++++++++++++++++++++++++++++---- >> 1 file changed, 56 insertions(+), 6 deletions(-) >> >> diff --git a/Documentation/git-replay.adoc b/Documentation/git-replay.adoc >> index 0b12bf8aa4..cc9f868c2f 100644 >> --- a/Documentation/git-replay.adoc >> +++ b/Documentation/git-replay.adoc >> @@ -9,16 +9,17 @@ git-replay - EXPERIMENTAL: Replay commits on a new base, works with bare repos t >> SYNOPSIS >> -------- >> [verse] >> -(EXPERIMENTAL!) 'git replay' ([--contained] --onto | --advance ) ... >> +(EXPERIMENTAL!) 'git replay' ([--contained] --onto | --advance ) [--update | --update-refs [--batch]] ... > Here --update, --update-refs and --batch are all documented, nice. > >> DESCRIPTION >> ----------- >> >> Takes ranges of commits and replays them onto a new location. Leaves >> -the working tree and the index untouched, and updates no references. >> -The output of this command is meant to be used as input to >> +the working tree and the index untouched, and by default updates no >> +references. The output of this command is meant to be used as input to >> `git update-ref --stdin`, which would update the relevant branches >> -(see the OUTPUT section below). >> +(see the OUTPUT section below). Alternatively, with `--update`, the >> +refs can be updated directly. > Here only --update is documented. > >> THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. >> >> @@ -42,6 +43,24 @@ When `--advance` is specified, the update-ref command(s) in the output >> will update the branch passed as an argument to `--advance` to point at >> the new commits (in other words, this mimics a cherry-pick operation). >> >> +--update:: >> + Update the relevant refs directly instead of outputting >> + update-ref commands. When this option is used, no output is >> + produced on successful completion, > It seems a bit redundant to say both "instead of outputting update-ref > commands" and then "no output is produced on successful completion". > Maybe there is a way to reword this to be a bit more concise. You are right that's redundant. I will reword it. > >> and the refs are updated >> + immediately. If any ref update fails, the command will exit >> + with a non-zero status. > This doesn't say if the command immediately stops when it fails to > update a ref, and if the ref updates are atomic or not. You are right the docs need to be clearer about the behavior differences. I will clarify that --update stops immediately on failure (like git update-ref --stdin), while --update-refs defaults to atomic mode. > >> +--update-refs:: >> + Update the relevant refs using ref transactions instead of outputting >> + update-ref commands. By default, uses atomic mode where all ref updates >> + succeed or all fail. > This seems to imply that --update doesn't update the refs atomically. That correct --update doesn't use transactions it updates refs one by one like `git update-ref --stdin` does. Should I make this clearer in the documentation? > >> Use with `--batch` to allow partial updates. > What about --update, when should it be used? Good point. My thinking was --update for simple cases where you want the exact same behavior as piping to `git update-ref --stdin` and --update-refs when you want transaction guarantees. But I am starting to think this distinction might be confusing users more than helping them. Would it be cleaner to just have --update-refs with the batch mode option and drop --update entirely? The sequential behavior can be achieved with --update-refs --batch if someone really needs it. > >> + When this option is used, no output is produced on successful completion. > Here also it seems a bit redundant to say both "instead of outputting > update-ref commands" and then "no output is produced on successful > completion". And maybe there is a way to reword this to be a bit more > concise. Yes same redundancy issue. I will fix the wording throughout in v2. > >> +--batch:: >> + Can only be used with `--update-refs`. Enables batch mode for ref >> + updates, allowing some refs to be updated successfully even if others >> + fail. Failed updates are reported as warnings rather than errors. > What's the difference with --update? Is it that --update immediately > stops when a ref update fails? Yes exactly. --update mimics the behavior of piping to `git update-ref --stdin` and it stops immediately on the first failure and doesn't update any remaining refs. --update-refs uses transactions, so in atomic mode all refs are updated together or none at all, and in batch mode it can continue processing remaining refs even after some fail. > >> :: >> Range of commits to replay. More than one can >> be passed, but in `--advance ` mode, they should have >> @@ -54,8 +73,9 @@ include::rev-list-options.adoc[] >> OUTPUT >> ------ >> >> -When there are no conflicts, the output of this command is usable as >> -input to `git update-ref --stdin`. It is of the form: >> +When there are no conflicts and neither `--update` nor `--update-refs` >> +is used, the output of this command is usable as input to `git update-ref --stdin`. >> +It is of the form: >> >> update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} >> update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} >> @@ -66,6 +86,15 @@ the shape of the history being replayed. When using `--advance`, the >> number of refs updated is always one, but for `--onto`, it can be one >> or more (rebasing multiple branches simultaneously is supported). >> >> +When `--update` is used, no output is produced and the refs are updated >> +directly using individual ref updates. This is equivalent to piping the normal output to >> +`git update-ref --stdin`. > Is it equivalent to `git update-ref --stdin` because both exit as soon > as a ref update fails? Yes that is the intention. Both --update and `git update-ref --stdin` process refs sequentially and exit on first failure leaving the repository in a partially updated state if failure occurs partway through. The difference is --update does this internally without needing the pipe while --update-refs uses proper transactions for better atomicity guarantees. >> +When `--update-refs` is used, no output is produced and the refs are updated >> +using ref transactions. In atomic mode (default), all ref updates succeed >> +or all fail. In batch mode (with `--batch`), some updates may succeed while >> +others fail, with failed updates reported as warnings.