I have recently learned that git diff --cached
shows how the new commit during an interactive rebase conflict after resolving the conflict looks. What does git diff
compare during resolving a git rebase
conflict?
What does git diff compare during resolving a git rebase conflict?
git diff --cached
here (or its equivalent, git diff --staged
) does what it always does: it compares the index with the most recent commit. Since the index is what will (or would) happen the next time a commit is made, this diff describes the future: as you rightly put it, how the new commit will look (with respect to the old commit).
This is simply a case of the situation described in https://stackoverflow.com/a/501461/341994. Indeed, one could argue that this question could be closed as a duplicate of that one. But perhaps you do not see at a glance why it is a duplicate; so instead of just saying it's a duplicate, I will explain why.
Start by understanding what a normal merge is: it is the creation, "out of whole cloth", of a new commit (the merge commit). The answer at https://stackoverflow.com/a/501461/341994 is telling you how to perform a merge without creating the new commit; instead, we get Git to pause just before the creation of the new commit. In this situation, the new commit is prepared — in the index, of course! — but not actually created. This allows us to look at the potential commit without actually making it (and we can then go on to make it, or we can retract the whole operation).
Well, if we don't ask Git to pause before the creation of the new commit, but there is a merge conflict, then Git pauses anyway! And so, when we have entered our conflict resolution changes into the problematic file and said git add
to get them into the index, we are in exactly the same situation I described in the previous paragraph: we are paused right before the creation of the commit, and can examine that potential commit by giving the same diff command.
Well, an interactive rebase is a rebase, and a rebase is basically just a series of cherry-picks — and a cherry-pick is a merge: it makes a new commit out of whole cloth, using merge logic, exactly like merge. (The "new commit" has only one parent in a cherry-pick, not two parents as in a true merge; but if you understand what the merge base is and what the two initial parents are, the process is indeed clearly the same process as when you merge.) Thus the same rules apply.
Okay, so there you are, in the middle of performing your interactive rebase, which is actually a series of cherry-picks, and suddenly one of those cherry-picks has a merge conflict — which can easily happen, because (as I just said) a cherry-pick is a merge. So you perform your conflict resolution changes in the problematic file and say git add
, and now presto, you can examine the potential new commit before actually making it by saying git diff --staged
.
EDIT: It appears, from your later comments on this answer, that you might have been asking about git diff
plain and simple.
git diff
plain and simple displays the difference between the working tree and the index. Just as with git diff --staged
, it does in the case of a merge conflict what it always does. But in the case of a merge conflict, for a conflicted file (one that cannot be auto-merged), the index contains three versions of the conflicted file — the base
version, the ours
version, and the theirs
version. And none of those is identical to the working tree version, which Git has already marked up with conflict markers.
And so git diff
shows you a --cc
diff between all three of those versions combined, on the one hand, and the working tree version (marked up with the conflict markers), on the other. See https://git-scm.com/docs/git-show#_combined_diff_format to learn about --cc
diff format, if that's what's confusing you.