> I think the main place I've seen where the mental model of "commits are diffs" breaks down and actually leads to significant confusion and/or mistakes, is when the tree ends up in a weird state, such as in the middle of resolving a merge conflict.
Not really?
With git you just keep track of three things:
1. The actual committed code 2. Code that's in the staging area 3. Code on disk right now
(git has official names for these but I forget)
Then during a rebase, if there a conflict, the base comes from the parent of the commit (in 1) you are applying the new commit on top of and the conflict is basically how the new commit makes changes w.r.t to the latest commit in 1. This conflict is written to 3 for files that are in conflict (and to 2 for files that aren't) and then you can resolve the conflict in 3, move the new code to 2 and commit that to 1. You can think of all of it in terms of diffs.