Reputation: 6466
I've heard it mentioned that you can create your own strategies for detecting merge conflicts. This question, for instance, suggests that it's possible. I'd like to give this a try, but I can't find any further information at all.
I understand that I need to create some executable and have it in the path - no problem - but what will be passed to this executable, and what should it output
Upvotes: 1
Views: 152
Reputation: 489293
A merge strategy is one selected by git merge -s
. You're correct that you would just have to put an executable program into your $PATH
(or Git's git-core
directory, which the git
front end adds to $PATH
).
The problem is that writing a merge strategy is not trivial (in fact it's very hard in general) and the arguments that Git passes are undocumented. You will have to figure them out from the Git source, and be aware that they might change in a future version of Git. Some of them are secreted in environment variables—in particular, the legends you can attach to the commits involved in the merge are in environment variables that contain the hash ID of the commits in question.
(I have not written a merge strategy myself and don't have any particular advice, other than: use GIT_TRACE=1 git merge -s <strategy>
to invoke your strategy to see what the argv elements are. The hidden environment variables used to be exposed in the git stash
script but git stash
has been rewritten in C.)
Your merge strategy's job is to update Git's index to hold the merge result, then exit with a zero status (success); or, don't, and exit with a nonzero status—normally 1—to indicate failure. If you wish to be user-friendly it's advisable to update the work-tree based on any successful merge result, too. There may be a special exit status for "merge not even attempted" (vs "merge failed, I leave a mess for human to finish merge with") but that too is not documented.
The built in set of merge strategies is:
git-merge-recursive
: git merge -s recursive
invokes this one; it's the usual one most people are most familiar with.git-merge-resolve
: git merge -s resolve
invokes this. It's actually the same program as git merge-recursive
, it just does something different when there is more than one merge base commit.git-merge-octopus
: While git merge -s octopus
invokes this one, so does any git merge
that lacks a -s
option, but mentions more than one other-commit to merge.git-merge-ours
: git merge -s ours
invokes this.git-merge-subtree
: git merge -s subtree
invokes this. Like git-merge-resolve
, is just a variant of git-merge-recursive
.If you don't pass a -s
argument, Git will use -s recursive
unless you named two or more commit arguments.
As you can see from the list above, there are really only three strategies built in to Git: octopus, ours, and "everything else". The octopus strategy does not handle merge conflicts (at all), and -s ours
completely ignores all other input commits, which makes its code relatively simple, so most of the hard work is in the single remaining merge strategy.
Upvotes: 3