【问题标题】:How could I force mergetool GUI (KDiff3) to be always shown?如何强制始终显示 mergetool GUI (KDiff3)?
【发布时间】:2013-02-25 14:51:55
【问题描述】:

如何强制始终显示合并工具 GUI 并禁用任何自动解析?

有时在合并期间发生冲突并且我使用合并工具时,它会在我对问题 “点击返回以启动合并解析工具 (kdiff3)”按 Enter 后立即返回 并且没有显示任何 GUI,并且似乎解决了冲突。

我现在已将 Git 配置为使用 KDiff3 作为合并工具,但是当我将 codecompare 作为指定的合并工具时也会发生这种情况。我知道 KDiff3 中有一个选项“自动保存并在合并时退出而不会发生冲突”,理论上这可能会导致所描述的行为,但我一直禁用/取消选中此选项。

另外,在Git mergetool gitconfig中直接有trustExitCode选项,我设置为true,但即使设置为false,GUI也不会显示。

我不确定谁会自动解析。 Mergetool 在某些预处理或 KDiff3 中?

我在 Windows 上运行并安装了 Git 扩展。

特定于 KDiff3 的类似问题,也在这里提出:Kdiff3 won't open with mergetool command

【问题讨论】:

    标签: git git-merge kdiff3 mergetool


    【解决方案1】:

    Git 将--auto 硬编码为 KDiff3 的命令行选项,如果所有冲突都可以由 KDiff3 自动解决,这会导致 GUI 不显示。在 KDiff3 设置中,您可以指定要忽略的命令行选项,但将 --auto 放在那里对我不起作用。

    作为一种解决方法,我将自己的 KDiff3 变体配置为合并工具:

    git config --global mergetool.kdiff3NoAuto.cmd "kdiff3 --L1 \"\$MERGED (Base)\" --L2 \"\$MERGED (Local)\" --L3 \"\$MERGED (Remote)\" -o \"\$MERGED\" \"\$BASE\" \"\$LOCAL\" \"\$REMOTE\""
    

    这与 Git 默认使用的 KDiff3 非常相似,但没有 --auto 标志。

    现在您可以调用git mergetool -t kdiff3NoAuto 或将kdiff3NoAuto 配置为全局合并工具,解决冲突时将始终显示KDiff3。

    关于您问题的第二部分,如果您真的想禁用任何自动解析,只需将--qall 添加到上面的kdiff3 命令行即可。但是随后您必须手动解决文件中的所有更改,即使是那些不会导致 Git 冲突的更改。最好的情况是:KDiff3 显示 Git 如何合并文件并将冲突留给用户选择。

    【讨论】:

    • 哇,太好了。谢谢!您也可以考虑回答链接的问题或在此处添加一些评论评论,因为它最终可能是完全相同的问题。
    • 谢谢。我已在另一个问题中链接到此答案。
    • 在 KDiff3 0.9.98(64 位)中将“--auto”添加到忽略的命令行选项对我有用。设置菜单 -> 配置 KDiff3 -> 集成选项卡。出现自动解析信息对话框,但随后会显示结果合并,允许进一步编辑。
    • @bobesponja 为什么不添加您的解决方案作为答案? :)
    【解决方案2】:

    不用配置只在发生冲突时调用的mergetool,只需用KDiff3设置一个合并驱动:

    git config merge.kdiff.driver 'kdiff3  "%O" "%A" "%B" -o "%A" --L1 "Nearest Common ancestor"  -L2 "Working Copy" --L3 "Version from Other Branch"'
    

    您可以通过添加--global 将此驱动程序设为全局。 但是你需要在你的存储库中添加一个 .gitattribute:

    *  merge=kdiff
    

    【讨论】:

      【解决方案3】:

      git mergetool 的行为完全取决于选择的合并工具和 Git 传递给它的命令行。因此,要改变它的行为,你需要找到一个命令行,并配置 Git 以使用该命令行。

      我自己也有这个问题(特别是关于 KDiff3),PiQuer's answer 让我参与其中,但它让我开始思考。应该有一种方法可以准确地为 KDiff3 复制 Git 的默认行为,除非没有 --auto 选项(这是导致 KDiff3 不显示 GUI 的原因)。

      看起来 KDiff3 合并工具的默认命令的来源在文件 git/mergetools/kdiff3 中。这看起来像一个 shell 脚本,所以我们应该能够准确地复制它!把它放在一行上,删除--auto,然后转义给我们这个:

      git config --global mergetool.kdiff3.cmd "if \"\$base_present\"; then \"\$merge_tool_path\" --L1 \"\$MERGED (Base)\" --L2 \"\$MERGED (Local)\" --L3 \"\$MERGED (Remote)\" -o \"\$MERGED\" \"\$BASE\" \"\$LOCAL\" \"\$REMOTE\" >/dev/null 2>&1; else \"\$merge_tool_path\" --L1 \"\$MERGED (Local)\" --L2 \"\$MERGED (Remote)\" -o \"\$MERGED\" \"\$LOCAL\" \"\$REMOTE\" >/dev/null 2>&1; fi"
      

      base_presentmerge_tool_path 变量在 Git 文档中并未具体提及可在 mergetool.<tool>.cmd 中使用,因此该命令可能在未来某个时候无法按原样工作。但是,它们可以很容易地替换为一个命令来测试BASE 是否分别引用存在的文件和 KDiff3 的硬编码路径。

      请注意,上述命令替换了 Git 的 kdiff3 合并工具的默认命令,而不是创建一个单独的命令。

      关于原始问题中的其他几点:

      • trustExitCode 设置告诉 Git 合并工具的退出代码是否正确指示合并是否成功。一旦合并工具退出,它不会影响合并工具的行为,而是影响 Git 的行为。请参阅manual for git-mergetool
      • 您在输入git mergetool 后看到的自动分辨率都是由合并工具本身完成的。 git mergetool 只是在需要合并的文件版本上调用外部工具。

      【讨论】:

      • 如何撤消此操作?我执行了命令,现在 kdiff3 根本不再打开,我意识到当我在 Windows 上时该命令可能仅适用于 Linux。如何恢复默认行为?
      • 您使用git config --unset 删除设置。如果您使用了我上面给出的确切命令,那么git config --global --unset mergetool.kdiff3.cmd 将只删除该设置。此设置在 Windows 上绝对可以正常工作。我主要在 Windows 上使用 Git。不确定您遇到问题的原因。可能需要做的一件事(取决于您的系统)是将 mergetool.kdiff3.path 设置为 KDiff3 的完整路径。
      • 我错了。我没有意识到我实际上是在 Windows 10 的 WSL/Ubuntu 环境中,我无法使用 kdiff3。因此,在退出 WSL 之后,在 Windows 上,我最终使用了 PiQuer 的解决方案(这样我就不会再次覆盖 kdiff3 命令),它可以工作,但我相信你的解决方案也可以工作。谢谢。
      【解决方案4】:

      如果问题与不需要的冲突自动解决严格相关...

      KDiff3 打开后,您只需从菜单中按Merge / Set Deltas to Conflicts,状态就会更新为漂亮的、人为驱动的冲突解决问题。

      【讨论】:

      • git mergetool --tool=kdiff3 ?
      【解决方案5】:

      Bob esponja 对已接受答案的评论使用 KDiff3 0.9.98 对我来说非常有效。

      --auto 添加到要忽略的命令行选项:

      Settings | Configure KDiff3... | Integration tab.
      

      KDiff3 出现冲突对话框,指示 未解决冲突的数量:0,但您可以根据需要检查/修改合并状态。

      比配置您自己的变体更方便一点,因为无论是从 git mergetool、Source Tree 还是使用 mergetool 的任何工具,它都可以按预期工作。

      【讨论】:

      • 注意 双破折号:'--auto'。 Kdiff3 的所有默认值都已经使用了单破折号(暗示“-auto”),我首先尝试过……但是单破折号对我不起作用。
      【解决方案6】:

      我发现的最简单的方法是:

      git config --global mergetool.kdiff3.cmd 'if $base_present; then "$merge_tool_path" --L1 "$MERGED (Base)" --L2 "$MERGED (Local)" --L3 "$MERGED (Remote)" -o "$MERGED" "$BASE" "$LOCAL" "$REMOTE" >/dev/null 2>&1; else "$merge_tool_path" --L1 "$MERGED (Local)" --L2 "$MERGED (Remote)" -o "$MERGED" "$LOCAL" "$REMOTE" >/dev/null 2>&1; fi'
      git config --global difftool.kdiff3.cmd '"$merge_tool_path" --L1 "$MERGED (A)" --L2 "$MERGED (B)" "$LOCAL" "$REMOTE" >/dev/null 2>&1'
      

      作为参考,直接在source on GitHub 中查看长期存在的默认值,我仅通过删除--auto 进行了更改。

      如果遇到任何问题,请使用以下命令恢复默认设置:

      git config --global --unset mergetool.kdiff3.cmd
      git config --global --unset difftool.kdiff3.cmd
      

      【讨论】:

      • 这里我最喜欢的是引号样式,它比必须在双引号中转义双引号更具可读性。
      猜你喜欢
      • 2012-06-08
      • 2011-05-14
      • 1970-01-01
      • 2012-04-04
      • 2020-09-15
      • 1970-01-01
      • 2020-10-28
      • 1970-01-01
      • 2017-08-16
      相关资源
      最近更新 更多