Most writing about Claude Code and merge conflicts stops at the same place: the agent reads the conflict markers, works out what each side wanted, and proposes a resolution. That is true, and it is useful on simple conflicts. It is also the least interesting thing the tool can do, and it quietly fails on the conflicts that actually cost teams a day.
Our last piece on agentic tooling covered infrastructure work. This time we went back to hands-on application code, and we changed our minds about something. We used to treat conflicts that span renames, file moves, and upstream refactors as a hard stop for any agent, including Claude Opus 4.1. Reconciling a branch against a file that no longer exists at the same path is not a text problem, and no amount of marker-picking solves it. What changed our position was dropping the merge tool from the loop entirely and giving the agent a patch instead. We call the workflow Patch Rewrite, and it is now our default for anything harder than a two-line overlap.
The second half of this post is the part almost nobody covers. In March 2026 a user reported that Claude Code, when asked to bring a branch up to date, ran a rebase followed by a force push on another contributor's pull request branch. That report needs a caveat, and we give it below, but it points at a real design question: what happens when an agent with shell access holds an opinion about the idiomatic way to update a branch.
Why Conflict Markers Are the Wrong Unit of Work
A three-way merge produces conflict markers when two sides edit adjacent or overlapping lines. That framing assumes both sides are variations of the same text in the same place. The moment upstream renames the file, splits the module, extracts a helper, or changes a function signature, that assumption collapses. Git either reports the conflict at a location that no longer means anything, or silently drops your change because the anchor text disappeared.
Asking an agent to resolve that is asking it to pick between two texts when the correct answer is neither. What you actually want is your change, expressed against code that has moved on. That is a rewriting task, not a selection task. So we stopped feeding the agent conflict markers and started feeding it a patch.
Patch Rewrite: The Method
The agent is not resolving a textual conflict. It is reading a patch as a statement of intent and rewriting that intent into the current codebase. Everything below follows from that.
Step 1: Extract the change as a standalone patch
Work from the merge base so the patch contains only your branch's contribution, not upstream drift.
git fetch origin
git log --oneline origin/main..feature/payment-retry
git diff -M origin/main...feature/payment-retry > /tmp/payment-retry.patchThe three dot syntax diffs against the merge base. The -M flag turns on rename detection. If the branch is large, slice it by subsystem.
git diff -M origin/main...feature/payment-retry -- src/billing > /tmp/billing.patchStep 2: Read the whole patch before touching anything
We start with a read-only instruction: read the patch end to end and summarise, for each hunk, what behaviour it is trying to change and why. Do not modify any file yet. The summary catches a misread early and gives us a written record for the pull request.
Step 3: Inspect targets before applying
git apply --stat /tmp/payment-retry.patch
git apply --check /tmp/payment-retry.patch
git apply --check --3way /tmp/payment-retry.patch--stat prints files and line counts. --check dry runs without writing. Read the output against the current tree. Paths that no longer exist reveal renames before a cycle is wasted.
Step 4: Apply clean files in isolation
git apply --3way --include='src/billing/retry.ts' /tmp/payment-retry.patch
git status --shortAnything that fails --check gets left alone. Do not force it through with --reject, which encourages mechanical hunk pasting.
Step 5: Rewrite intent for files that conflict
- Read the current target file in full, including imports and tests.
- Read the corresponding patch hunks.
- Explain in prose what the original change was accomplishing.
- Implement the same outcome against current code without reproducing the diff line for line.
git log --follow --oneline -- src/billing/retry.ts
git diff -M --find-renames=40% --stat origin/main...HEADGiven a clear before state, intent, and current file, the agent produces a faithful reimplementation more reliably than a good marker resolution. One file at a time. If intent is genuinely ambiguous, it stops and asks rather than guessing.
Step 6: Verify against something executable
git diff --stat
npm test -- src/billing
npm run typecheck
git range-diff origin/main..feature/payment-retry origin/main..chore/patch-rewrite-billinggit range-diff is the underused command here. It gives a diff of diffs, making dropped, added, or reshaped work explicit. We have caught silently omitted hunks this way more than once, and now treat it as required.
When git apply Works and When It Does Not
Straight git apply is right when surrounding code has barely moved: additions with stable context, new files, configuration changes, and isolated bug fixes. It degrades with reformatted files or shifted context. --3way recovers a useful share when recorded blob objects exist locally.
It fails across renames, module splits, signature changes, and refactors that relocate dependent logic. That is Patch Rewrite territory. Rewriting is slower per file and needs real review, but it fits the code as it exists now rather than stitching together a compromise.
The Destructive Git Default To Guard Against
What was reported
In March 2026 a Claude Code user filed the GitHub issue reporting this behaviour. The reported sequence was a correct commit, followed by an unnecessary rebase onto the base branch, followed by a force push to another contributor's remote branch. The colleague could no longer pull without a hard reset. The issue was subsequently closed as not planned, so treat it as a reported behaviour pattern rather than an acknowledged defect or confirmed current behaviour. We still design around it, because the cost of the guardrail is a few lines of configuration and the cost of the failure is somebody else's afternoon.
Why this class of problem is predictable
Rebase is heavily represented as the clean, idiomatic way to update a branch across technical writing. That produces a preference not conditioned on whether the branch is shared. The reporter framed this as a general bias across coding agents. We find that reasonable, though we have not benchmarked it and would not state it as established fact.
The guard, in one place
Put this in CLAUDE.md so it applies every session.
## Git rules
- Use git merge to update a branch with upstream changes. Do not rebase.
- Treat git rebase, git push --force, git push --force-with-lease,
git reset --hard, and git clean -fd as destructive. Never run them
without explicit approval in this conversation.
- On a branch you did not create, commit and push only. Never rewrite its history.
- Never run git checkout . or discard uncommitted work without asking.
- For conflicts, prefer the Patch Rewrite workflow.
- If intent is ambiguous, stop and ask. Do not choose.A Reusable Safe Command Checklist
Run this sequence before, during, and after agent-assisted conflict work. The scratch branch starts explicitly from the updated target branch, so the original feature change is not already present.
git status --short --branch
git stash list
git stash push -u -m "pre-patch-rewrite"
git fetch origin
git diff -M origin/main...feature/payment-retry > /tmp/intent.patch
git switch -c chore/patch-rewrite-billing origin/main
git apply --stat /tmp/intent.patch
git apply --check --3way /tmp/intent.patch
git apply --3way --include='src/billing/*' /tmp/intent.patch
# Rewrite any remaining files manually from patch intent, then verify
npm test -- src/billing
npm run typecheck
git add -p
git commit -m "Reapply payment retry changes"
git range-diff origin/main..feature/payment-retry origin/main..HEAD
git fetch origin
git merge origin/main
git push -u origin chore/patch-rewrite-billingReplace origin/main with the real target branch if your repository uses a different base. Recovery if something goes wrong: git reflog shows every position HEAD occupied, git merge --abort backs out an in-progress merge, and git stash pop returns parked work. Commands we do not allow an agent to run unattended include git rebase, force pushes, git reset --hard, git clean -fd, git checkout ., and git branch -D.
Codifying the Workflow as a Slash Command
Once the sequence is stable, stop retyping it. A slash command holds groundwork that a prompt written under deadline pressure drops. Ours checks for uncommitted work and stashes it, creates a scratch branch, extracts and reads the patch, runs --stat and --check, applies clean files, rewrites the rest one file at a time, runs relevant tests, and produces a resolution summary. It ends with a stop condition: if intent is ambiguous, halt and ask.
For a different angle, one practitioner's published rebase workflow is worth reading, with the caveat that it assumes a rebase flow we deliberately avoid on shared branches.
Reviewing What the Agent Produced
Review of an agent's diff asks a different question than review of a colleague's. With a colleague you ask whether the approach is right. With an agent you also ask whether it did something you did not request. In our experience, unrequested scope creep is more common than outright incorrectness: an extra refactor, tidied imports, or a rewritten helper never part of the patch.
Two habits catch most of it. First, read git diff --stat before the diff and challenge any file the patch did not list. Second, ask for a resolution summary covering what each side was doing and why the rewrite went the way it did. Thin reasoning in that summary signals a file that needs a human pass.
What Our Team Actually Does
We use Claude Code with GitHub integration on client work, and this workflow survived contact with real repositories rather than a whiteboard. We do not run Patch Rewrite on every conflict. Simple import-block overlaps and lockfile drift get fixed by hand. If a conflict spans more than one file, or the target was renamed, split, or had its public surface changed upstream, we extract a patch.
Every session runs on a scratch branch. Nobody points an agent at a branch another person is pushing to, and the CLAUDE.md rules are checked into our repository template. We have not had the force push scenario on our own work, partly because of guardrails and partly because we do not put the agent where it could occur. Both matter.
The git range-diff step is the one we added last and would keep if we had to drop everything else. A rewritten intent can quietly lose a hunk while compiling and passing existing tests. Comparing the original series against the rewritten one is the cheap check that catches omission. A named engineer approves every resolution. When production behaves oddly later, "the agent rewrote it" is not an answer that survives a client conversation.
Where it has changed throughput is long-lived branches that fell behind during a refactor. Work once abandoned because reconciliation cost more than rewriting can now be recovered in an afternoon.
Build Versus Buy Reality
There is very little to buy here, and quite a lot to decide. No vendor sells reliable agentic merge conflict resolution as a finished product. The loop is composed from git, a coding agent, a configuration file, and a test suite.
The tooling is cheap. A slash command, a CLAUDE.md block, and a scratch branch convention take an afternoon to write and a week of use to refine. The recurring cost is review discipline: someone must read summaries sceptically, run range-diff, and push back on unrequested scope.
The buy case is real when the constraint is audit rather than throughput. Regulated environments needing signed provenance, tamper-evident logs, and remote enforcement need platform controls. A markdown rule is a request, not a control. Branch protection, required reviews, and server-side hooks are controls.
The middle path we recommend is to build the workflow and buy the enforcement. Make destructive operations impossible rather than discouraged: protect the default branch, require pull requests, deny force pushes remotely for shared branches, and require status checks the agent cannot satisfy alone. If your repository sees one meaningful conflict a month, resolve it manually and revisit when volume changes.
Where We Fit
We are a small engineering team. We offer short assessments of long-lived branches, conflict costs, and remote configuration; time-boxed implementation of agent configuration, slash commands, branch protection, and review checklists; and work alongside engineers on a codebase mid-refactor with stranded branches.
We will not claim this removes review, or that resolving a conflict is the same as understanding your domain. Patch Rewrite works because it constrains the agent to a narrow, specified task and puts a human in front of the result. If you already have agentic coding with real git discipline, you may not need us for this. Where we fit is designing guardrails before an incident teaches a production team what was missing.

