Re: [PATCH 0/1] replay: add --revert option to reverse commit changes
- From
Siddharth Asthana <siddharthasthana31@gmail.com>
- Date
- Nov 28, 2025, 08:24 UTC
- Message-ID
- <c930d6df-5dc4-401f-a9a1-eb2f00b2e837@gmail.com>
- In-Reply-To
- <CABPp-BFsDJVtR6RV8KugCW2vmbD1=rTOKLp2jeawRfuPUEsNEA@mail.gmail.com>
On 28/11/25 13:37, Elijah Newren wrote:
Show 22 quoted lines
> On Thu, Nov 27, 2025 at 11:21 AM Siddharth Asthana > <siddharthasthana31@gmail.com> wrote: >> On 27/11/25 02:34, Junio C Hamano wrote: >>> Siddharth Asthana <siddharthasthana31@gmail.com> writes: >>> >>>> 1. For quick undoing an entire MR, the `merge-tree` approach you >>>> suggest is indeed more efficient and avoids unnecessary intermediate >>>> conflicts. >>>> >>>> 2. For commit-by-commit reverts, we need individual revert commits with >>>> proper attribution (which commit is being reverted) for auditability and >>>> history clarity. This is particularly useful when only specific commits >>>> from a merged branch need to be reverted. >>> These are both good workflows with appropriate uses. To make the >>> tool useful for #2, it needs to be able to allow "I have merged a >>> topic with 7 commits, but the first commit and the fourth commit are >>> faulty and I need to revert them", i.e., not just a range >> >> Since replay uses the same rev-list machinery as `git log`, users can >> already specify disconnected commits: >> >> git replay --revert <target> <commit1> <commit4>
Hi Elijah,
> No, this command does not specify disconnected commits. A <range> of > "<commit1> <commit4>" specifies all commits in the history of either > <commit1> or <commit4>.
You are right, I misspoke. I was conflating the command-line syntax with what the revision machinery actually produces after prepare_revision_walk().
Show 10 quoted lines
> Thus, this example command line would be > asking to revert all commits in the history of either <commit1> or > <commit4> (all the way back to the initial commit), rather than just > reverting those two commits. This is just like how > git log <commit1> <commit4> > shows all commits in the history of either <commit1> or <commit4> > instead of just showing those two commits. > > There isn't really a mechanism in replay right now to handle a > disconnected set of commits for either --advance or --revert.
Right, the check at line 190 in replay.c:
if (rinfo.positive_refexprs > 1)
die(_("cannot advance target with multiple sources..."));fires before we even get to the revision walk.
Show 23 quoted lines
> If there were, it'd probably look like > > git replay --advance <branch> --no-walk <commit1> <commit4> > > but the code isn't set up to check whether you specified --no-walk, > and thinks "Um, you specified multiple branches here and it's not > clear the order in which to cherry-pick them" so it throws an error: > > $ git replay --advance main --no-walk Commit1 Commit7 > fatal: cannot advance target with multiple sources because ordering > would be ill-defined > > If you comment out the relevant check which dies with that error, then > you end up in some codepath that segfaults instead (not-properly > initialized commit/tree objects or something?). I'm sure that could > be fixed, but "users can already specify disconnected commits" is just > not accurate. > >> I will add a test to verify this works and document the capability. > Supporting --no-walk so that folks can do disconnected commits for > both --advance and --revert may be nice, but given that it's missing > for --advance already, it might be considered a separate change from > your current submission. I'll leave that up to you.
Agreed. I will keep the current submission focused on basic --revert functionality. Supporting --no-walk for disconnected commits (benefiting both --advance and --revert) would make a nice follow-up series.
Thanks for the correction.
Siddharth