我在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:
创建一个自定义合并驱动程序,始终返回“false”,这将创建一个有冲突的合并状态,而不会实际执行任何自动合并。然后使用git mergetool
执行差异比较。完成后中止合并。
Add to
.git/config
:[merge "assert_conflict_states"] name = assert_conflict_states driver = false
Create (or append to)
.git/info/attributes
to cause all merges to use the new driver:* merge=assert_conflict_states
Perform the merge, which now doesn't do any automerging.
Do the diff. In my case:
git mergetool
which brings up the kdiff3 three-way merge.When done, abort the merge:
git merge --abort
.Undo step #2.
.../git-core/mergetools/kdiff3
)来解决这个问题,具体方法是删除--auto
开关。即便如此,这个方法还存在以下几个严重问题:
- 只有当两个文件都发生了变化时才能使用。如果只有一个文件发生了变化,那么更新后的文件将替换旧文件,而合并操作则永远不会被调用。
- 我必须修改Git的kdiff3驱动程序,这样做根本不可移植。
- 在进行差异比较之前和之后,我必须修改
attributes
。 - 当然,我希望能够在不进行合并的情况下完成这个任务 :)
赏金相关信息:
根据提供的答案,标准的Git无法实现此功能。因此,我正在寻找更加开箱即用的解决方案:如何调整Git以实现此目的?
这里有一个线索:显然,如果只有三个文件中的一个发生了更改,则在合并结果中使用此新文件而不实际调用合并驱动程序。这意味着在这种情况下,我的自定义“冲突创建”合并驱动程序从未被调用。如果它被调用了,那么我的“部分解决方案#2”实际上就能够起作用。
是否可以通过调整文件或配置来更改此行为?或者也许有一种创建自定义差异驱动程序的方法?我还没有准备好开始玩弄Git源代码...
有什么聪明的想法吗?
cmd = 'C:/Program Files/KDiff3/kdiff3' $BASE $LOCAL $REMOTE -o $MERGED
。 - Christoph