Git 2.56 improves developer productivity by providing safer conflict resolution workflows and massive performance gains for history traversal. These optimizations reduce CI/CD overhead and prevent accidental staging of broken code during complex merges in large-scale repositories.
The open source Git project just released Git 2.56.0 with features and bug fixes from over 104 contributors, 39 of them new. We last caught up with you on the latest in Git back when 2.55 was released.
To celebrate this most recent release, here is GitHub’s look at some of the most interesting features and changes introduced since last time.
Resolving a merge conflict has two distinct parts. First, you edit the working tree until each conflicted path contains the result you want. Then, you stage those paths to tell Git that the conflict is resolved.
Suppose a merge conflicts in recipe.txt, while notes.txt contains an unrelated local edit.
The second step sounds simple, but existing commands make it easy to stage more than you intended. git add -u updates every modified tracked path. During a merge, that may include local changes that are unrelated to the conflict. It can also stage a file that still contains conflict markers if you overlooked one.
Git 2.56 provides a safer workflow:
$ git add --resolved
fatal: the following paths still have conflict markers:
recipe.txt
$ # Edit recipe.txt and remove the conflict markers.
$ git add --resolved
$ git status --short
M notes.txt
M recipe.txt
The new git add --resolved mode is designed specifically for this step. It considers only paths that are currently unmerged in the index. Before staging anything, it scans unmerged regular files for leftover conflict markers. If it finds one, it reports the affected paths and leaves the index unchanged.
The two columns in git status --short distinguish staged and unstaged changes. recipe.txt is staged as resolved, while the unrelated change to notes.txt remains unstaged.
You can also pass a pathspec to limit which unmerged paths are considered. The all-or-nothing marker check still applies within that selection: if any selected regular file contains conflict markers, Git stages none of them. Resolved deletions and binary conflicts do not have textual markers, so Git can stage them normally.
This is intentionally narrower than git add -u or git add -A. --resolved cannot be combined with either mode, and it ignores tracked files that were never conflicted. That makes it a useful safety rail for maintainer workflows where a merge may begin with unrelated local changes already present.
[source, discussion]
Many Git operations need to find the best common ancestor(s) of two commits. Merges use them as the starting point for combining changes, while three-dot diffs use a best common ancestor to decide where a topic branch’s work begins. Repository hosts perform the same calculation for pull request diffs, mergeability checks, review ranges, and other comparisons.
Git finds these common ancestors by walking backward from both tips. Imagine painting commits reachable from one side blue and commits from the other side red. A commit reached by both colors is a merge-base candidate.
Finding one candidate is not necessarily enough. Criss-cross merges can produce multiple merge bases, none of which is an ancestor of another, so Git must keep walking until it knows that it has found all of them. But the old stopping rule could keep processing a long tail of stale, already-common history after another merge base had become impossible.
Git 2.56 tracks how many queued commits remain painted exclusively by each side. The implementation has additional guards around this rule, but at a high level once one exclusive side is exhausted, no new meeting point can appear. Git can stop while still returning every merge base.

The difference can be dramatic when old side branches have been merged into a much longer history. In one real monorepo case, the traversal fell from 0.68 seconds to 0.01 seconds. 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.
The final series also fixed a long-standing Linux-kernel performance case. With Git’s default v2 commit-graph, the command 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.
[source]
When Git repacks a repository, it searches for similar objects that can be stored efficiently as deltas. The traditional search groups 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.
The potential storage savings are substantial. In a benchmark using a recent clone of the Fluent UI repository and forcing Git to recompute deltas, an ordinary bitmapped repack produced a 558.5 MB pack. Repacking with --path-walk produced a 164.4 MB pack, about 71% smaller.
But repository hosts need more than small packs. They commonly use reachability bitmaps to answer object-enumeration queries quickly, and some use delta islands to prevent objects in one group of refs from depending on objects available only in another. Path-walk repacking was incompatible with both, limiting where its storage improvements could be deployed.
Git 2.56 removes those two restrictions. A path-walk repack can now select commits for a new bitmap. Later git pack-objects invocations can reuse an existing bitmap when it answers the request, falling back to the path walk only when necessary.
Path-walk also now performs the bookkeeping required by delta islands: propagating island membership through commits and trees before choosing delta bases. That lets hosts preserve their isolation rules while experimenting with path-walk’s smaller on-disk representation.
These changes do not enable path-walk repacking by default. Instead, they remove two important adoption blockers, making it possible for large repository hosts to evaluate the storage savings without giving up fast bitmap-assisted serving or delta-island constraints.
Those are just a few of the changes in Git 2.56. Here are some other new
features and updates worth highlighting.
git history command continues to grow. Git 2.54 introduced it with reword and split, and Git 2.55 added fixup. Git 2.56 adds:$ git history drop <commit>HEAD moves, Git updates the index and working tree while preserving unrelated local changes. It aborts if replaying a descendant would conflict or overwrite a local change. The command remains experimental, cannot operate on a history that contains merge commits, and cannot drop a root or merge commit.git update-ref, git symbolic-ref, and other plumbing. Git 2.56 continues consolidating low-level reference management under the git refs toolbox:$ git refs create refs/heads/topic <new-value>$ git refs update refs/heads/topic <new-value> [<old-value>]$ git refs delete refs/heads/topic [<old-value>]$ git refs rename refs/heads/old refs/heads/newgit refs rename moves the ref and its reflog, but does not perform the branch configuration adjustments that git branch -m does.$ git branch --delete-merged 'origin/*' 'topic-*' --dry-runorigin/* matches branches whose upstream is under origin, topic-* limits the candidates to local branch names beginning with topic-, and --dry-run lists what would be deleted without deleting anything.--dry-run, Git deletes only branches whose tips are reachable from their matching upstreams. Branches checked out in a worktree, branches with missing upstreams, and several ambiguous push configurations are skipped. branch.<name>.deleteMerged = false can protect a branch from bulk cleanup.git bisect run is wonderfully effective at finding the commit that introduced a regression, but when it finishes it normally leaves you checked out at the culprit until you run git bisect reset. The new --reset-when-found[=<where>] option combines those steps. Its default is original, which returns to the commit checked out before the bisection began; found cleans up the bisection state but leaves the culprit checked out. The option is unavailable with --no-checkout.git replay command can now flatten merge topology with --linearize. Git replays the commits in a single line and drops merge commits, matching the topology produced by git rebase --no-rebase-merges, but without using the working tree. The option cannot be combined with --contained or with replaying multiple branches at once.git push origin/main advises using git push origin main, while git branch --set-upstream-to origin main suggests git branch --set-upstream-to=origin/main. Git checks that each correction is plausible before suggesting it, avoiding indiscriminate guesses.$ git repack -a --filter=blob:limit=1m --drop-filtered --dry-run$ git repack -a --filter=blob:limit=1m --drop-filteredblob:limit filters. Git requires a promisor remote and refuses unsafe cases such as dropping an object referenced by the current index. The work was contributed as a GSoC project by Siddharth Shrimali, with Christian Couder and Siddharth Asthana recorded as mentors.git log --follow can now track a path more reliably through non-linear history. Previously, the command kept one global “current path.” If different parents renamed the path differently, whichever side happened to be visited first could determine what Git followed through the rest of the walk. Git 2.56 records the path separately for each parent, making the result independent of traversal order and fixing cases such as subtree merges. * root of one visible history
* unrelated commit
git diff improved from about eight minutes to 0.07 seconds.That’s just a sample of changes from the latest release. For more, check out the release notes for 2.56, or any previous version in the Git repository.
The post Highlights from Git 2.56 appeared first on The GitHub Blog.
Continue reading on the original blog to support the author
Read full articleGitHub is evolving its Git storage to handle agentic scale by moving to Azure and decoupling storage from compute. By implementing per-reference serialization, they overcome cross-region latency bottlenecks and enable independent scaling of read and write traffic.
This report details the practical challenges of large-scale cloud migration and database scaling. It provides valuable lessons on implementing failure containment, overload controls, and the necessity of monitoring primary database health during background maintenance tasks.
As AI agents become primary contributors to codebases, traditional Git architectures face unprecedented write pressure. Engineers must understand how infrastructure evolves to support millions of automated commits daily without sacrificing performance for human users.
This report highlights the complexities of scaling a massive platform while migrating to cloud infrastructure. It provides insights into managing database hotspots, handling cascading failures in service meshes, and the critical trade-offs between availability and feature velocity.