Skip to main content

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 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 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 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.

Definition

Three-way Merge

A merge that compares yours, theirs, and the common ancestor so shared history can guide automatic combination and conflict presentation.

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.

Definition

diff3

A conflict presentation that inserts the common-ancestor version between yours and theirs so you can see how each side diverged.

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.

Definition

zdiff3

A conflict presentation, available since Git 2.35, that shows the merge base like diff3 and removes matching edge lines from the two sides when they appear near the start or end of a conflict region.

StyleShows base?Conflict region
mergeNoTwo-sided region. Matching edge lines may already be moved outside.
diff3YesMay retain matching edge lines when showing the base.
zdiff3YesAlso 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:

git config --global merge.conflictStyle zdiff3

Or set it for one repository:

git config merge.conflictStyle zdiff3

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

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

git restore --conflict 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:

1,
foo,
bar,
<<<<<<< HEAD
=======
quux,
woot,
>>>>>>> side
baz,
3,

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

1,
<<<<<<< HEAD
foo,
bar,
baz,
||||||| 60c6bd0
# add more here
=======
foo,
bar,
quux,
woot,
baz,
>>>>>>> side
3,

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

1,
foo,
bar,
<<<<<<< HEAD
||||||| 60c6bd0
# add more here
=======
quux,
woot,
>>>>>>> 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 <<<<<<<, =======, and >>>>>>> will miss the ||||||| base section under diff3 and zdiff3. Marker length is also configurable through the conflict-marker-size attribute, so do not assume exactly seven <, |, =, or > characters.

Agent-driven parallel work raises conflict volume. Better markers do not replace isolation. Use separate worktrees, rebase early, and keep shared contracts owned by one branch. See How to Fix Merge Conflicts Created by Coding Agents.

Next Steps