Use three way diff for diff

Issue

Another S.O. question shows how to configure git to use a three way diff for merge conflicts.

Is it possible to set up this three way style as the default for a standard diff operation? If I request a diff between versions where there is a common root (that isn’t just one of the versions), changes from the common root will be shown in the diff.

Solution

I’m afraid the answer is no.

The ratonale for this is that no matter how you specify the arguments when calling git diff, it always considers just two entities (blobs or trees (most of the time inferred from the commits referring to them)).

In other words, that’s by design: git diff considers separate objects and does not do any history traversal. To cite the git diff manual page:

For a more complete list of ways to spell <commit>, see "SPECIFYING REVISIONS"
section in gitrevisions(7). However, "diff" is about comparing two endpoints,
not ranges, and the range notations ("<commit>..<commit>" and
"<commit>...<commit>") do not mean a range as defined in the "SPECIFYING RANGES"
section in gitrevisions(7).

On the other hand, with a suitable shell, you should be able to do that thing yourself. Say, given two commits, rev1 and rev2, you could use

git-diff3() {
  local rev1="$1" rev2="$2"
  diff3 <(git show "$rev1") \
        <(git show $(git merge-base "$rev1" "$rev2")) \
        <(git show "$rev2")
}

in a shell which understands <(...) (e.g. bash).

This function requires massaging to make it more useful/less fragile.

Answered By – kostix

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published