WinMerge implements something people sometimes calls a "two-way merge". This is a misnomer as a two-way "merge" is not a merge at all: it's just a diff, followed by a guided application of that diff. See Why is a 3-way merge advantageous over a 2-way merge?
WinMerge also implements a 3-way merge. Git only implements a 3-way merge, in its merge algorithms (git merge
and git merge-file
). That is, there must be a common base file.
You will therefore have to use something other than Git to achieve the file-level merge, or come up with a common base file:
- You don't need a common-ancestor commit (as in bk2204's answer), but having one makes things much easier, because Git itself will then do all the work. The common base file comes from the common merge base commit.
- You do need a common base file, though, if you want to use Git's tools.
In other words, if you like, you can:
- Start the merge using
git merge --allow-unrelated-histories
.
- Let Git stop with its messages about
CONFLICT (add/add)
.
- For each merge-result that is in this conflicted state:
- Pick out your two or three files. The two Git found are easy to get. Finding or creating a common merge base is your own problem; Git has no answer for you here.
- Use any tool of your choice to produce the merge result. This can be
git merge-file
, WinMerge, or whatever you like.
- Tell Git: this merge result is the correct result of merging. Git will accept whatever you give it as the correct merge result.
- Now that you have resolved all conflicts, finish the merge.
It's relatively easy, using bash scripting for instance, to automate the "for each conflicted file" part. git status
tells you which files are in UU
(unmerged) state, so that gives you the set of file names. You can then use git ls-files --stage <name>
on each file name to verify that there is indeed a slot-2 and slot-3 index entry for that name, and no slot-1 entry, i.e., that this is an "add/add" conflict. You can then use a rather user-unfriendly variant of git checkout-index
to get the two conflicting-input files into temporary files.
In fact, git mergetool
does all of the above for you, then runs any arbitrary command of your choice. If it's possible to run WinMerge on those files from git mergetool
directly, that might be a way to deal with this.
In other words, git mergetool
does the "for each conflicted merge, get the three files from Git" part of the work. Since Git didn't find a common merge base file, git mergetool
provides an empty file as the merge base to the tool of your choice. You can, knowing (or checking) that this file is empty, simply throw out the file and do your "2-way merge"—really, guided diff application—to produce the correct result.
(I have no idea how to run WinMerge itself, whether as a merge tool invoked from git mergetool
or any other way. So that part, you'll need to find or figure out on your own.)