How can I do a three way graphical diff (not merge) with git?

寵の児 提交于 2019-12-20 06:14:15

问题


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


回答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.



来源:https://stackoverflow.com/questions/55819873/how-can-i-do-a-three-way-graphical-diff-not-merge-with-git

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!