Re: [PATCH v3 0/4] history: add squash subcommand to fold a range
- From
Patrick Steinhardt <ps@pks.im>
- Date
- Jun 19, 2026, 12:37 UTC
- Message-ID
- <ajU4JYYUTz5r-Xgc@pks.im>
- In-Reply-To
- <xmqqo6h7nza3.fsf@gitster.g>
On Thu, Jun 18, 2026 at 05:34:44PM -0700, Junio C Hamano wrote:
Show 21 quoted lines
> "Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com> writes: > > > Adds git history squash <revision-range> to fold a range of commits into its > > oldest one, reusing that commit's message and replaying any descendants on > > top. > > One thing that just occurred to me. > > When you have a linear history > > o---A---B---C > > you run "git history squash A..C" and come to > > o---X > > where the tree of X is the same as C, with the log message of A > reused for it. That is simple, clean, and easy to explain. > > But what should happen to refs (i.e., branch head) that point at A > or B?
It's a very good question. I had `git history squash` in my backlog for a while, and this very question made me defer that topic repeatedly.
Show 8 quoted lines
> I am adressing this message to Patrick as this question relates to > the grand vision for the "git history" command. I think "git > replay" wants to rewrite all the refs that are involved in the > rewrite operation, while "git rebase" (without "--update-refs") > wants to leave all others refs intact and update only the branch it > was told to rewrite. Is it the same design as "rebase" and > "--update-refs" controls if we update _other_ refs that happened to > be in the range that are rewritten?
Yeah.
Show 11 quoted lines
> Now, assuming that there do exist a mode where the command can > update these refs that point into the history that got rewritten, > there probably are at least two possibilities. > > On one hand, I think it is reasonable to _remove_ these refs that > used to point at a section of history that disappeared (like the one > that were pointing at A or B). Perhaps A and B were pointed at by > two branches or tags that were used to mark "up to this point things > are broken" and "from here on things are fixed" (i.e., imagine a > manual bisection). After squashing all of the commits in this > section of history, the result no longer has such transition points.
I think just pruning references would be extremely surprising to our users.
Show 8 quoted lines
> It also is plausible that users may want these refs that used to > point at A or B to point at X, just like the ref that used to point > at C would now point at X, even though I cannot offhand think of a > good story (like "there used to be transtion points, now there > isn't" I said above to explain why these refs should disappear) to > support such a behaviour. > > Thoughts?
There are two more modes:
- If a reference points at an intermediate commit then it stays there.
- We detect this case and reject the update. Optionally, we may ask
the user what they intend to do with those other refs.It really is kind of ambiguous what is supposed to happen, and I can think of different scenarios where each of the possibilities would be the best choice. So ultimately, I think the last option is the best one, as it also gives us a way to iterate.
If so, a user would already be able to achieve that other refs keep pointing at X by saying `git history squash --update-refs=head`. The other modes can then be added at a later point in time as the need arises.
Patrick