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

From: Toon Claes <[email-masked]>
Date: Fri, 20 Feb 2026 18:35:21 +0100

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:

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

-- 
Cheers,
Toon