我想在具有公共合并基础的两个 git 分支之间执行三向差异,并使用 kdiff3 查看它。
我发现了很多关于SO的指导(以及一些非常相似的问题(1 https://stackoverflow.com/q/26301307/3380131, 2 https://stackoverflow.com/q/3635788/3380131, 3 https://stackoverflow.com/q/33440597/3380131) ) 但我还没有找到直接的答案。值得注意的是,评论这个答案 https://stackoverflow.com/a/5818279/3380131意味着我想要的东西是可能的,但它对我不起作用。希望该用户可以在这里插话:)
对于背景,当我执行合并时,我使用“diff3”冲突样式:
git config --global merge.conflictstyle diff3
我有git mergetool
配置为使用 kdiff3。
解决合并冲突时,这显示了四个文件:
- 当前分支的文件($LOCAL)
- 另一个分支的文件($REMOTE)
- 该文件是两个分支的共同祖先 ($BASE)
- 合并的输出文件 ($MERGED)
然而,git difftool
只会拉起两个分支尖端。我也想看看基础文件。需要明确的是,我希望能够执行此 diffbefore合并,包括没有合并冲突的文件. (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:
Thanks to this answer https://stackoverflow.com/a/5091756/3380131 and comment https://stackoverflow.com/questions/5074452/git-how-to-force-merge-conflict-and-manual-merge-on-selected-file#comment40997817_5091756 for the inspiration.
创建一个始终返回“false”的自定义合并驱动程序,这会创建冲突的合并状态,而不实际执行任何自动合并。然后使用执行差异git mergetool
。然后在完成后中止合并。
-
Add to .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
switch.
即便如此,这仍然存在以下令人困扰的问题:
-
仅当两个文件都更改时才有效!在仅更改一个文件的情况下,更新的文件将替换旧的文件,并且永远不会调用合并。
- 我必须修改 Git kdiff3 驱动程序,它根本不可移植。
- 我必须修改
attributes
进行差异之前和之后。
- 当然,我希望在不合并的情况下做到这一点:)
赏金信息:
根据给出的答案,这对于标准 Git 来说是不可能的。所以现在我正在寻找一个更开箱即用的解决方案:如何调整 Git 来实现这一点?
这是一个线索:显然,如果三个文件中只有一个发生了更改,则在合并结果中使用这个较新的文件,而无需实际调用合并驱动程序。这意味着在这种情况下永远不会调用我的自定义“产生冲突”合并驱动程序。如果是的话,那么我的“部分解决方案#2”就会真正起作用。
可以通过调整文件或配置来改变这种行为吗?或者也许有一种方法可以创建自定义差异驱动程序?我还没准备好开始使用 Git 源代码......
有什么巧妙的想法吗?