Thread (60 messages) 60 messages, 9 authors, 2026-03-31

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

From: Toon Claes <hidden>
Date: 2026-02-20 17:35:34

Siddharth Asthana [off-list ref] writes:
quoted hunk ↗ jump to hunk
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 [off-list ref]
Helped-by: Patrick Steinhardt [off-list ref]
Helped-by: Elijah Newren [off-list ref]
Helped-by: Phillip Wood [off-list ref]
Helped-by: Johannes Schindelin [off-list ref]
Helped-by: Junio C Hamano [off-list ref]
Signed-off-by: Siddharth Asthana <redacted>
---
 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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help