How could I force mergetool GUI (KDiff3) to be always shown?

倾然丶 夕夏残阳落幕 提交于 2019-11-28 18:40:29
PiQuer

Git has --auto hard coded as a command-line option to KDiff3, which causes the GUI not to show up if all conflicts are auto-resolvable by KDiff3. In the KDiff3 settings you can specify command line options to ignore, but putting --auto there did not work for me.

As a workaround I configured my own variant of KDiff3 as the merge tool:

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

This is very similar to what Git uses by default for KDiff3, but without the --auto flag.

Now you can call git mergetool -t kdiff3NoAuto or configure kdiff3NoAuto as mergetool globally and KDiff3 will always show up when resolving conflicts.

Regarding the second part of your question, if you really want to disable any automatic resolving, just add --qall to the kdiff3 command line above. But then you have to manually resolve all changes in the file manually, even the ones that did not result in a Git conflict. The best scenario would be: KDiff3 shows how Git merged the files and leaves the conflicts open for the user to choose.

Joel Davies

The behavior of git mergetool is entirely dependent on the merge tool chosen and the command line Git passes to it. Therefore, to change its behavior, you need to find a command line that does what you want and configure Git to use that command line.

I had this question myself (specifically in regard to KDiff3), and PiQuer's answer got me part of the way, but it got me to thinking. There ought to be a way to replicate Git's default behavior exactly for KDiff3 except without the --auto option (which is what causes KDiff3 not to display the GUI).

It looks like the source for the default command for the KDiff3 merge tool is in the file git/mergetools/kdiff3. That looks like a shell script, so we ought to be able to copy it exactly! Putting that on one line, removing --auto, and escaping things gives us this:

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"

The base_present and merge_tool_path variables are not specifically mentioned in the Git documentation as being available to use in mergetool.<tool>.cmd, so it is possible at some point in the future that this command may not work as-is. However, they could easily be replaced with a command to test whether BASE refers to a file that exists, and a hard-coded path for KDiff3, respectively.

Note that the above command replaces the default command for Git's kdiff3 merge tool rather than creating a separate one.

Regarding a couple of other points in the original question:

  • The trustExitCode setting tells Git whether the exit code of the merge tool is a proper indication of whether the merge was successful. It will not affect the behavior of the merge tool but rather the behavior of Git once the merge tool has exited. See the manual for git-mergetool.
  • The automatic resolution you are seeing after typing git mergetool is all done by the merge tool itself. git mergetool merely invokes the external tool on the file versions that need to be merged.
sophana

Instead of configuring mergetool which is called only when there is a conflict, simply set up a merge driver with KDiff3:

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

You can make this driver global by adding --global. But you need to add a .gitattribute in your repository:

*  merge=kdiff

If the problem strictly relates to unwanted conflict auto-resolution...

Once KDiff3 has opened, you could just press a Merge / Set Deltas to Conflicts from the menu, and the state gets updated to a beautiful, man-driven conflict resolution problem.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!