Merge Diffs
Why merge diffs are different.
1. Merges
Consider this project history of musical instrument development:
harp-lyre-lute-banjo-guitar-keytar \ / clavicord-piano-synthesizer
At most points in this graph, we can reasonably ask "show me the diff" where a diff is a precise set of instructions to get to a given state from the preceding state. For instance, "the diff" for guitar is all the changes that need to be made to turn a banjo into a guitar.
But merges are fundamentally different because they combine two things into a third and differences are inherently about only two things. So you can't meaningfully ask "what are the differences that make a keytar?" without saying relative to what starting point. The description of how to turn a guitar into a keytar will be almost completely different from the description of how to turn a keyboard into a keytar. Nor is there any particularly sensible definition of "the combined differences" or "the non-obvious differences" or "differences relative to a harp" or anything like that, or at least none that result in set of step-by-step instruction to get from one state to another in the standard sense of "diff".
So when you ask Mercurial for the diff of a merge, it shrugs and says "ok, I guess you mean relative to its first parent". And here that will be complete, precise instructions for turning a guitar into a keytar. And that set of instructions will be LONG because it will include things like "build a synthesizer". You might not find this diff very useful, but remember that diffs are not just for humans: patch(1) or 'hg import' can do useful things with it.
Also, it may or may not happen that the other set of instructions is much shorter and more comprehensible, depending on the merge, but Mercurial always shows the first set for consistency. To get the second set, you can specify a base revision, for instance "-r p2(keytar)".
2. Related
Similar issues appear everywhere that we ask for comparisons that involve merges, for instance with status. In fact, status and diff will typically disagree about changes on merges, because diff is defined as "set of instructions from state A to state B", while status is more generally defined as "what new things need to be recorded by commit".