是否有任何方法可以查看已经在三向差异中提交的合并?
如果在3周前提交了分支间的大规模合并,我是否可以在外部diff工具(如BeyondCompare3 )中看到它的三向差异?我正在寻找,只是在合并提交中更改的文件。如果我能让它只显示冲突和手动更改的任何内容,而不是看到两个分支之间文件的全部差异,那就更好了。
如果左边有<<<<< ===== >>>>>冲突标记,而右侧是提交结果的话,我不介意进行双向区分。
我试着看了一下difftool,diff-file,diff,散乱的工具,显示,以及其他的,但都搞不清楚。我知道gitk只会在合并提交中显示更改,但我不喜欢diff视图下的过度,而且很难理解当有大量更改时。
如果我能做一些像git difftool --cc firstparent..secondparent..result这样的事情
发布于 2012-07-06 15:20:29
更新的回答:--我下面的脚本的原始版本--存在缺陷,因为$conflicting_files实际上并不只包含真正有冲突的文件,而是包含在两个父分支中更改的所有文件(但不一定有冲突)。而且,它使用的不是“配置的合并工具”,而是diffuse。我已经在脚本的当前版本中解决了这两个问题。
最初的回答:假设我们有一个“主”分支,它正在进行主要的开发,而一个“主题”分支,它在主(旧的)状态之上添加了一些特性。通过说您只是在寻找在合并提交中更改的文件,我假设您只对合并提交中引入到“主”的“主题”(包括任何冲突解决方案)中的更改感兴趣,而不是在“主”中进行的无冲突更改,因为“主题”是分支的。进一步假设“主”是合并提交的第一个父级,而“主题”是第二个,则可以通过
git difftool <merge commit>^1 <merge commit>注意,当我们看到包含任何冲突解决的状态时,在这里使用三向差异是没有意义的。顺便说一句,这也是GitHub为合并提交所展示的,参见例如我用于测试的此合并提交。
为了只看到冲突的文件和它们的解决方案,我想出了这个脚本。
#!/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我使用的是漫射而不是无与伦比,因为第一个可以直接在Git提交上工作,而不是本地文件;根据您的喜好更改参数的顺序。要使用BC,您可能需要进行临时签出;我还考虑重新执行合并、应用已知的解析并运行任何配置过的git mergetool,但这两种想法都需要更多的工作才能避免工作树混乱,并正确地进行清理。
发布于 2012-06-19 01:48:35
我不知道如何在不使用黑客的情况下对git进行三向区分,但对于双向差异,我将使用meld。如果您签出了项目的三个不同版本,按目录执行一个新的diff并选择“三路比较”选项,meld就能够执行三向比较。
首次安装meld
sudo apt-get install meld
然后设置meld作为扩散工具。
git config --global diff.tool meld
找到提交
git log | more
打开提交
git difftool <old-version>..HEAD
发布于 2014-12-05 22:32:00
像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)这有点烦人,但我把它发布在偶然的机会中,它帮助了某人。
https://stackoverflow.com/questions/10998728
复制相似问题