import DefinitionCard from "@site/src/components/DefinitionCard";

# What is zdiff3?

_Zealous Diff3 shows the merge base and often pulls matching edge lines out of the conflict markers._

When a [merge or rebase](./merge-vs-rebase) stops on conflicting edits, Git writes conflict markers into the file. The default layout shows `ours` and `theirs`. **zdiff3** keeps the three-way view from `diff3` and often narrows the marked region by moving matching lines near its beginning or end outside the conflict markers. It does not guarantee a globally minimal conflict.

## Introduction

Git's [`merge.conflictStyle`](https://git-scm.com/docs/git-config#Documentation/git-config.txt-mergeconflictStyle) setting controls how conflicted hunks are written into working-tree files. It does not change the merge strategy or Git's automatic conflict decisions. It changes how unresolved hunks look while you resolve them.

The default style is `merge`. It shows `ours` and `theirs`. That is enough when you already know both edits. It fails when you need the pre-divergence text to decide which lines to keep, combine, or rewrite.

During a rebase, `ours` and `theirs` may be opposite of what their names suggest. The upstream tip is generally `ours`, and the commit being replayed is `theirs`. The [`git rebase`](https://git-scm.com/docs/git-rebase) manual documents that swap.

## Understanding the Concept

A **three-way merge** compares three snapshots: your tip, the tip being merged, and their common ancestor. When both tips changed the same region differently, Git cannot auto-combine them and leaves a conflict for you to resolve.

The **`diff3`** conflict style adds that ancestor as a middle section marked with `|||||||`. You see what the file looked like before either branch edited it. That context is often the difference between guessing and reconstructing intent.

**zdiff3** (Zealous Diff3) extends that layout. Like `diff3`, it shows the base. It also removes matching lines on the two sides from the conflict region when those lines appear near the beginning or end of that region. Think of the markers as a highlighter that often covers less of the shared frame, while still leaving some matching lines inside when Git cannot peel them off cleanly.

| Style | Shows base? | Conflict region |
| --- | --- | --- |
| `merge` | No | Two-sided region. Matching edge lines may already be moved outside. |
| `diff3` | Yes | May retain matching edge lines when showing the base. |
| `zdiff3` | Yes | Also removes matching edge lines from the two sides when they sit near either end. |

`diff3` and `zdiff3` present the same three sides. The difference is which lines sit inside the markers. `diff3` may keep shared edges inside so the base stays easy to align. `zdiff3` tries to move those matching edges outside, which often shrinks what you have to resolve by hand.

## Applying It in Practice

Require Git 2.35 or later, then set the style globally:

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

Or set it for one repository:

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

If a conflict is already written with another style, regenerate one file while the path is still unmerged:

```bash
git restore --conflict=zdiff3 -- path/to/file
```

[`git restore --conflict`](https://git-scm.com/docs/git-restore) recreates the conflicted file from the unmerged index stages. That overwrites current working-tree edits for that path, so use it before you start resolving or after you save your work elsewhere. Older Git also accepts `git checkout --conflict=zdiff3 -- path/to/file` for the same job.

Compare the three presentations on the same conflict. Both sides keep the same surrounding lines and only disagree in the middle:

Default `merge`:

```text
1,
foo,
bar,
>>>>>> side
baz,
3,
```

`diff3` adds the ancestor, but still marks the shared edges:

```text
1,
>>>>>> side
3,
```

`zdiff3` keeps the base and moves `foo`, `bar`, and `baz` outside the markers:

```text
1,
foo,
bar,
>>>>>> side
baz,
3,
```

You still decide how to combine the middle. The shared frame no longer looks like part of the dispute in this case. Other conflicts can still leave matching lines inside the markers.

## Engineering Considerations

`zdiff3` is a presentation choice. It does not auto-resolve conflicts, change merge strategies, or replace tests after you finish editing. Resolve the markers, stage the files, and continue the merge or rebase as usual.

Prefer `zdiff3` when conflicts span multi-line regions with identical wrappers on both sides: shared imports, braces, trailing returns, or list delimiters. Prefer plain `diff3` when you want the base kept aligned with a larger overlapping block. Prefer `merge` when you already know both sides and want the shortest two-sided marker text.

Editors and merge tools may reformat or hide conflict sections. Confirm that your tool still shows the `|||||||` base section when you rely on three-way context. If a GUI collapses the base, fall back to the working-tree file or regenerate with `git restore --conflict=zdiff3`.

## Scaling and Operations

Set `merge.conflictStyle` in a shared team docs page or onboarding checklist so local clones agree on conflict presentation. Mismatched styles do not break merges, but they change what reviewers see when they open a conflicted file.

CI and bots that parse conflict markers should accept both two-section and three-section layouts. Scripts that assume only `>>>>>>` will miss the `|||||||` base section under `diff3` and `zdiff3`. Marker length is also configurable through the [`conflict-marker-size`](https://git-scm.com/docs/gitattributes) attribute, so do not assume exactly seven `` characters.

Agent-driven parallel work raises conflict volume. Better markers do not replace isolation. Use separate [worktrees](./git-worktrees), rebase early, and keep shared contracts owned by one branch. See [How to Fix Merge Conflicts Created by Coding Agents](/learn/how-to/merge-conflicts-with-coding-agents).

## Next Steps

- [Parallel Development Workflow](/learn/workflows/git/parallel-development): run concurrent branches without shared-checkout collisions
- [Auto-Rebasing AI Workspaces](/learn/how-to/auto-rebase-ai-branches): keep dependent agent branches current before conflicts pile up
- [What is Git Rerere?](./git-rerere): reuse a conflict resolution when the same conflict returns
- [Customizing Settings](/docs/how-to/customizing-settings): set conflict style and merge preferences in Treq
- [Merging Workspaces](/docs/tutorials/merging-workspaces): resolve conflicts before Treq opens the merge preview
