2012-06-12 68 views
30

有沒有任何方法可以查看已在3-way diff中提交的合併?在外部三維差異工具中查看已提交的Git合併

如果分支之間的巨大合併是在3周前提交的,有沒有什麼辦法可以在像BeyondCompare3這樣的外部diff工具中看到它的三向差異?我正在尋找只是在合併提交中更改的文件。如果我可以讓它只顯示衝突和手動更改的任何內容,而不是看到兩個分支之間的文件的全部差異,那麼獎金也是如此。

我不介意解決了2路差異,如果左側有< < < < < ===== >>>>>衝突標誌,右側是承諾的結果。

我試圖尋找DIFF樹DIFF-文件DIFFdifftool顯示,和其他人並不能弄明白。我知道gitk會在合併提交中顯示更改,但我不喜歡over-under diff視圖,並且很難理解何時發生大量更改。

如果只有我可以做類似git difftool --cc firstparent..secondparent..result

回答

2

我不知道該怎麼做的混帳三路差異沒有一些兩輪牛車,但對於一個雙向差異我會用meldmeld如果您簽出項目的三個不同版本,按目錄做一個新的差異並選擇「三向比較」選項,則可以執行三向比較。

首先安裝MELD

sudo apt-get install meld

然後設置MELD爲difftool

git config --global diff.tool meld

查找提交

git log | more

打開提交

git difftool <old-version>..HEAD

6

更新答案:我原來下面的腳本是在意義上有缺陷是$conflicting_files其實並不只包含真的有衝突的文件的版本,但被更改的所有文件在兩個分支機構(但不一定有衝突)。另外,它沒有使用在原理中廣告的「配置的合併工具」,但是diffuse。我已經在current version of the script中解決了這兩個問題。

原來的答覆: 比方說,我們與主要的發展事「主」分支,和「主題」分支,它增加了對大師的一些(舊的)狀態頂部的一些功能。通過說你正在尋找合併提交中改變的文件,我假設你只對在合併提交(包括任何衝突解決方案)中引入「主」的更改「主題」感興趣,自「主題」分支以來,在「主」中完成的相互衝突的更改。進一步假設「大師」是您的合併的第一父提交和「主題」是第二個,這可以用

git difftool <merge commit>^1 <merge commit> 

注意,它並沒有什麼意義使用三路差異這裏實現我們正在查看包含任何衝突解決方案的狀態。這也是GitHub針對合併提交顯示的內容,順便說一下,請參閱我用於測試的this merge commit

要看到的僅僅是衝突的文件及其決議3方區別工具,我想出了這個腳本

#!/bin/sh 

if [ $# -ne 1 ]; then 
    echo "Rationale : Show the conflict resolution of a given merge commit in the configured merge tool." 
    echo "Usage : $(basename $0) <merge commit>" 
    exit -1 
fi 

# Test e.g. with https://github.com/git/git/commit/8cde60210dd01f23d89d9eb8b6f08fb9ef3a11b8 
our=$1^1 
their=$1^2 
base=$(git merge-base $our $their) 

conflicting_files=$(git merge-tree $base $our $their | grep -A 3 "changed in both" | grep "base" | grep -Po "[^\s]+$") 
for f in $conflicting_files; do 
    diffuse -r $our -r $base -r $their $f 
done 

我使用Diffuse而不是Beyond Compare因爲Git修訂的第一直接合作而不是本地文件;根據自己的喜好更改參數的順序。要使用BC,你可能需要做臨時結賬;我也在考慮重做合併,應用已知的分辨率,並運行配置好的git mergetool,但這兩個想法都需要更多的工作來避免混亂你的工作樹並正確地進行清理。

+0

+1對於漫反射,它甚至可以用不同的提交做4路diff – Johan

0

像sschuberth,我寫了一個腳本,幫助我找到合併提交的變化。它使用vimdiff一次處理單個文件,以顯示父代和合並提交之間的差異。

#! /usr/bin/env ruby 

require 'pp' 
require 'tmpdir' 

merge = ARGV[0] || abort("I need a merge commit as the first argument") 
file = ARGV[1] || abort("I need a path as the second argument") 
cmd = "vimdiff" 

commits = `git log -n 1 #{merge} --format="%H %P"`.split(' ') 
abort "expected three commits" unless commits.size == 3 
commits[0], commits[1] = commits[1], commits[0] 
tmpdir = Dir.mktmpdir 
commits.each do |commit| 
    tfile = "#{tmpdir}/#{commit[0..10]}" 

    puts "git show #{commit}:./#{file} > #{tfile}" 
    `git show #{commit}:./#{file} > #{tfile}` 
    cmd += " #{tfile}" 
end 
puts cmd 
exec(cmd) 

它有點冒險,但我發佈它的機會有助於某人。