2

I just tried to merging one of my branches, but unfortunately, there was a merge conflict because both my branch and the master added a file with the same name. Hence after sending the merge command I get:

...
Auto-merging Defines.php
CONFLICT (add/add): Merge conflict in Defines.php
Automatic merge failed; fix conflicts and then commit the result.

My problem is that git will alter the file to create a unified diff, rather than creating separate files to work from which I am used to with SVN. E.g. I would get three new versions of the file with the extensions .working, .merge-right and .merge-left.

Question

Is it possible to configure Git to create multiple files instead of creating a unified diff, when it encounters a merge conflict? This way I can use a tool like meld to view a side-by-side diff. Alternatively, is it possible to manually do this with commands similar to git checkout --ours [filename] and git checkout --theirs [filename] but have it write to a new file rather then the original?

Programster
  • 12,242
  • 9
  • 49
  • 55
  • https://stackoverflow.com/questions/34119866/setting-up-and-using-meld-as-your-git-difftool-and-mergetool – max630 Nov 27 '17 at 13:54
  • I have already set up meld as my merge tool, and from reading that post, I can see that I could use the command `git mergetool` to have meld open up with a 3 way diff, for which I need to ensure the middle pane is as the file needs to be. However, I would still like to be able to configure git to just create separate files if possible. – Programster Nov 27 '17 at 14:12
  • This doesn't do exactly what you want, but you might be interested in setting the `merge.conflitStyle` to `diff3`, which produces unified merges but with excepts from all files. – SpoonMeiser Nov 27 '17 at 16:14

2 Answers2

2

I have sometimes done this manually. As you've noted, this is kind of a pain in the neck because it's not so simple to check a file out to an alternate path. You could of course check out the base version, then rename it, then check out "their" version, then rename it, then check out "our" version, then rename it. And since this would be scripted, the extra steps aren't that bad. Alternately you could cobble something together from plumbing commands, though I'd have to think that one through and it doesn't seem worth it when the above works fine.

If you want to configure git to do this on its own, you probably need to write a custom merge driver. Merge drivers have access to the three versions of the file so putting them at appropriate paths in the working tree would be easy. See "Defining a custom merge driver" in the gitattributes documentation (https://git-scm.com/docs/gitattributes). Apart from having to work out the details of delegating to the regular merge strategies in most respects, the down side is that once this has run you'd have the .working, .merge-left, and .merge-right files to be cleaned up from your work tree. (And of course it shouldn't be an issue, but there's the potential for conflicting with the name of an actual file.)

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • I think at the end of the day, if I want a full-blown solution I have to write a merge driver like you said, so I'm marking this as the answer for now although max's answer below will be what I'm doing in the meantime. – Programster Nov 28 '17 at 08:08
1

I don't know how to make it automatically at conflict but you can extract them from index manually:

git cat-file -p :1:dir/file >dir/file.base
git cat-file -p :2:dir/file >dir/file.local
git cat-file -p :3:dir/file >dir/file.remote

See gitrevisions

max630
  • 8,762
  • 3
  • 30
  • 55
  • Hey, that looks remarkably similar to what I've been doing in the meantime with `git show :1:folder/filename.php > filename.php.base` `git show :2:folder/filename.php > filename.php.ours` `git show :3:folder/filename.php > filename.php.theirs`. Are there any significant differences? – Programster Nov 28 '17 at 08:05
  • 1
    For blobs `cat-file` and `show` are very-very close, I cannot even say the difference. So yes, this should be basically the same. – max630 Nov 28 '17 at 16:01