RBL92
RBL92

Reputation: 31

Prevent git conflict markers

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

Answers (2)

alfunx
alfunx

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

Mark Adelsberger
Mark Adelsberger

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

Related Questions