Reputation: 31
I looked quite thoroughly yo find an answer to this and was not able too. Is there a simple way to prevent git from appending conflict markers to conflicted files when merging. I'd like to prevent git from adding "<<<< ==== -----" when there is a conflict in a file.
I tried using the gitattributes "binary" as I thought it was not gonna change the content of the file but without success. Any ideas?
Cheers!
Upvotes: 1
Views: 1178
Reputation: 3140
Considering your comments, you should set up Beyond Compare as mergetool
instead of manually opening the files with conflicts. Make sure you can run bc3
in the terminal first. You can then set it up like this (on Linux):
git config --global merge.tool bc3
git config --global mergetool.bc3.trustExitCode true
Now, when you run into a conflict, simply run
git mergetool
to open the conflicted file(s) in Beyond Compare.
Find more details and instructions for other operating systems on their support site: scootersoftware.com/support.php.
Upvotes: 1
Reputation: 45649
The goal is, if a file is conflicted, to
1) have git mark the file as "in conflict", and
2) be able to use Beyond Compare between the unmerged versions of the file ("our" version and "their" version).
I will caution that while this will work well in simple cases, it does somewhat defeat the 3-way merge approach that would typically be used (i.e. you're not looking at the changes in the context of a merge base), so in some more complex cases this will not be so easy. (For that reason I would recommend becoming familiar with a more "standard" approach to conflict resolution, so that you can at least fall back on it when necessary.)
But certainly there are a few ways to do it. The simplest thing is to start the merge normally
git checkout our_branch
git merge their_branch
and then, when it conflicts, revert the work tree to "our" version
git checkout --ours path/to/conflicted/file
If you have Beyond Compare configured to work as your diff tool, then you may be able to skip the checkout and just
git diff our_branch their_branch -- path/to/conflicted/file
but the disadvantage here is that BC won't have your working version of the file open, so you might not have the support you want for directly editing it.
So another option, more complex to set up but more automatic to use, is to set up a custom merge driver. A custom merge driver kicks in whenever both "our" version and "their" version of a given file are changed (relative to the "base" version). It is a script that receives, as parameters, the names of temporary files representing the various versions of the file. It creates a (tentative) merge result at the path for "our" version, and returns a status that indicates whether conflicts occurred.
Merge drivers are described in the documentation of the merge
attribute (at https://git-scm.com/docs/gitattributes). This also shows that, given a configured merge driver, you would associate it with file(s) at given path(s) with a .gitattributes
file. (You could associate it with all paths in your repo with an entry for *
, but if your repo may contain binary files you may want to either avoid doing that, or take care that your driver script behaves reasonably for binary files as well.)
The script itself would attempt a normal merge
git merge-file -p <ours> <base> <theirs> > <temp-path>
(where <ours>
, <base>
, and <theirs>
are from the scripts' parameters, and <temp-path>
is a new temporary file). If this command returns 0 (no conflicts), the script would move the output (<temp-path>
) over "our" version and return 0. Otherwise it would delete the temp file, leave "ours" unchanged, and return a non-zero value.
Now, that would make your merges work pretty much like the first approach, except you can skip the git checkout --ours
. That may not be worth it. But the advantage of this solution is, you can build on it to do a bit more.
The problem with all of the above solutions is, if a file contains any conflicts, then none of the changes (including non-conflicting changes) for that file are auto-merged. You have to process the entire file manually (with Beyond Compare, or whatever).
You could refine the merge driver script so that, in case of conflict, it reruns the merge with the --ours
strategy option
git merge-file --ours <ours> <base> <theirs>
(You would still want to run without the --ours
option first, so that you know if any conflicts occurred. If there are conflicts, then you delete the temp file, rerun with the --ours
option - but without the -p
or the output redirection - and, again, return a non-zero value so git knows there was a conflict.)
Finally, note that this should not be confused with what happens if you just run merge with either -s ours
(which ignores the other branch content entirely) or -X ours
(which resolves conflicts in favor of "our" version and reports no conflicts).
Upvotes: 0