From: Elijah Newren Date: Fri, 28 Nov 2025 22:03:55 GMT Subject: Re: [PATCH 0/1] replay: add --revert option to reverse commit changes Message-ID: In-Reply-To: On Fri, Nov 28, 2025 at 12:50 PM Junio C Hamano wrote: > > Elijah Newren writes: > > > How does one distinguish the "topic~5" in the range "topic~5 > > topic~3..topic" from > > * the topic~5 in "^topic~7 topic~5" > > Two answers. > > (1) You don't have to. When you scan cmdline->rev[], you can notice > the ^topic-7 form and reject, saying "we accept A..B but not ^A B." Using revision ranges like ^A B C with --onto (rebasing several branches at once) was one of the major usecases for git replay. Because of that, even when I only have one branch, I often use ^A B over A..B. It's also called out pretty explicitly in the manual: ``` When calling `git replay`, one does not need to specify a range of commits to replay using the syntax `A..B`; any range expression will do: ------------ $ git replay --onto origin/main ^base branch1 branch2 branch3 ------------ This will simultaneously rebase `branch1`, `branch2`, and `branch3`, all commits they have since `base`, playing them on top of `origin/main`. These three branches may have commits on top of `base` that they have in common, but that does not need to be the case. ``` Granted, unlike --onto, using --advance (or --revert) with multiple branches at once doesn't make sense because cherry-picking/reverting multiple branches into one has an ill-defined ordering problem. Since only one branch is allowed, maybe we could make special rules for --advance and --revert, but it would feel a little weird to have a revision range not actually be a revision range for some modes of the command while also having them be an actual revision range for the other mode. > (2) Or you design and document the interpretation you implement when > you see a negative commit while you scan over cmdline->rev[]. > Perhaps you may make "^topic-7" to require a positive commit > after it and convert "^topic-7 topic5" as if the user gave you a > single "topic~7..topic~5". Or you may do something else. Part of the point of replay was to "use the same revision ranges that git log allows". I agree that having a way to specify "topic~3..topic plus the commit topic~5" is useful for this command, but it's equally likely to be useful for `git log`; people have asked for it before. However, there is currently no way to specify that set of revisions to `git log`. Perhaps we should add some flag to revision walking that allows that kind of alternate rule? If we do that, then both log and replay would benefit. We could even consider making that flag be implied by both --advance and --revert (but NOT by --onto). If we do that, we would also need a way to negate that flag, since someone will probably want a way to cherry-pick some disconnected branch down to the root commit, meaning they really would want "topic~5" to be treated as a traditional range and not as a single commit. > > * the "topic1" and "topic2" in "^$OLD_COMMIT --ancestry-path topic1 topic2" > > I haven't thought it through, but doesn't ancetry-path imply you are > really interested in the traditional connected set of commits? The > path is a connected subset inside those commits after all, no? Yes, I believe --ancestry-path makes it clear that a range is wanted. It's not clear to me that we can always correctly guess old-style-range vs. new-style-range from the existing command line arguments alone, particularly given the example above of single commit vs. commits back to the root. I think an explicit flag is needed, if we want to go this route. (Also, this feels like a fair amount of work, when people can easily just invoke replay multiple times...)