Skip to content

Build Independently confirmed2 publishers 3 min read Published

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

Send a correction

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.

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
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [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.

    Reported Supported Source: Git v2.56.0 release announcement, via LWNView cited source
  2. [2]

    The 'ort' merge backend has been hardened against corrupt trees by ensuring it aborts under appropriate error conditions.

    Reported Supported Source: Git v2.56 release notesView cited source
  3. [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.

    Reported Supported Source: Git v2.56 release notesView cited source
  4. [4]

    The fetch.followRemoteHEAD configuration variable has been added to provide a default for the per-remote remote.<name>.followRemoteHEAD setting.

    Reported Supported Source: Git v2.56 release notesView cited source
  5. [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.

    Reported Supported Source: Git v2.56 release notesView cited source
  6. [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>".

    Reported Supported Source: Git v2.56 release notesView cited source
  7. [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.

    Reported Supported Source: Git v2.56 release notesView cited source
  8. [8]

    The experimental 'git history' command has been taught a new 'drop' subcommand to remove a commit, with its descendants replayed onto its parent.

    Reported Supported Source: Git v2.56 release notesView cited source
  9. [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.

    Reported Supported Source: GitHub blog, Highlights from Git 2.56View cited source
  10. [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.

    Reported Supported Source: GitHub blog, Highlights from Git 2.56View cited source
  11. [11]

    Resolved deletions and binary conflicts do not have textual markers, so Git can stage them normally under git add --resolved.

    Reported Supported Source: GitHub blog, Highlights from Git 2.56View cited source
  12. [12]

    "That makes it a useful safety rail for maintainer workflows where a merge may begin with unrelated local changes already present."

    Reported Supported Source: Elijah Newren, GitHub blog, Highlights from Git 2.56View cited source
  13. [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.

    Reported Supported Source: GitHub blog, Highlights from Git 2.56View cited source
  14. [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.

    Reported Supported Source: GitHub blog, Highlights from Git 2.56View cited source
  15. [15]

    "Git can stop while still returning every merge base."

    Reported Supported Source: Elijah Newren, GitHub blog, Highlights from Git 2.56View cited source
  16. [16]

    In one real monorepo case, the merge-base traversal fell from 0.68 seconds to 0.01 seconds.

    Reported Supported Source: GitHub blog, Highlights from Git 2.56View cited source
  17. [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.

    Reported Supported Source: GitHub blog, Highlights from Git 2.56View cited source
  18. [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.

    Reported Supported Source: GitHub blog, Highlights from Git 2.56View cited source
  19. [19]

    The difference can be dramatic when old side branches have been merged into a much longer history.

    Reported Supported Source: GitHub blog, Highlights from Git 2.56View cited source
  20. [20]

    Repository hosts perform the same merge-base calculation for pull request diffs, mergeability checks, review ranges, and other comparisons.

    Reported Supported Source: GitHub blog, Highlights from Git 2.56View cited source
  21. [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.

    Reported Supported Source: GitHub blog author bioView cited source
  22. [22]

    The kernel merge-base query took about 43 times fewer traversal steps in Git 2.56.

    Derived Supported
  23. [23]

    The absolute time saved on the kernel merge-base query is 0.28 seconds per call.

    Derived Supported
  24. [24]

    The single monorepo case ran about 68 times faster.

    Derived Supported
  25. [25]

    Wall time on the kernel merge-base query fell about 29 times.

    Derived Supported

Sources

2 independent publishers whose own reporting we read for this story.

  1. github.blog

    1 article · September 28, 2026

    Highlights from Git 2.56
  2. lwn.net

    1 article · September 28, 2026

    Git v2.56.0 released

Topics and entities