deniz.in

Markets

Weather

Loading weather

· via GitHub Blog

Git 2.56 adds safe conflict staging, faster merge-base searches and server-ready path-walk repacks

Git 2.56 introduces git add --resolved to stage conflict fixes without sweeping in unrelated edits, plus big merge-base speedups and bitmap-compatible path-walk repacks.

Git 2.56 adds safe conflict staging, faster merge-base searches and server-ready path-walk repacks

The Git project has released version 2.56.0, drawing on work from more than 104 contributors, 39 of them first-timers, according to the GitHub Blog. The release's headline changes are a safer way to stage resolved merge conflicts, a substantially faster merge-base algorithm, and fixes that make path-walk repacks viable on large hosting infrastructure.

Staging only what you resolved

Resolving a merge conflict has two parts: edit the working tree until each conflicted path is correct, then stage those paths to mark the conflict resolved. As the GitHub Blog explains, existing commands make it easy to stage more than intended. git add -u updates every modified tracked path, which during a merge can sweep in unrelated local edits, and it can also stage a file that still contains conflict markers you overlooked.

Git 2.56 adds git add --resolved, which considers only paths currently unmerged in the index. Before staging anything, it scans unmerged regular files for leftover conflict markers; if it finds any, it lists the affected paths and leaves the index unchanged. A pathspec can narrow which unmerged paths are considered, but the marker check is all-or-nothing within that selection. Resolved deletions and binary conflicts have no textual markers, so they stage normally. The flag cannot be combined with -u or -A, and it ignores tracked files that were never conflicted.

Merge-base searches stop sooner

Merges, three-dot diffs and the mergeability and comparison checks that repository hosts run for pull requests all need the best common ancestors of two commits. Git finds these by walking backward from both tips and marking which side can reach each commit. Criss-cross merges can produce multiple merge bases, none an ancestor of another, so Git must keep walking until it knows it has found them all.

The old stopping rule could keep processing a long tail of stale shared history after another merge base had become impossible. Git 2.56 instead tracks how many queued commits remain reachable exclusively from each side; once one exclusive side is exhausted, no new meeting point can appear, so Git can stop while still returning every merge base.

The gains reported by the GitHub Blog are large. In one real monorepo, a traversal fell from 0.68 seconds to 0.01 seconds, and 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. A long-standing Linux kernel case also improved: with the default v2 commit-graph, git merge-base --all v4.8 v4.9 dropped from 167,441 traversal steps and 0.29 seconds to 3,887 steps and 0.01 seconds.

Path-walk repacks get server-ready

When repacking, Git traditionally groups delta candidates using a name hash. Path-walk repacking instead visits objects by their location in the tree, bringing versions of the same path together and often finding much better delta relationships. In a GitHub Blog benchmark using a clone of the Fluent UI repository with deltas recomputed, an ordinary bitmapped repack produced a 558.5 MB pack, while a path-walk repack produced 164.4 MB — about 71% smaller.

Until now, path-walk repacking was incompatible with reachability bitmaps, which hosts use to answer object-enumeration queries quickly, and with delta islands. Git 2.56 removes both restrictions: a path-walk repack can select commits for a new bitmap, later git pack-objects invocations can reuse an existing bitmap when it satisfies the request, and path-walk now performs the island-membership bookkeeping required before choosing delta bases. Path-walk remains off by default, but hosts can now evaluate the storage savings without giving up fast bitmap-assisted serving or their isolation rules.

git history and git refs grow

The experimental git history command, introduced in Git 2.54 with reword and split and extended in 2.55 with fixup, gains git history drop, which removes a commit and replays its descendants onto the commit's parent while preserving unrelated local changes. It aborts if a replay would conflict or overwrite a local change, cannot operate on histories containing merge commits, and cannot drop a root or merge commit.

Low-level reference writing, historically scattered across git update-ref, git symbolic-ref and other plumbing, continues consolidating into a git refs toolbox with create, update, delete and rename subcommands, including optional old-value arguments that provide compare-and-swap protection. One caveat from the GitHub Blog: git refs rename moves the ref and its reflog but does not perform the branch-configuration adjustments that git branch -m does.

Why it matters

Git sits under nearly every development workflow, so changes at this level multiply across millions of repositories. git add --resolved targets a routine but error-prone step — accidentally committing conflict markers or unrelated changes into a merge — and turns it into a guarded operation. The merge-base optimization is felt wherever Git computes diffs and mergeability, including pull request checks on hosting platforms, and the kernel and monorepo figures show the difference can reach orders of magnitude on long histories. Meanwhile, making path-walk repacks compatible with bitmaps and delta islands clears the way for dramatically smaller on-disk repositories at host scale without sacrificing serving performance. For a tool as mature as Git, 2.56 shows meaningful work is still landing at every layer, from individual commands to server-side packing.

  • #git
  • #version-control
  • #open-source
  • #developer-tools
  • #performance

Related posts