Subject: Re: [PATCH v3 2/2] replay: add --revert mode to reverse commit changes

From: Siddharth Asthana <[email-masked]>
Date: Fri, 6 Mar 2026 10:35:21 +0530

On 20/02/26 23:05, Toon Claes wrote:
> Siddharth Asthana <[email-masked]> writes:
> 
>> Add a `--revert <branch>` mode to git replay that undoes the changes
>> introduced by the specified commits. Like --onto and --advance, --revert
>> is a standalone mode: it takes a branch argument and updates that branch
>> with the newly created revert commits.
>>
>> At GitLab, we need this in Gitaly for reverting commits directly on bare
>> repositories without requiring a working tree checkout.
>>
>> The approach is the same as sequencer.c's do_pick_commit() -- cherry-pick
>> and revert are just the same three-way merge with swapped arguments:
>>
>>    - Cherry-pick: merge(ancestor=parent, ours=current, theirs=commit)
>>    - Revert: merge(ancestor=commit, ours=current, theirs=parent)
>>
>> We swap the base and pickme trees passed to merge_incore_nonrecursive()
>> to reverse the diff direction.
>>
>> Revert commit messages follow the usual git revert conventions: prefixed
>> with "Revert" (or "Reapply" when reverting a revert), and including
>> "This reverts commit <hash>.". The author is set to the current user
>> rather than preserving the original author, matching git revert behavior.
>>
>> Helped-by: Christian Couder <[email-masked]>
>> Helped-by: Patrick Steinhardt <[email-masked]>
>> Helped-by: Elijah Newren <[email-masked]>
>> Helped-by: Phillip Wood <[email-masked]>
>> Helped-by: Johannes Schindelin <[email-masked]>
>> Helped-by: Junio C Hamano <[email-masked]>
>> Signed-off-by: Siddharth Asthana <[email-masked]>
>> ---
>>   Documentation/git-replay.adoc |  37 +++++++-
>>   builtin/replay.c              |  25 ++++--
>>   replay.c                      | 162 ++++++++++++++++++++++++----------
>>   replay.h                      |  11 ++-
>>   t/t3650-replay-basics.sh      | 107 ++++++++++++++++++++--
>>   5 files changed, 277 insertions(+), 65 deletions(-)
>>
>> diff --git a/Documentation/git-replay.adoc b/Documentation/git-replay.adoc
>> index 8d696ce3ab..ffdf790278 100644
>> --- a/Documentation/git-replay.adoc
>> +++ b/Documentation/git-replay.adoc
>> @@ -9,7 +9,7 @@ git-replay - EXPERIMENTAL: Replay commits on a new base, works with bare repos t
>>   SYNOPSIS
>>   --------
>>   [verse]
>> -(EXPERIMENTAL!) 'git replay' ([--contained] --onto <newbase> | --advance <branch>) [--ref-action[=<mode>]] <revision-range>
>> +(EXPERIMENTAL!) 'git replay' ([--contained] --onto <newbase> | --advance <branch> | --revert <branch>) [--ref-action[=<mode>]] <revision-range>...
> 
> The modes `--onto`, `--advance` and `--revert` seem to be extremely
> different from each other. So I'm starting to wonder whether it won't
> make more sense to instead create subcommands instead of options for
> these. Maybe something like:

Agree the interface could be cleaner as subcommands. I think Christian's 
suggestion to do this separate series after --revert lands make sense -- 
we would get real-world usage feedback first, and it avoids scope creep 
here.

> 
>      git replay revert --base=<branch> <revision-range>
>      git replay pick --base=<branch> <revision-range>
>      git replay replay --base=<branch> <revision-range>
> 
>