I’m creating a merge driver. I have defined a .gitattributes file as follows:
filename merge=mergeStrategy
I have created the merge driver in $PROJECT/.git/config as follows:
[merge "mergeStrategy"]
name = My merge strategy
driver = scripts/mergeScript.sh
This works fine locally, but I would like to commit this merge driver to the git repository so that the merge strategy is in effect for everyone.
Is there a way I can add this (or other Git configuration options) to the repository itself?
You could simply add and commit (and push)
script/mergeScript(along with the.gitattributesfile, of course)That would work as long as:
mergeScriptis somehow in the$PATHof the user executing the merge driver.mergeScriptis executable,chmod +xmergeScriptis without extension, to allow you to later change its content (from a bash shell to a Perl script to a C executable to …) if needed.(Thank you, MestreLion, for the last two points, as he mentioned them in the comment)
That was the case for you locally, as I suspect that ‘
.‘ was in your$PATH, but you cannot assume that for everybody.However, the local config file (
.git/config) won’t be pushed/cloned (as Alexandr Priymak points out in the comment), so the users still need to replicate the declaration of the custom merge driver.This is a basic safety measure, in order for you to not push a potential "harmful" script which would then be automatically executed at the next merge.
An alternative method using
MakefileAn another option is to keep all the git drivers and
.gitattributesin the version history and also include something that easily activates all the drivers. For example, one project usedMakefilethat had special targetmake gitdriversthat activated all the git drivers in the repo.This is needed because
gitconsiders custom drivers as potential security vulnerability and you need to do something to grant trust to any new drivers. The merge drivers and other hooks are executable code running on your user credentials that start automatically as a side-effect on git actions, so obviously extra care must be taken before running that code.Running code that changes
.git/configto activate the drivers is the git style of granting the trust.In practice, you can use
Makefilefor that (but you could use whatever build system or script that suits your project). For Ubuntu Linux hosts, you can simply do it like follows (example with three drivers):In file
.gitattributes:and in
Makefile(indent should be done with U+0009 TAB character only but stackoverflow.com doesn’t support it here):Where files
merge-po-files,image-textconvandbinary-textconvare suitable executables in the project subdirectorybin. If you have a project that needs to work on multiple platforms, you could have an extra dependency to build/link correct binary for the current platform.The example config tells
gitto render ASCII presentation of images in diffs, merge gettext .PO files with special merge driver and prevent merging selected binary files even ifgitheuristics declare those as text. Instead require selecting one version or the other for files marked asBINARY. And show special user visible summary for theBINARYfiles in diffs.This way all developers just need to run
make gitdriversonce after doing the initial clone. And they automatically get updates to drivers that they’ve already installed when they merge or rebase their working copy later. And if they’re not sure if they have the latest drivers, they can simply re-run the same command at any time. Note that the example above will reset all submodules you have which may or may not what you really want.TL;DR:
.git/configis not included in the repository but you can include a script that re-creates suitable config usinggit configcommands. For UNIX-like systems a shell script is great. If your project needs building the code you can hook installing the required drivers to build process if needed. Also note that it’s much safer to usegit config ...commands instead of trying to directly modify the config file because those commands will keep working even if the file format of that config file changed in the future.