3
votes

Can KDiff3 interpret standard diff conflict markers?

Explanation:

I currently have KDiff3 setup as my merge tool in Mercurial. I run my merges (e.g. hg merge) from a terminal session and when a conflict is encountered Mercurial invokes KDiff3 for 3-way merging, as expected.

What I would like to do is first use Mercurial's internal merge3 algorithm and leave the conflict markers in the files -- and then secondly resolve individual files at will (rather than attempting to complete all the merges at once).

I'd like to pass a merge tool to the resolve command (e.g. hg resolve --tool kdiff3 file.txt), but it looks like KDiff3 does not handle the conflict markers and instead wants three files supplied as command line arguments.

Is there a way to do what I want? I'd rather see the diffs in a GUI than edit around conflict markers manually.

1

1 Answers

2
votes

I am not entirely certain what precisely you want to do; I'm guessing, so correct me if I'm wrong.

First, pretty much all merge tools require two or three files to perform a merge. This is the way these tools are designed; tools that work on files with conflict markers directly are pretty rare. This, however, is something that is up to your selection of a tool that does this; Mercurial and kdiff3 cannot help you if that is what you need: you'd need a different tool.

Second, let's have an in-depth look at how merge tools are configured. You can review hg help mergetools for a list of available merge tools and how to select one, and hg help config.merge-tools (note the dash) for the configuration parameters that are required. You can review the kdiff3 settings by doing:

hg config merge-tools | grep -w kdiff3

By default, merge-tools.kdiff3.premerge should not be set, so hg merge will first attempt to use its internal merge algorithm to resolve conflicts and only fall back to kdiff3 (assuming you have it selected as your merge tool) for files that cannot be resolved without conflicts. How kdiff3 is invoked can be seen by doing:

hg config merge-tools.kdiff3.args

That default here should already be pretty close to what you want. I am assuming now that you don't want kdiff3 to start up up by default, but want to have control over when kdiff3 is invoked.

What you can do if you don't want to get dumped into a merge tool by default if there are conflicts – and I don't know how close it comes to what you want – is to first merge with one of the internal tools :merge, :merge3, or :fail. Either :merge or :merge3 will put conflict markers in the files that it cannot merge internally and mark the ones that it could merge as resolved, the rest as unresolved. The :fail merge tool will mark all files as unresolved that have changes on both sides, even if conflicts could be resolved (and will not add conflict markers). This can be done, e.g., via:

hg merge --tool :merge

At this point, you'll have some conflicts that Mercurial's internal merge tool was able to resolve and some that it could not resolve (check hg resolve -l to see their status or hg resolve -l -T '{ifeq(status,"U","{path}\n","")}' to just list unresolved files).

You can then call hg resolve --tool kdiff3 FILE (the --tool kdiff3 option can also be omitted if kdiff3 is your default merge tool) to resolve any conflicts in FILE. Mercurial will generate the local, base, and other revisions prior to calling the merge tool; as part of this process, any conflict markers in the local file will be wiped out, as that file will be replaced with a fresh copy of the working directory's first parent.