Reading a Merge Conflict

the stop, the markers, the three panes, the ruling - and the always-open door

$ git merge logo-redesign
Auto-merging menu.txt
CONFLICT (content): Merge conflict
  in menu.txt # wrapped
Automatic merge failed; fix conflicts
  and then commit the result. # wrapped
the stop - real output, fixtures/git-course

A merge conflict is git stopping mid-merge to ask a question it cannot answer alone. The commonest shape: both branches changed the same region since the commit they grew from. (Other shapes - a file edited on one side, deleted on the other; renames colliding; binaries - stop the merge the same way.) Everything else has already merged silently.

<<<<<<< HEAD
special: quattro formaggi
=======
special: diavola
>>>>>>> logo-redesign
the envelope, default style

Git writes the question into your working copy as plain-text markers. Nothing is damaged: between <<<<<<< and ======= is your side; between ======= and >>>>>>> is theirs. The repository holds clean copies of BOTH sides in the index - and the base referee waits in stage 1; the markers show the two sides inline.

<<<<<<< ours
special: quattro formaggi
||||||| base
special: margherita
=======
special: diavola
>>>>>>> theirs
diff3: the base block is the referee

Default markers show two versions and make you guess who changed what. Turn on diff3 style and the referee appears: a middle block showing the line before EITHER side touched it. Here both sides rewrote the plain margherita - so keeping one side, or weaving a new line, are the honest options; stacking both would duplicate the special.

yours = your tip, theirs = their tip, base = the fork commit
yours = your tip, theirs = their tip, base = the fork commit

Merge tools - IntelliJ, VS Code, meld - lay the same versions out as panes: yours on one side, theirs on the other, and a middle pane you assemble the result in, with the base as its ground truth. Layouts differ tool to tool; the ROLES never do - the seated graph shows where they come from.

Resolving a text block is one of four decisions: accept yours, accept theirs, accept both in an order you choose, or hand-weave one honest line. Every button in every tool is one of these four wearing a different label. The whole-file shortcuts - git checkout --ours or --theirs - take a side wholesale, including that side's non-conflicting changes: sharper than they look.

$ git add menu.txt && git commit -m
    'reconcile the special: ...' # wrapped
$ git log --oneline -3
ff55b2f reconcile the special: both
  testimonies honored # wrapped
...
add = ruled; the commit seals it

Saving the file resolves nothing - git add is the ruling: it collapses the three kept versions back to one and marks the file resolved. When status shows every conflict ruled, git merge --continue takes the two-parent commit and the merge is history.

And the door is always there: git merge --abort restores everything to the moment before the merge began - branches and commits untouched. Start merges with a clean working directory and the door is always safe to walk through. Most merge fear dies the day you learn the exit exists.