# Resolve git merge conflicts with AI, safely

URL: https://agentvera.dev/en/blog/resolve-merge-conflicts-with-ai/ · Published: 2026-10-29

Resolve merge conflicts with AI without losing work: zdiff3 markers, a prompt for your coding agent, tests before git add, rerere, rebase vs merge and prevention.

**In short:**

- Set merge.conflictStyle to zdiff3 first: the conflict then shows the common ancestor, so you and the agent can see what each side actually changed.
- Give the agent the intent of both branches, the conflicted files and strict rules: keep both changes, touch only conflicted files, leave no markers, don’t edit tests to pass.
- Verify before git add: git diff --check for leftover markers, then the type check, tests and build, then read the resolved diff yourself.
- Most conflicts are avoidable: small tasks, one owner per file area, frequent rebases on main and a merge queue that tests every branch on the latest tip.

**To resolve merge conflicts with AI safely, make the conflict readable first, then give a coding agent both sides’ intent and strict rules, and only accept the result after git confirms no conflict markers are left and your tests pass.** Agents like Claude Code and Codex are genuinely useful here: they read both versions, the common ancestor and the surrounding code faster than you can, and they can combine two changes instead of picking one. Their typical failure is just as clear: when the intent of one side is unclear, they keep the side that compiles and drop the other without saying so.

This guide covers why conflicts happen (and why parallel agents make them more frequent), a step-by-step workflow from `git status` to `git merge --continue`, a prompt template, rebase vs merge, `git rerere`, a pre-merge check, and how to prevent most conflicts in the first place. Git commands are checked against the official documentation on git-scm.com as of October 2026.

## Why merge conflicts happen

When Git merges two branches, it compares both against their common ancestor. Changes to different areas of a file are combined automatically. When both sides changed the **same area**, Git can’t pick one, so it stops and writes both versions into the file between conflict markers. That is a textual conflict.

The common kinds you’ll meet:

- **Content conflict:** both branches edited the same lines of the same file.
- **Modify/delete:** one branch changed a file, the other deleted or moved it.
- **Generated files:** lockfiles, snapshots, compiled output or translation bundles that both branches regenerated.

There is also a conflict Git can’t see: a **semantic conflict**. Two branches touch different files, merge cleanly and still break each other, for example when one changes a function signature and the other adds a new caller. Only tests on the merged result catch that; [the merge queue post](/en/blog/merge-queue-for-ai-agents/ "Merge queue for AI agents") walks through an example.

### Why parallel agents make conflicts more common

Running several agents at once, each in its own [git worktree](/en/glossary/git-worktree/ "What is a git worktree"), keeps them from overwriting each other’s files while they work. It doesn’t stop the conflict; it moves it to merge time. Each agent works from the base it started on and never sees what the others changed. A few files attract conflicts again and again:

- route tables, dependency injection setups and other registries where every feature adds one line,
- barrel files (`index.ts`) and shared types,
- `package.json` and its lockfile,
- translation files, changelogs and config files.

Agents are also thorough in ways that hurt here: they reformat a file they only meant to touch, rename a helper “while they’re at it”, or fix an unrelated lint warning. Each of those widens the area two branches have both changed.

## Step 1: stop and look before anything else

When a merge or rebase stops, find out where you are before asking anyone, human or agent, to fix it:

```bash
git status                                  # which operation, which files are "both modified"
git diff --name-only --diff-filter=U        # only the unmerged files
```

`--diff-filter=U` selects unmerged paths, which gives you a clean list to hand to an agent. Remember the exits too. If the conflict is bigger than you expected, nothing is lost yet:

```bash
git merge --abort      # back to the state before the merge
git rebase --abort     # back to where the branch was before the rebase
```

Git’s docs recommend committing or stashing your own changes before running `git merge`, because `--abort` can’t always reconstruct uncommitted work. The same goes for an agent’s worktree: let it commit before you merge anything into it.

## Step 2: switch to zdiff3 so the base is visible

By default Git shows only the two sides:

```text
<<<<<<< HEAD
const timeout = config.timeout ?? 30_000;
=======
const timeout = getTimeout(config);
>>>>>>> feature/retry
```

You can’t tell from this what the original line was, so you can’t tell what each side intended. Set the conflict style to `zdiff3` (added in Git 2.35; use `diff3` on older versions):

```bash
git config --global merge.conflictStyle zdiff3
```

Now the conflict includes the common ancestor after a `|||||||` marker:

```text
<<<<<<< HEAD
const timeout = config.timeout ?? 30_000;
||||||| base
const timeout = config.timeout;
=======
const timeout = getTimeout(config);
>>>>>>> feature/retry
```

Now it’s readable: one side added a default, the other moved the lookup into a function. The right resolution probably keeps both, for example by putting the default inside `getTimeout`. According to the git-config docs, `zdiff3` is like `diff3` but moves matching lines at the start and end of a conflict out of the conflict region, so the hunks stay small.

For a merge that is already in progress, recreate the markers of one file in the new style:

```bash
git checkout --conflict=zdiff3 src/http/client.ts
```

This matters even more for an agent than for you. Without the base, the model has to guess which side changed what, and guessing is where silent data loss starts.

## Step 3: give the agent the context it needs

The conflict markers show the lines. The agent also needs to know **why** each side changed them. Git can show the history of both sides for a file:

```bash
git log --merge -p src/http/client.ts   # diffs from HEAD first, then from MERGE_HEAD
git show :1:src/http/client.ts          # common ancestor
git show :2:src/http/client.ts          # HEAD (ours)
git show :3:src/http/client.ts          # MERGE_HEAD (theirs)
```

Add the human context: the task or pull request description of each branch. Then use a prompt like this one:

```text
We are in the middle of a git merge of feature/retry into main. These files
have conflicts (merge.conflictStyle is zdiff3, so the base is shown):
<output of git diff --name-only --diff-filter=U>

Intent of main: <one or two sentences, or the PR description>
Intent of feature/retry: <one or two sentences, or the PR description>

For each conflicted file:
1. Read the ours, base and theirs sections and say in one line what each
   side changed relative to the base.
2. Write a resolution that keeps both intents. If they truly contradict,
   stop and ask me instead of choosing.
3. Edit only the conflicted hunks. No reformatting, renames or unrelated fixes.
4. Do not edit tests to make them pass, and do not delete code you
   don't understand.
For package-lock.json / pnpm-lock.yaml: resolve package.json only, then
regenerate the lockfile with the package manager.
When done: no conflict markers left, run the type check and tests, and give
me a per-file summary of what you kept from each side. Do not run git add,
git commit or git merge --continue.
```

The last line keeps the final step with you. The per-file summary is what makes review fast: you compare each claim with the diff instead of reading every line cold.

## Step 4: resolve one file at a time, by hand-checked rules

A few rules make the difference between a clean merge and a quiet regression:

- **No blanket `--ours` or `--theirs`.** `git checkout --ours <path>` takes one whole side of a file and discards the other. Use it only for a file where you know one side should win, such as a generated file you will regenerate anyway.
- **Mind the swap during rebase.** Git’s docs note that during `git rebase` and `git pull --rebase`, `--ours` is the branch you are rebasing onto and `--theirs` is your own work being replayed. Agents get this wrong surprisingly often, so tell them which branch is which by name.
- **Regenerate, don’t merge, generated files.** Lockfiles, snapshots and build output should come from the tool that generates them, after the source files are resolved.
- **Modify/delete needs a decision.** If one branch deleted a file the other changed, the agent should report it and ask, not restore or delete it on its own.
- **Big conflicts get split.** If one file has dozens of hunks, ask the agent to resolve and explain it in parts, or step back and rethink the merge order.

## Step 5: verify before you continue

An agent saying “resolved” is a claim, not proof. Check it:

```bash
git diff --check                 # warns about leftover conflict markers (and whitespace errors)
git diff                         # review the resolution
pnpm typecheck && pnpm test      # or your project's own check
```

`git diff --check` exits non-zero when changes introduce conflict markers, so it is a cheap gate to run every time. On recent Git versions, `git diff AUTO_MERGE` shows only the changes made so far to resolve the textual conflicts, which is a focused view of exactly what the agent wrote.

Then finish the operation yourself:

```bash
git add src/http/client.ts
git merge --continue     # or: git rebase --continue
```

### Never accept blindly: red flags in a resolution

| Red flag | What it usually means |
| --- | --- |
| One side’s change is simply gone | The agent picked a side instead of combining them |
| A test or assertion changed | The resolution broke behaviour and the test was bent to fit |
| Files outside the conflict list changed | Scope creep: reformatting or “fixes” that need their own review |
| Code appears twice | Both sides were kept verbatim, not merged |
| Markers or a stray `=======` left in a non-code file | Nobody ran `git diff --check` |

If you see any of these, ask the agent to explain that hunk, or redo the file by hand. An AI code review of the merge result is a useful second pair of eyes, but it doesn’t replace running the tests.

## Rebase vs merge when conflicts are likely

Both work; they fail differently.

| | Merge | Rebase |
| --- | --- | --- |
| Where you resolve | Once, in the merge commit | Commit by commit, as each one is replayed |
| Same conflict twice | No | Possible, in several replayed commits |
| `--ours` / `--theirs` | Your branch / the other branch | Swapped: the target / your own work |
| History | Keeps a merge commit | Linear, rewrites the branch’s commits |
| Safe on shared branches | Yes | Only if nobody else builds on that branch |

For short-lived agent branches that only you use, rebasing onto main often is the easier habit: conflicts show up early, while they’re small. For long-lived or shared branches, merge. During a rebase, `git rebase --skip` drops the current commit entirely, so only use it when you’re sure that commit isn’t needed.

## Let Git remember: rerere

If you rebase the same branch again and again, you’ll resolve the same conflict more than once. `git rerere` (“reuse recorded resolution”) records how you resolved a conflict and replays it when the same conflict appears again:

```bash
git config --global rerere.enabled true
```

Once enabled, `git merge` and `git commit` run it automatically. Useful commands:

```bash
git rerere status       # paths whose resolution will be recorded
git rerere diff         # what the current resolution looks like
git rerere remaining    # conflicts rerere could not resolve
git rerere forget src/http/client.ts   # drop a wrong recorded resolution
```

Two things to know. rerere leaves the index alone, so you still check the result and `git add` it, which is good, because a wrong resolution gets replayed just as faithfully as a right one. And old records are pruned by `git rerere gc`: by default unresolved records after 15 days and resolved ones after 60.

## Check for conflicts before you merge

You don’t have to start a merge to find out whether it will conflict. Since Git 2.38, `git merge-tree --write-tree` performs the merge without touching your working tree or index:

```bash
git merge-tree --write-tree --name-only main feature/retry
echo $?    # 0 = clean, 1 = conflicts
```

With `--name-only`, the conflicted section lists just the file names. Git’s docs advise relying on the exit status rather than an empty file list. This is a handy step to give an agent before it touches anything: “check whether feature/retry merges cleanly into main, and if not, list the conflicted files and what each side changed.”

## Prevention: fewer conflicts with parallel agents

The cheapest conflict is the one that never happens:

- **Small tasks.** An agent that changes five files conflicts less than one that changes fifty. Split big jobs by area.
- **One owner per area.** Decide which agent may change the router, the schema, the shared types. Say it in each agent’s instructions.
- **Merge or rebase often.** A branch that lives for an hour rarely conflicts; a branch that lives for a week almost always does.
- **No drive-by edits.** Tell agents not to reformat, rename or fix things outside their task.
- **One lockfile change at a time.** Let a single branch add dependencies, or regenerate the lockfile after each merge.
- **A merge queue.** Branches land one by one on the latest tip, with tests on the merged result, so semantic conflicts are caught too.

For the setup side of running agents in separate folders, see [git worktrees for parallel agents](/en/blog/git-worktree-parallel-agents/ "Git worktrees for parallel agents").

## How AgentVera helps

AgentVera is a desktop app that runs coding-agent CLIs such as Claude Code and Codex side by side, with git built in. These features touch the workflow above:

- **Worktrees and the Git panel.** Create a worktree per feature and start an agent in it; stage per file, commit, fetch, pull and push, and read diffs GitHub-style, unified or split.
- **Early warnings.** By default AgentVera runs `git fetch` in the background every 5 minutes. When new commits reach your branch, a banner lets you fast-forward in one click, or rebase when both sides have commits. When two agents in the same project edit the same file, [agent coordination](/en/features/agent-coordination/ "Agent coordination") warns you; for agents in different worktrees it notes that merging may conflict.
- **File ownership.** With [file ownership](/en/features/file-ownership/ "File ownership") you give an agent paths or globs like `src/api/**`. While it runs, Claude Code agents are stopped before editing those files and told to ask the owner; Codex and other CLIs get the rules in their instructions.
- **Parallel team.** A [parallel team](/en/features/parallel-team/ "Parallel team") (Pro) splits a job into parts that each run in their own worktree and merge into an integration branch. If a merge conflicts or the final check fails, an integration agent steps in.
- **Merge queue.** The [merge queue](/en/features/merge-queue/ "Merge queue") (Pro) merges branches one at a time onto the latest target. A Claude agent resolves conflicts, the check runs on the merged result with up to 2 fix rounds, and a branch that can’t be fixed is returned. Landing waits for your approval by default.

If you work alone on one branch at a time, plain git with `zdiff3` and `rerere` is all you need. These tools pay off once several agents produce branches at the same time.

## Common mistakes

- **Resolving without the base.** The default conflict style hides what the code looked like before; turn on `zdiff3`.
- **“Fix the conflicts” as the whole prompt.** Without each branch’s intent, the agent picks the side that looks more complete.
- **Letting the agent run `git add` and `--continue`.** Keep the final step for after `git diff --check` and the tests.
- **Hand-merging lockfiles.** Resolve the manifest, then regenerate.
- **Rebasing a shared branch.** Everyone who built on it now has to untangle rewritten commits.

## Wrapping up

Resolving merge conflicts with AI works when the agent sees the full picture and you keep the proof: `zdiff3` markers that show the base, a prompt that states both intents and forbids shortcuts, `git diff --check` and the test suite before `git add`, and `rerere` for conflicts that keep coming back. Prevention does the rest: small tasks, clear file ownership and branches that land one at a time.

To try it with your own agents, [download AgentVera](/en/download/ "Download AgentVera").

## Frequently asked questions

**Can an AI coding agent resolve git merge conflicts?** Yes, and it is often good at it, as long as it sees the common ancestor (zdiff3 style), knows what each branch was meant to do and has a test suite to prove the result. Without those, it tends to keep one side and quietly drop the other.

**What is the zdiff3 conflict style?** A value of merge.conflictStyle that adds a ||||||| section with the original text from the common ancestor, like diff3, but moves lines that both sides changed the same way out of the conflict region. Git added it in version 2.35.

**Why are ours and theirs swapped during a rebase?** Git’s docs explain that during git rebase and git pull --rebase, --ours is the branch you are rebasing onto and --theirs is your own work being replayed. Blanket --ours or --theirs is risky for that reason alone.

**What does git rerere do?** With rerere.enabled set, Git records how you resolved a conflict and reapplies that resolution when the same conflict shows up again, for example in a repeated rebase. It leaves the index alone, so you still check the result and git add it.

**How do I check for conflicts before merging?** Run git merge-tree --write-tree --name-only main feature. It performs the merge without touching your working tree or index, exits with 1 when there are conflicts and lists the conflicted files. It needs Git 2.38 or later.

---

**About AgentVera.** AgentVera is a desktop app for macOS, Windows and Linux, built by Solviera Teknoloji. It runs 18 AI coding agents (Claude Code, Codex, Gemini CLI, Copilot, Cursor, Antigravity, opencode, Hermes, Qwen Code, Kimi Code, Kiro, Amp, Droid, Goose, Vibe, Crush, Aider, Cline) side by side, per project, in real terminals with the user's own CLI installs and logins. The free plan has unlimited agents. Download: https://agentvera.dev/en/download/ · Pricing: https://agentvera.dev/en/pricing/
