Git 2.56 stops merge-base searches once no new common ancestor can appear
Git 2.56.0 ships a merge-base stopping rule that GitHub measured at around 70 times faster in many cases on one large monorepo. Whether a build fleet sees gains like that depends on its repositories having old side branches merged into long histories.
The Engineer · Build desk
What happened
- Git 2.56.0 collects 748 non-merge commits since v2.55.0 from 104 contributors, 39 of whom are new to the project.
- On the Linux kernel, git merge-base --all v4.8 v4.9 fell from 167,441 traversal steps and 0.29 seconds to 3,887 steps and 0.01 seconds with the default v2 commit-graph.
- A new git add --resolved mode stages only unmerged paths, and it leaves the index untouched if any of them still holds conflict markers.
- The ort merge backend has been hardened so that it aborts on corrupt trees under appropriate error conditions.
- A new promisor.acceptFromServerURL configuration variable lets the server side add entries to a client's list of promisor remotes.
Why it matters
- Who has to decide decision Repository shape sets the upgrade priority. Fleets working on long histories with old merged side branches stand to gain most, while a 0.28-second saving per kernel-sized query gives a single developer little reason to rush.
- What it limits constraint Merge jobs that ran against a damaged tree can now stop with an error under ort, so a new CI image needs a test pass on real repositories before it reaches every runner.
- Who's exposed exposure Clients that set promisor.acceptFromServerURL let the server add promisor remotes on their behalf, so that variable belongs in the reviewed part of a build machine's gitconfig.
Next story · Build · 3d ago
Anthropic built Scion after agents pushed daily merges from 2,500 to over 30,000Confirmed5 publishers
The old merge-base search had a stopping problem. Git walks backward from both commits and treats any commit reachable from both sides as a candidate [13]. Criss-cross merges can produce several merge bases, none an ancestor of another, so Git must keep walking until it has found all of them [13]. Under the old rule, that walk could keep processing a long tail of stale, already-common history after another merge base had become impossible [13]. Git 2.56 tracks how many queued commits are still reached from only one side. Once one side runs out, no new meeting point can appear, and the implementation adds guards around that rule [14]. "Git can stop while still returning every merge base," wrote Elijah Newren, the GitHub staff engineer who designed merge-ort, Git's default merge strategy since 2.34 [15][21].
I like this change because the output is untouched and only the exit condition moved [14][15]. On the kernel query, traversal steps fell about 43 times and wall time about 29 times [22][25]. At 0.01 seconds, two decimal places cannot resolve much, so the step count is the better guide to what changed [18].
The monorepo numbers come from GitHub's own workloads. One real monorepo case fell from 0.68 seconds to 0.01, about 68 times faster [16][24]. Across two large monorepos, the post reports many cases near 70 times faster in one and an average near 20 times in the other [17]. It says the gain is largest when old side branches have been merged into a much longer history [19]. For the figures to transfer, a repository needs that shape, and the kernel result was measured with Git's default v2 commit-graph [18]. The absolute saving on the kernel query is 0.28 seconds [23]. On a laptop that is hard to notice. The post notes that repository hosts run the same calculation for pull request diffs, mergeability checks and review ranges [20].
The `--resolved` check is narrow on purpose. A pathspec can limit which unmerged paths it considers, and the all-or-nothing marker rule still applies inside that selection [10]. It cannot be combined with `git add -u` or `-A`, and it ignores tracked files that never conflicted [10]. "That makes it a useful safety rail for maintainer workflows where a merge may begin with unrelated local changes already present," Newren wrote [12]. The check is textual. Resolved deletions and binary conflicts have no markers, so Git stages them normally, and the marker scan cannot tell whether a binary conflict was actually resolved [11].
For build images, the release also changes output a pipeline might read. `git log --follow` now handles histories where a tracked path was renamed differently on separate lines [5]. Advice from `git status` for a branch that is behind or has diverged now suggests `git pull <remote> <branch>` [6]. A new `fetch.followRemoteHEAD` variable sets a default for the per-remote `followRemoteHEAD` setting [4]. Git now flags `git push origin/main` as a probable typo and offers a fix, a change that shipped without a benchmark [7]. For a CI fleet built around one large, long-lived repository, I think the upgrade is worth taking after a test run on that repository, since both the faster merge bases and the new ort aborts would show up there first [2][19].
What to watch
- Independent merge-base timings on repositories without long merged side-branch histories, which would show how far GitHub's 20 to 70 times figures carry.
- CI merge jobs that start failing under the hardened ort backend, pointing to corrupt trees that earlier releases let through.
- Whether the experimental git history command, which gained a drop subcommand in 2.56, is declared stable in a later release.
Clarity's read
What the record supports and how the coverage leans. The claims behind it follow.
Reality
- Evidence62
- Adoption
- Not scored
- Hype gap+15
- Incentives55
- Confidence66
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
Git v2.56.0 is a feature release comprising 748 non-merge commits since v2.55.0, contributed by 104 people, 39 of whom are new faces.
- [2]
The 'ort' merge backend has been hardened against corrupt trees by ensuring it aborts under appropriate error conditions.
- [3]
The handling of the promisor-remote protocol capability has been updated to allow the other side to add to the list of promisor remotes via the 'promisor.acceptFromServerURL' configuration variable.
- [4]
The fetch.followRemoteHEAD configuration variable has been added to provide a default for the per-remote remote.<name>.followRemoteHEAD setting.
- [5]
"git log --follow" has been updated to better handle non-linear history, in which the path being tracked gets renamed differently in multiple history lines.
- [6]
Advice shown by "git status" when the local branch is behind or has diverged from its push branch has been updated to suggest "git pull <remote> <branch>".
- [7]
When 'git push origin/main' or 'git branch origin main' is run, the command is now recognized as a potential typo, and advice has been added to offer a typo fix.
- [8]
The experimental 'git history' command has been taught a new 'drop' subcommand to remove a commit, with its descendants replayed onto its parent.
- [9]
The new git add --resolved mode considers only paths that are currently unmerged in the index; before staging anything it scans unmerged regular files for leftover conflict markers, and if it finds one it reports the affected paths and leaves the index unchanged.
- [10]
A pathspec can limit which unmerged paths git add --resolved considers, and the all-or-nothing marker check still applies within that selection; --resolved cannot be combined with git add -u or -A, and it ignores tracked files that were never conflicted.
- [11]
Resolved deletions and binary conflicts do not have textual markers, so Git can stage them normally under git add --resolved.
- [12]
"That makes it a useful safety rail for maintainer workflows where a merge may begin with unrelated local changes already present."
- [13]
Git finds merge bases by walking backward from both tips; a commit reached from both sides is a candidate. Criss-cross merges can produce multiple merge bases, none an ancestor of another, so Git must keep walking until it has found all of them, and the old stopping rule could keep processing a long tail of stale, already-common history after another merge base had become impossible.
- [14]
Git 2.56 tracks how many queued commits remain painted exclusively by each side; once one exclusive side is exhausted, no new meeting point can appear. The implementation has additional guards around this rule.
- [15]
"Git can stop while still returning every merge base."
- [16]
In one real monorepo case, the merge-base traversal fell from 0.68 seconds to 0.01 seconds.
- [17]
Production evaluations on two large monorepos found many cases around 70 times faster in one and an average improvement around 20 times in the other.
- [18]
With Git's default v2 commit-graph, git merge-base --all v4.8 v4.9 on the Linux kernel fell from 167,441 traversal steps and 0.29 seconds to 3,887 steps and 0.01 seconds.
- [19]
The difference can be dramatic when old side branches have been merged into a much longer history.
- [20]
Repository hosts perform the same merge-base calculation for pull request diffs, mergeability checks, review ranges, and other comparisons.
- [21]
Elijah Newren is a Staff Software Engineer at GitHub and the designer and implementer of merge-ort, Git's default merge strategy since 2.34.
- [22]
The kernel merge-base query took about 43 times fewer traversal steps in Git 2.56.
- [23]
The absolute time saved on the kernel merge-base query is 0.28 seconds per call.
- [24]
The single monorepo case ran about 68 times faster.
- [25]
Wall time on the kernel merge-base query fell about 29 times.
Sources
2 independent publishers whose own reporting we read for this story.
- github.blogHighlights from Git 2.56
1 article · September 28, 2026
- lwn.netGit v2.56.0 released
1 article · September 28, 2026