Re: [PATCH RFC 00/11] Introduce git-history(1) command for easy history editing
- From
D. Ben Knoble <ben.knoble@gmail.com>
- Date
- Dec 22, 2025, 13:47 UTC
- Message-ID
- <CALnO6CDCRgpgsU1W38NDXe=Gzk9qpTfdTSHXf3TXVH95CmxrtQ@mail.gmail.com>
- In-Reply-To
- <aUVDax0PbkaXGB61@pks.im>
[resend] I originally wrote this before some of the fruitful conversation replying to this message, so grain of salt. I think my questions have been answered in terms of how --update-refs behaves, etc.
I still don't think we lose anything by not deviating from other commands now, but I also agree (perhaps to come later, actually using the experimental status to break things?) that I don't want to have to remember to rebase descendants myself.
On Fri, Dec 19, 2025 at 7:48 AM Patrick Steinhardt <ps@pks.im> wrote:
Show 62 quoted lines
> > On Wed, Dec 10, 2025 at 11:18:29PM +0900, Junio C Hamano wrote: > > Phillip Wood <phillip.wood123@gmail.com> writes: > > > > >> Its mostly because I don't like too much magic and because I think being > > >> explicit is always better than not. > > >> > > >> So from my POV, I would expect "the simple case" to be "the simple CLI > > >> call" and if I want the tool to do magic and "rewrite all the > > >> things"^tm, that I would need to specify a flag for that. > > > > > > Thanks, that's useful to know. I'd assumed rewriting all the branches > > > descended from the rewritten commit was the natural thing do do but > > > clearly not everyone thinks it is. > > > > It probably depends on the way one looks at the tool, as a building > > block (in which case less magic may be preferrable) or a complete > > solution for one part of workflow. I probably fall into former camp > > more often than other people, but for this particular one, I tend to > > think it is less confusing if we moved all branch refs away from the > > commits that are obsoleted by rewriting/replaying. > > Okay, so the majority of folks here seem to favor rewriting all > dependent branches, which is also the default that JJ uses here, and > git-replay(1) does it, too. > > There is one major difference between git-replay(1) and git-history(1) > though: the former works with revision ranges, whereas the latter does > not. By using revision ranges we avoid the problem I have mentioned in a > different branch of this discussion, which is that we have no easy way > to figure out which branches we'd have to touch in the first place. This > is because we simply walk the revision range there and then look at > which of our references point into that range. That's simple enough. > > But in our case we're not working with ranges, we are working with a > singular commit. In my head this meant that we'd have to basically do a > revision walk that starts from all of our branches so that we can figure > out which of them would eventually reach the commit that we are about to > rewrite. And that of course doesn't scale. > > Now we could of course also introduce ranges into git-history(1). That > would indeed solve the issue, as we can reuse the same architecture as > we already have in git-replay(1). But I don't really want to go there as > it is leaking complexity to the user: they want to rewrite a single > commit, why should they have to think about ranges? > > But now that I've thought about the problem a bit I think we can avoid > that issue by implicitly identifying the range: it's all the commits > between the commit we're about to rewrite and HEAD. So, same as with > git-replay(1), the set of branches that we'd need to rewrite is any one > branch that points into that range. It keeps the UI simple as the user > still only has to think about a singular commit, should be sufficiently > fast to compute in most cases, and it allows mega-merge workflows like > JJ supports. > > Does that make sense to everyone? If so, I'll revise my stance and will > adapt the current implementation to do exactly that. > > Thanks for the discussion! > > Patrick >
Makes sense to me, and is easily explainable.
One thing that I think JJ handles and which it sounds like replay, history do not (I’m not sure about rebase with update-refs): stacked branches that point to a chain of commits reaching into the range, but whose reference is still outside it. For example:
A <- B <- C
If branchB points at B and similar for branchC, and branchB is HEAD, then “replay <stuff> A..B“ and “history <cmd> <A|B>” sound like they would leave branchC alone? That means I have to remember to do something like “rebase --onto=branchB branchB@{1} branchC”, and if I forget I usually have to later replace branchB@{1} with branchC~<n>.
OTOH, it means branchC serves as an additional backup of the original branchB pre-rewrite :)
Anyway. If the other commands don’t support it yet, I don’t think we lose anything by not rewriting descendants. But something to consider in terms of workflow.
-- D. Ben Knoble