· via dev.to (home feed)
Git 2.56's experimental history drop rewrites commits up to 77x faster than rebase
Benchmarks published on dev.to show Git 2.56's experimental history drop command replaying commits 40 to 77 times faster than rebase by rewriting objects directly, with all-or-nothing conflict handling.

Git 2.56 ships a faster way to delete a commit from history
Git 2.56, released on 28 September 2026, includes a new git history command with four experimental subcommands: drop, fixup, reword and split. The most notable is drop, which removes a commit from the middle of a history and replays every descendant onto the removed commit's parent — directly against a bare repository, with no worktree and no checkout. A hands-on benchmark published on dev.to, written after compiling the tagged v2.56.0 source because the release was not yet available in Ubuntu's apt repositories, measured the new command running 40 to 77 times faster than the traditional worktree-and-rebase workflow.
The benchmark numbers
The dev.to author built fresh test repositories containing a root commit, a target commit and a varying number of descendants, then cloned each one bare twice so both methods started from identical history. The old path — adding a linked worktree, running git rebase --onto, then removing the worktree — averaged 1.4 seconds with 20 descendants, 7.1 seconds with 100, and 26.5 seconds with 400. git history drop averaged 0.035, 0.092 and 0.36 seconds for the same sizes, giving ratios of 40.7x, 77.5x and 73.2x. The resulting trees were identical between the two methods — the tree hash of the rewritten branch matched exactly — so the speed does not come from cutting corners; only the commit hashes differed, owing to fresh timestamps.
Where the speedup actually comes from
The intuitive explanation — skipping worktree setup — turns out to be wrong. Worktree add and remove together cost 26 milliseconds out of a 25-second run. The expensive part is rebase itself: git rebase --onto cherry-picks commits one at a time, updating the index and working tree at every step even though those intermediate states are never used. The isolated rebase run showed roughly six seconds of system time alone to replay 400 commits. git history drop never touches a working tree for drop, reword or split operations; it works purely on objects inside .git, so its cost tracks the actual diff work rather than per-commit filesystem writes.
Two behavioral differences from rebase
First, with --update-refs=branches, the command updates every branch that descends from the dropped commit, not just the current one. In the author's test, both main and a feature branch moved after a single invocation; a rebase would have required a second, separate run per branch.
Second, it does not run hooks. An executable post-rewrite hook that fired immediately under rebase never triggered under git history drop. The man page acknowledges that hooks are not run at present and that this may change, but as of this release, any automation relying on post-rewrite — bot notifications, cache invalidation, linting — will silently stop firing if a script switches over.
Failures leave nothing behind
The command refuses three operations outright: dropping a root commit, since there is no parent to replay onto; dropping a merge commit; and any drop whose replay would conflict. All three fail immediately with a non-zero exit status. In the conflict case the author verified that nothing changed — no conflict markers, no rebase state directory, no half-finished rewrite. The man page presents non-stateful rewrites as a design limitation, but compared with an interactive rebase halting mid-sequence on a dirty working tree, failing atomically reads more like a feature. There is also a --dry-run flag that outputs ref updates in git update-ref --stdin form rather than a simple textual preview.
Why it matters
Deleting a commit from the middle of shared history is routine maintenance, and until now it meant paying for a full checkout plus an index-and-worktree update per replayed commit — a cost that grows with history length and bites hardest on servers and CI runners. Rewriting objects directly removes most of that overhead, and the same command addresses two recurring rebase irritations: descendant branches update in one shot, and a conflicting rewrite aborts cleanly instead of leaving a mess behind. The experimental label means scripts should treat the behavior as unstable — the man page warns it may change, and the missing hooks are a genuine migration hazard — but for anyone maintaining long-lived repositories, this is a workflow change worth tracking.
- #git
- #version-control
- #developer-tools
- #command-line