Resolving A Conflict by Editing It
Important
You interpret conflict markers and see how resolution automatically propagates.
The natural way to solve a conflict is fixing the affected files.
§ l empty
× zm My parent is conflicted
× zo Merge conflict <- Resolve the conflict here
├─╮
│ ~
~
You have 3 conflicted Changes. @ and zm are conflicted only
because they inherit zo’s conflict. zo is the origin to fix.
Don’t Edit Changes Directly
If you are tempted to run jj edit zo, don’t! As I recommended in
Don’t Edit, create a Buffer Change
instead:
jj new zo
§ k empty <- Your Buffer Change
│ × zm My parent is conflicted
├─╯
× zo empty Merge conflict <- The Change to fix
├─╮
│ ~
~
The Buffer Change is conflicted too: that’s the point. You’ll resolve from there.
Here’s the idiomatic resolution workflow:
jj newtargeting the conflicted Change.- Resolve the conflict, then
jj squash. - If you want to start over,
jj restore.
Resolving The Conflict
If you edit the conflicted file.txt you’ll find:
Donec neque quam...
<<<<<<< conflict 1 of 1
%%%%%%% diff from: vrzponzu b12f7845 "Base of merge-a and merge-b"
\\\\\\\ to: mvxxwqoo e1acf668
-We will create a conflict here.
+We will create a conflict here: merge-a added this text.
+++++++ nzsunxwp 0004a47a
We will create a conflict here: merge-b added this text.
>>>>>>> conflict 1 of 1 ends
Nullam rutrum...
Interpreting Conflicts
See the conflict markers?
<<<<<<< conflict 1 of 1
>>>>>>> conflict 1 of 1 ends
Lines outside are unchanged.
Inside, two elements exist:
-
How the first change modified the base. Read it as:
%%%%%%% diff from: v “Base of merge-a and merge-b” <- from the common Base \\\\ to: mvxxwqoo e1acf668 <- the first Change merge-a -We will create a conflict here. <- wants to apply this diff. +We will create a conflict here: merge-a added this text.
-
The second change’s contribution:
+++++++ nzsunxwp 0004a47a We will create a conflict here: merge-b added this text.
Basically, you have to combine:
We will create a conflict here: merge-a added this text.
We will create a conflict here: merge-b added this text.
into
We will create a conflict here: merge-a and merge-b added this text.
That fixs the conflict. jj st will show:
Hint: Conflict in parent commit has been resolved in working copy
Good. Squash it:
jj squash
All clear! The Buffer Change is automatically abandoned.
Conflict Resolution Propagates
Look the beauty!
@ l empty
│ ○ zm My parent is conflicted
├─╯
○ zo Merge conflict
├─╮
│ ~
~
The resolution automatically propagated upward to zm. How cool is that?
Resolutions All The Way Down
Conflicts propagate upward. Fix them in any point, and descendants heal.
× g ⎫
× f │
× e ⎬ inherit the conflict
× d │
× c ⎭
× b <- conflict origin
○ a
Ideally, you’ll fix the conflict at its origin, then jj squash to
propagate it:
○ g
○ f
○ e
○ d
○ c
○ b <- resolution here
○ a
Got the idea? Ready for tougher cases?