Reputation: 3654
There's certain binary file types that I have written my own code to merge cleanly. I've tried to add my own merge strategy by adding a merge command line with a driver in .gitconfig and adding a file expression in .gitattributes to point to my merge program.
And it works - if I do a git merge with that file type, it calls my program - if I exit with 1 it fails and says there's a conflict - if 0 it succeeds.
HOWEVER - I can't find any documentation on how it gets parameters - ie how do I know what file is being merged - what file it's being merged with etc. They aren't coming in as environment variables... I know on the driver command line I can put some variables, but with trial and error, $PWD is the only one that I've found that works.
Can anyone point me to any documentation about how to write a custom merge strategy?
Upvotes: 2
Views: 377
Reputation: 489293
This answer is in two parts, because what you have described is not a merge strategy but rather a merge driver.
I don't think there is any proper documentation. There is only the source code. You can get a good high level overview of how the strategies work using GIT_TRACE
, though, because git merge
computes some information and then runs git-merge-recursive
or git-merge-octopus
or whatever other -s <strategy>
you've selected. If you write your own git-merge-oakey
command, and run git merge -s oakey
, you can view the arguments.
Your merge driver is invoked in the way described in the gitattributes documentation (search for Defining a custom merge driver). The %
-character substitutions will fill in the various arguments. As it says, wherever you write %O
, %A
, or %B
, Git will fill in the name of a temporary file that holds the data from the appropriate index stage (copied out to an ordinary file in the work-tree). You're expected to overwrite the file that %A
names.
how do I know what file is being merged ...
You don't know (and cannot tell) which file name is being merged; you're expected to complete your job using only the three input contents. Ultimately, there isn't necessarily a single file name anyway: Git may have detected a rename on one side of the merge, so that the file is named foo
in the merge base and on one side, and bar
on the other side. (As Hasturkun noted in a comment, the %P
placeholder will expand to whichever name Git is going to use as its best guess for the final path-name. Do not use this as one of the three inputs to the merge process, though—the three inputs are in the %O
, %A
, and %B
files.)
Upvotes: 6