【发布时间】:2017-01-23 09:37:19
【问题描述】:
我想在两个具有公共合并基础的 git 分支之间执行三向差异,并使用 kdiff3 进行查看。
我找到了很多关于 SO 的指导(以及一些非常相似的问题(1、2、3)),但我还没有找到直接的答案。值得注意的是,this answer 上的评论暗示我想要的东西是可能的,但它对我不起作用。希望用户可以在这里插话:)
对于背景,当我执行合并时,我使用“diff3”冲突样式:
git config --global merge.conflictstyle diff3
我已将 git mergetool 配置为使用 kdiff3。
当解决合并冲突时,这显示了四个文件:
- 当前分支的文件 ($LOCAL)
- 另一个分支的文件 ($REMOTE)
- 两个分支的共同祖先文件 ($BASE)
- 合并的输出文件 ($MERGED)
但是,git difftool 只会拉出两个分支提示。我也想看看基础文件。 明确地说,我希望能够在合并之前执行此差异,包括在没有合并冲突的文件上。 (git mergetool 仅在存在冲突时显示三向差异)。
部分解决方案 #1:
使用单个文件,我可以导出三个版本并手动调用差异:
git show local_branch:filename > localfile
git show remote_branch:filename > remotefile
git show `git merge-base local_branch remote_branch`:filename > basefile
{kdiff3_path}/kdiff3.exe --L1 "Base" --L2 "Local" --L3 "Remote" -o "outputfile" basefile localfile remotefile &
这样做有两个问题:
- 我希望它适用于整个项目,而不仅仅是特定文件。
- 这太丑了!我可以编写脚本,但我希望有一种使用标准 git 进程的更简洁的方法。
部分解决方案 #2:
感谢this answer 和comment 的启发。
创建一个始终返回“false”的自定义合并驱动程序,这会创建一个冲突的合并状态,而不实际执行任何自动合并。然后使用git mergetool 执行差异。完成后中止合并。
-
添加到
.git/config:[merge "assert_conflict_states"] name = assert_conflict_states driver = false -
创建(或附加到)
.git/info/attributes以使所有合并使用新驱动程序:* merge=assert_conflict_states 执行合并,现在不会进行任何自动合并。
做差异。在我的例子中:
git mergetool带来了 kdiff3 三路合并。完成后,中止合并:
git merge --abort。撤消步骤 #2。
这将(排序)工作,除了 kdiff3 在调用时执行自动合并,所以我仍然无法看到预合并的差异。不过,我可以通过更改 Git 的库存 kdiff3 驱动程序文件(.../git-core/mergetools/kdiff3 删除 --auto 开关来解决此问题。
即便如此,这也存在以下令人无法接受的问题:
- 这仅在两个文件都更改时才有效! 在只有一个文件更改的情况下,更新的文件会替换旧文件并且永远不会调用合并。
- 我必须修改 Git kdiff3 驱动程序,它根本不可移植。
- 我必须在做差异之前和之后修改
attributes。 - 当然,我希望在不合并的情况下做到这一点 :)
赏金信息:
根据给出的答案,标准 Git 无法做到这一点。所以现在我正在寻找一个更开箱即用的解决方案:我如何调整 Git 来实现这一点?
这里有一个线索:显然,如果三个文件中只有一个发生了更改,则在合并结果中使用这个较新的文件而不实际调用合并驱动程序。这意味着在这种情况下永远不会调用我的自定义“冲突创建”合并驱动程序。如果是这样,那么我的“部分解决方案 #2”实际上会起作用。
可以通过调整文件或配置来改变这种行为吗?或者也许有一种方法可以创建自定义差异驱动程序?我还没准备好开始玩 Git 源代码...
有什么聪明的想法吗?
【问题讨论】:
-
也许 diffmerge 工具可以在stackoverflow.com/questions/18131515/… 中轻松配置。
-
@Marina-MSFT 谢谢!但是该方法仅在合并失败后才有效,并且在想要差异(不合并)时我无法弄清楚如何做到这一点。
-
@Marina-MSFT,没有“diffmerge”工具。有一个difftool 和一个mergetool。前者是双向的,后者仅用于合并。
-
@JanHudec,我的意思是应用程序sourcegear.com/diffmerge/index.html。
标签: git version-control merge diff