Thread (10 messages) 10 messages, 6 authors, 2026-01-06

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

From: Elijah Newren <hidden>
Date: 2025-12-20 16:51:36

On Fri, Dec 19, 2025 at 8:30 AM Elijah Newren [off-list ref] wrote:
On Fri, Dec 19, 2025 at 4:22 AM Patrick Steinhardt [off-list ref] wrote:
quoted
[...]
quoted
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.
I don't understand the distinction at all.  `git replay edit` also
took a single commit, and then implemented the obvious (and jj-like)
behavior of rewriting all branches that descended from that commit.
quoted
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.
Yes, and it's only a few lines of code, as I showed earlier.
quoted
And that of course doesn't scale.
That's quite an assumption about scaling; I don't believe it.  Under
what conditions would this be slow enough for users to notice and be
bothered?  commit-graphs not enabled + weird local clone with
thousands of local branches?  Also, isn't jj specifically designed for
large repositories and with scaling in mind, and yet this is their
default behavior?

More importantly, this is being used to justify a large principle of
least astonishment violation (disconnecting branches with shared
history), so we'd not only need to show that walking all branches was
slower enough for users to notice, but slower enough that the negative
user performance experience offsets the negative user experience from
the astonishing behavior.  Typically, spending extra cycles to provide
users with good warnings/errors is a good use of time, especially when
it'll take them far longer to discover and recover from negative
surprises.
A quick clarification in case I'm misunderstood above:

When I talk about rewriting branches descended from the commit, I am
specifically talking about refs/heads/*, not refs/remotes/origin/* or
refs/tags/* or anything else.  Because:
  * I suspect we'll soon implement an "immutable branches" concept, so
that e.g. a request to modify a commit in the history of "main" would
result in an error (by default).  This leads to the idea that we're
just rewriting the user's local stuff they have on top of the
immutable history, i.e. their local branches.
  * refs/tags/* are designed to be immutable, obviously.  In fact, we
might want to automatically include tags in the set of "immutable
branches" by default.
  * refs/remotes/* are designed to match what the corresponding remote
had, not to be independently rewritten.  We'd really mess people up if
we changed that.
  * The fact that users created local branches means they are marking
those parts of history as a relevant area of interest
  * While it could be that some of refs/remotes/origin/* have shared
history with whatever commit is being reworded/split/edited, so too
could branches that were never pushed.  I think focusing on the
branches of interest to the user (i.e. their local branches) makes
sense.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help