Git has added a direct way to combine commits on a branch you are not currently working on. The October 1 development-branch merge introduces git history squash: select a range, fold it into one commit, and replay the work that follows. It belongs to Git’s experimental history editor, not a released feature we have verified in an installed package.
That matters when preparing work for someone else to review. A useful patch often starts as several attempts, corrections and follow-ups. Cleaning up that history should not require abandoning the unrelated branch currently open in the editor. One upstream regression case exercises precisely this arrangement: squash another branch’s commits, then check that the current branch’s tip has not moved.
A direct edit, not a new invention of squash
The broader ambition predates this change. In the January introduction, contributor Patrick Steinhardt described the friction of opening an interactive rebase plan for common edits. He explicitly pointed to stacked branches in competing systems such as Jujutsu as design pressure. The proposal was to give familiar operations their own commands.
Rebase already combines commits, and its autosquash and update-refs options already help organize fixups and move branch references. The new gain is a different interaction: name the range directly, without first editing a rebase instruction list. An editor still opens to combine commit messages by default; skipping that is a separate choice.
The implementation builds the replacement from the oldest selected commit’s authorship and parents, using the newest selected commit’s file snapshot. Later commits are replayed above it. A second test selects an interior range and checks that the final file tree stays the same. The history becomes shorter without throwing away the later work.
Where the branch points matters
A branch is a named position in that history. By default, the history editor carries descendant local branches to their rewritten positions. But suppose a second branch leaves halfway through the range being collapsed. Moving it above the combined commit could give it changes it never contained.
The new range guard refuses that arrangement and names the branches it cannot carry forward. Choosing --update-refs=head explicitly limits the rewrite to the current branch, leaving those other branches on their old history. Tags and remote-tracking references also stay unchanged. This is a choice about which local history to rewrite, not a mechanism for coordinating everyone who has already fetched it.
The refusal is useful information: the selected range crosses another line of work. It does not establish comprehensive protection for every workspace arrangement. The guard explicitly leaves checking HEAD references in other worktrees as unfinished work.
Some merges fit inside the operation
The most substantial extension becomes visible beside the January documentation, which excluded histories containing merges. Squash now accepts certain merges inside the selected range. The new contract requires a connected selection with one tip and constrained parent relationships. A merge above that range, which would need replaying, still causes refusal.
That distinction lets a bounded piece of branching development collapse into one patch; it does not promise arbitrary graph surgery. The merge cases include accepted internal merges and rejected outside parents and later merges. Conflicting rewrites remain outside the history command’s intended contract. Rebase retains the broader role.
We inspected the implementation and upstream test definitions, without building this Git revision or executing those tests. The change appears in the new 2.98 development-cycle notes; no inspected release tag contains it.
For teams maintaining a stack of local patches, the interesting next test is therefore specific: a released build that folds the intended range, carries the right branches, and clearly refuses the rest. Git is expanding the set of edits users can request directly. The value lies in making the scope of each edit understandable before the branch names move.