Git 2.56.0 adds git add --resolved — a staging mode that refuses to commit leftover conflict markers and never touches your unrelated edits. After two decades of git add -u footguns, here's how to retrain your merge muscle memory.

Everyone who maintains a Git repository has committed this bug. You merge a branch, hit a conflict in recipe.txt, resolve it by hand — and meanwhile notes.txt carries an unrelated local edit you were mid-way through. You type the muscle-memory command, git add -u, and walk away. Two things just happened that you didn't intend: notes.txt's unrelated work is now staged, and if you missed a single <<<<<<< marker in recipe.txt, that conflict marker is staged too. The first is noise; the second is a landmine that can survive code review.

Git 2.56.0, the project's latest quarterly release with work from 104 contributors, finally ships the safety rail. It is called git add --resolved, and its entire design is a rebuke of the command you have been using.

A narrower command on purpose

git add --resolved considers only paths that are currently unmerged in the index — the actual conflicted files. Before staging anything, it scans those files for leftover conflict markers. Find one, and Git stages nothing at all, printing the offending paths instead:

$ git add --resolved
fatal: the following paths still have conflict markers:

        recipe.txt

Fix the markers, run it again, and only the resolved file stages. Your unrelated edit to notes.txt stays right where it was: unstaged, in the working tree, exactly as git status --short will show you. You can also scope it with a pathspec, and the all-or-nothing marker check still applies within that selection.

Three deliberate limitations make it trustworthy. It cannot be combined with -u or -A, so there is no way to accidentally widen it. It ignores tracked files that were never conflicted. And resolved deletions and binary conflicts — which have no textual markers to scan for — stage normally. This is the part maintainers will appreciate most: in maintainer workflows, a merge often begins with unrelated local changes already in the tree, and the old commands punished that.

Retrain the habit

The practical move is boring and effective: make --resolved the thing your fingers type during merges.

  1. Alias it now. git config --global alias.ar 'add --resolved' gives you git ar — short enough to replace git add -u in muscle memory. The official docs themselves recommend exactly this workflow.
  2. Pair it with a status check. Run git status --short after every merge-resolution session and read the two columns: left is staged, right is working tree. If you see an M on the right for a file you didn't mean to leave out, your old habit leaked through.
  3. Teach it to your team in one sentence: "After a conflict, stage with --resolved, never with -u." That sentence prevents more merge accidents than any hook script.

While you're here: two more 2.56 upgrades worth adopting

Bulk branch cleanup has been overdue for a decade. git branch --delete-merged 'origin/*' 'topic-*' --dry-run lists every local topic-* branch whose tip is reachable from its upstream, and drops --dry-run to actually delete them. Branches checked out in a worktree, missing upstreams, and ambiguous push configs are skipped, and branch.<name>.deleteMerged = false protects the ones you want to keep. If your local repo carries forty stale topic branches from every release you've shipped, this is the one command that ends the sprawl.

The performance story is quieter but substantial. Git 2.56 reworked how merge bases are found: once one side's commit queue is exhausted, no new common ancestor can appear, so the walk stops. In a real monorepo, a merge-base traversal fell from 0.68 seconds to 0.01 seconds. Similar scaling-cliff removals landed across reftable writes and packfile loading — on a Chromium checkout with half a million index entries, one affected git diff went from about eight minutes to 0.07 seconds. Nobody will notice these; everybody benefits.

The deeper point

Twenty years of Git ergonomics can be summarized as "sharp tools, read the manual." git add --resolved is a different philosophy: a command whose shape makes the wrong outcome hard instead of merely documented. It is a small feature — a staging mode, a marker scan, a refusal to widen. But it closes the gap between what you meant and what Git did, and that gap is where most merge disasters live. Update, alias it, and let the old footgun rust.


Sources: GitHub Blog — "Highlights from Git 2.56" by Elijah Newren · Git project release notes — git 2.56