TIL: How jj (Jujutsu) Handles Conflicts Differently from Git
I’ve been experimenting with Jujutsu (jj) as a Git-compatible VCS, and the way it handles conflicts completely changed how I think about version control workflows.
The Git Way
In Git, a merge conflict is a blocker. You hit a conflict, and you’re stuck — you can’t commit, you can’t switch branches, you can’t do much until you resolve it. The working directory is in a liminal state.
$ git merge feature-branch
Auto-merging src/main.rs
CONFLICT (content): Merge conflict in src/main.rs
Automatic merge failed; fix conflicts and then commit the result.
You’re forced to stop everything and deal with the conflict immediately.
The Jujutsu Way
Jujutsu treats conflicts as first-class data. A conflicted file can be committed, rebased, and even further merged — all while remaining in a conflicted state. Conflicts are stored in the commit tree, not as transient markers in your working directory.
$ jj new main feature-branch
Created new commit with 1 conflict
$ jj log
@ merge-commit (conflict)
├─ feature-branch
└─ main
This means you can:
- Commit conflicts and come back to them later
- Rebase conflicted commits without resolving first
- Share conflicts with teammates for collaborative resolution
- Undo a resolution if you made a mistake
Why This Matters
For complex rebases involving many commits, the Git approach forces serial conflict resolution — one commit at a time. Jujutsu lets you see the full picture, rebase everything, and then resolve conflicts in whatever order makes sense.
It’s a small conceptual shift with surprisingly large implications for workflow fluidity. Still early in my exploration, but jj is already changing how I think about branching strategies.