在外部3路diff工具中查看已提交的Git合并 [英] View already-committed Git merge in external 3-way diff tool

查看:174
本文介绍了在外部3路diff工具中查看已提交的Git合并的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么办法可以查看已经在3-way diff中提交的合并吗?

如果分支之间的巨大合并是在3周前提交的,有没有什么方法可以在像BeyondCompare3这样的外部diff工具中看到它的三维差异?我正在寻找仅在合并提交中更改的文件。奖金,如果我能得到它只显示我的冲突和任何手动改变,而不是看到两个分支之间的文件的全部差异。

我wouldn'如果左侧具有<<<<<< ===== >>>>>冲突标记,右侧是提交的结果。



我试着看看 diff-tree diff-files diff difftool show 等等,并且找不到它。我知道gitk会在合并提交中显示更改,但我不喜欢over-under diff视图,并且很难理解何时发生大量更改。



如果我只能做一些像 git difftool --cc firstparent..secondparent..result

解决方案

更新后的答案:我的原始版本的脚本在 $ conflicting_files 事实上确实存在缺陷不仅包含真正有冲突的文件,而且包含在两个父分支中更改的所有文件(但不一定有冲突)。此外,它并未使用在合理性中广告的配置的合并工具,而是使用 diffuse 。我已经解决了目前的两个问题版本的脚本

原始答案:
假设我们有一个主分支,主分支正在进行开发,还有一个主题分支,它在一些(较旧的)主状态之上增加了一些功能。通过说你正在寻找合并提交中改变的文件,我假设你只对在合并提交(包括任何冲突解决方案)中引入主的更改主题感兴趣,自主题分支以来,在主中完成的相互冲突的更改。进一步假设master是合并提交的第一个父代,第二个是topic,这可以通过使用

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

注意在这里使用3-way diff是没有意义的,因为我们正在查看声明包含任何冲突解决。这也是GitHub针对合并提交显示的内容,顺便说一下,请参阅这个合并提交,我用于测试。



要在三向diff工具中查看冲突的文件及其分辨率,我想出了这个脚本

 #!/ bin / sh 

if [$#-ne 1];那么
echo原理:在配置的合并工具中显示给定合并提交的冲突解决方案。
echo用法:$(basename $ 0)< merge commit>
出口-1
fi

#例如与https://github.com/git/git/commit/8cde60210dd01f23d89d9eb8b6f08fb9ef3a11b8
我们= $ 1 ^ 1
他们= $ 1 ^ 2
base = $(git merge-base $我们$他们的)$ |
$ b conflictting_files = $(git merge-tree $ base $ our $ their | grep -A 3)在| grepbase| grep -Po[^ \s] + $)
for $在$ conflicting_files; do
diffuse -r $我们-r $ base -r $他们$ f
完成

我使用 Diffuse 而不是超越比较,因为第一个可以直接在Git提交上工作而不是在本地文件上;根据自己的喜好更改参数的顺序。要使用BC,你可能需要做临时结账;我也在考虑重做合并,应用已知的解决方案,并运行配置好的 git mergetool ,但这两个想法都需要更多的工作来避免混乱工作树并妥善清理。


Is there any way to view a merge that has already been committed in a 3-way diff?

If a huge merge between branches was committed 3 weeks ago, is there any way I can see a 3-way diff of it in an external diff-tool like BeyondCompare3? I'm looking for just the files changed in the merge commit. Bonus if I could get it to only show me the conflicts and anything manually changed, as opposed to seeing the entire difference of a file between the two branches.

I wouldn't mind settling for a 2-way diff if the left side had the <<<<< ===== >>>>> conflict markers and the right side was the committed result.

I tried looking at diff-tree, diff-files, diff, difftool, show, and others and couldn't figure it out. I know gitk will show the changes just in the merge commit but I do not like the over-under diff view and it is very hard to understand when there are tons of changes.

If only I could do something like git difftool --cc firstparent..secondparent..result

解决方案

Updated answer: My original version of the script below was flawed in the sense that $conflicting_files in fact did not contain only the files that really had conflicts, but all files that were changed in both parent branches (but not necessarily had conflicts). Also, it was not using "the configured merge tool" as advertized in the rationale, but diffuse. I've addressed both issues in the current version of the script.

Original answer: Let's say we have a "master" branch with the main development going on, and a "topic" branch which adds some feature on top of some (older) state of master. By saying that you're looking for just the files changed in the merge commit I assume you're only interested in the changes "topic" introduced to "master" in the merge commit (including any conflict resolution), not in the non-conflicting changes that were done in "master" since "topic" was branched. Further assuming that "master" is the first parent of your merge commit and "topic" is the second, this can be achieved with

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

Note that it does not make sense to use a 3-way diff here as we are looking at the state that includes any conflict resolution. This is also what GitHub is showing for merge commits, by the way, see e.g. this merge commit which I have used for testing.

To see only the conflicting files and their resolutions in a 3-way diff tool I came up with this script

#!/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

I'm using Diffuse instead of Beyond Compare because the first can work directly on Git commits as opposed to local files; change the order of arguments to your liking. To use BC, you probably would need to do temporary checkouts; I was also thinking about redoing the merge, applying the known resolution, and run what ever git mergetool is configured, but both of these ideas would require more work to not clutter your working tree and to do the clean up properly.

这篇关于在外部3路diff工具中查看已提交的Git合并的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆