Subject: Re: [PATCH RFC 00/11] Introduce git-history(1) command for easy history editing

From: Patrick Steinhardt <[email-masked]>
Date: Fri, 19 Dec 2025 13:22:03 +0100

On Wed, Dec 10, 2025 at 11:18:29PM +0900, Junio C Hamano wrote:
> Phillip Wood <[email-masked]> 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