0

I have two branches in git that are similar and I want to manually pull those changes into a third branch that is quite different. Is it possible to do a three way graphical diff of those changes?

Graphical diff of two branches is currently setup and working well with 'meld'. The following displays a graphical meld window as expected:

  • git diff branch1 branch2 -- myfilename

I tried to do the following, but I get the ASCII output of 'diff --cc'.

  • git diff master branch1 branch2 -- myfilename

Is that a valid syntax to get a 3-way diff? What is the proper .gitconfig settings to have it open meld? I'm using Git version 1.8.2.1.

My expectation is to have the three files opened in a meld window, then I can look at the changes between branch1/branch2 and then visually make sure the same change is in master. I just realized that I can do this by checking out each file from the three branches independently, then passing the filenames as arguments directly to meld. The checkout can be done as per this SO answer: https://stackoverflow.com/a/888623/350265

Jeff
  • 1,315
  • 2
  • 17
  • 30
  • 1
    What output format do you expect? You may want to just run `diff3` directly. Note that there are various diff3 algorithms as well; see https://stackoverflow.com/q/3931490/1256452 and the link to a PDF in the answer. – torek Apr 23 '19 at 21:54

1 Answers1

1

The manual one-liner command

You can invoke meld on three versions of the file without using temporary files by combining the <(cmd) syntax in bash with your git show idea:

meld <(git show master:file) <(git show branch1:file) <(git show branch2:file)

This will pop up meld with files dev/fd/61, /dev/fd/62 and /dev/fd/63 refering to the file in each of the three branches. The names are not very friendly, but you'll get used to that. The point is that it will show what you want to see.

Scripting it

The obvious next step is to simplify the syntax with a script:

Create file ~/bin/git-meld3 (or anywhere else on your PATH):

#!/bin/bash
meld <(git show $1:$4) <(git show $2:$4) <(git show $3:$4)

Make it executable:

chmod +x ~/bin/git-meld3

Call it:

git meld3 master branch1 branch2 myfilename

The command works with any committish:

git meld3 master 36d1cf756 HEAD^^^ myfilename

A more flexible script

This ~/bin/git-meld script accepts two or three committishes:

#!/bin/bash
if [[ $# -eq 3 ]]; then
   meld <(git show $1:$3) <(git show $2:$3)
elif [[ $# -eq 4 ]]; then
   meld <(git show $1:$4) <(git show $2:$4) <(git show $3:$4)
else
   echo Usage: git meld committish1 committish2 [committish3] file >&2
   exit 1
fi

PS

On my own machine, I have to invoke meld like this: python2.6 /usr/bin/meld, possibly because it's not installed correctly, so this is my actual ~/bin/git-meld3 script:

#!/bin/bash
python2.6 /usr/bin/meld <(git show $1:$4) <(git show $2:$4) <(git show $3:$4)

Meld is old! the script says it requires Python 2.4, but it fails to compile with 2.7 or 3. Fortunately, it does run with 2.6, so I was able to test my solution.

joanis
  • 10,635
  • 14
  • 30
  • 40