Reading conflict markers
Intermediate Core Git Git CLI
Why this matters
When Git cannot decide, it writes both candidates into the file and marks them. That block of angle brackets is not damage; it is a form with two options and a place for your answer. Reading it confidently is most of the skill.
The default markers
Here is a real conflicted file, exactly as Git leaves it:
# Frequently asked questions
## Is Trailguide free?
<<<<<<< HEAD
Yes. It is a practice project and costs nothing.
=======
Yes. It is free for everyone, including commercial use.
>>>>>>> e3e760c6c090dbae77da2af1ffc203d5550dfae5
## Where does the trail data come from?Four parts:
| Line | Meaning |
|---|---|
<<<<<<< HEAD |
Start of your version: the branch you are on |
| the text after it | what your side says |
======= |
The divider |
| the text after that | what their side says: the branch or commit being merged in |
>>>>>>> e3e760c… |
End, labelled with the incoming commit or branch |
"Yours" is always the branch you were on when the merge started, which during a git pull is your local branch and during a git merge feature/x is the branch you are sitting on. Everything outside the markers merged cleanly and needs no attention.
zdiff3: also show the original
The default shows what each side wants but not what they started from, which is often the missing piece. Turn on the better style once:
$ git config --global merge.conflictstyle zdiff3The same conflict then looks like this:
## Is Trailguide free?
<<<<<<< HEAD
Yes. It is a practice project and costs nothing.
||||||| b6ae751
Yes. It is a practice project for the Git Course and can be used, changed and shared freely.
=======
Yes. It is free for everyone, including commercial use.
>>>>>>> e3e760c6c090dbae77da2af1ffc203d5550dfae5The new middle section, between ||||||| and =======, is the common ancestor: the text before either side touched it. With it, the intent of each change is usually obvious — here, one side shortened the sentence and the other made the licence explicit, so the resolution should keep both ideas.
Lesson 3.5 includes this setting in the starter configuration. On Git older than 2.35, use diff3, which is the same idea with slightly noisier output.
Reading it as a diff
git diff during a conflict shows a combined diff of the conflicted files:
$ git diffdiff --cc docs/faq.md
index da62846,c6149f4..0000000
--- a/docs/faq.md
+++ b/docs/faq.md
@@@ -2,7 -2,7 +2,11 @@@
## Is Trailguide free?
++<<<<<<< HEAD
+Yes. It is a practice project and costs nothing.
++=======
+ Yes. It is free for everyone, including commercial use.
++>>>>>>> e3e760c6c090dbae77da2af1ffc203d5550dfae5
## Where does the trail data come from?diff --cc means "combined diff", and it has two columns of markers instead of one, because it compares against both parents at once. It is dense; the file itself is easier to read. What it is genuinely good for is finding conflicts in a large file, since the markers stand out.
Prose, code and binaries
Prose (Markdown). The most common kind for a documentation contributor, and the easiest, because you can usually read both versions and write a better third one. Watch for conflicts caused by re-wrapping rather than by meaning: if both sides say the same thing with different line breaks, keep one and move on.
Code. The same mechanics, with one extra duty: after resolving, the file must still be valid. A resolution that keeps both versions of a function definition is syntactically broken even though the markers are gone. Run the tests, and ask the author of the other side if the intent is unclear.
Binary files. Git cannot combine them at all:
warning: Cannot merge binary files: docs/images/logo.png (HEAD vs. e3e760c)
CONFLICT (content): Merge conflict in docs/images/logo.pngThere are no markers to read; you choose one whole file:
$ git checkout --ours docs/images/logo.png # keep your version
$ git checkout --theirs docs/images/logo.png # keep theirs
$ git add docs/images/logo.pngThe same two options exist for text files, when you are certain one side is simply right.
Common mistakes
- Leaving a marker line in the file.
<<<<<<<or=======committed into a document is the classic embarrassment. Search for<<<before committing; linters and pipelines often catch it too. - Assuming "ours" means "the right one". It means "the branch you are on", nothing more.
- Keeping both sides mechanically and producing text that repeats itself or code that does not compile.
- Reading
diff --ccas a normal diff. The double columns are not a rendering error. - Editing outside the markers by accident while cleaning up, which quietly changes something nobody reviewed.
Try it yourself
Goal: see the same conflict in both marker styles.
- Recreate the conflict from lesson 11.1: a branch and
mainthat change the same FAQ line differently, thengit merge docs/conflict-demo. - Open
docs/faq.mdand identify the four parts of the marker block. - Abort:
git merge --abort. - Turn on the better style:
git config --global merge.conflictstyle zdiff3. - Merge again and open the file: a third section has appeared.
- Abort again.
Expected result: the second version has a ||||||| section containing the text as it was before either change.
Show solution
The ancestor section is what turns "two strangers' sentences" into "one sentence that two people edited", which is almost always enough to write the right resolution. Leave zdiff3 on permanently; there is no downside.