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 .gitattributes
file, of course)
That would work as long as:
mergeScript
is somehow in the $PATH
of the user executing the merge driver.mergeScript
is executable, chmod +x
mergeScript
is 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 Makefile
An another option is to keep all the git drivers and .gitattributes
in the version history and also include something that easily activates all the drivers. For example, one project used Makefile
that had special target make gitdrivers
that activated all the git drivers in the repo.
This is needed because git
considers 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/config
to activate the drivers is the git style of granting the trust.
In practice, you can use Makefile
for 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
:
[attr]POFILE merge=merge-po-files
[attr]IMAGE diff=image
[attr]BINARY diff=binary -merge -text
locale/*.po POFILE
data/*.img BINARY
*.png IMAGE
and in Makefile
(indent should be done with U+0009 TAB character only but stackoverflow.com doesn't support it here):
developer-dependencies:
sudo apt install required-package1 required-package2
submodules:
@echo "Overwriting submodules with committed versions..."
git submodule sync
git submodule update --init
gitdrivers: developer-dependencies submodules
@echo "Overwriting git drivers with current version..."
git config merge.merge-po-files.driver "./bin/merge-po-files %A %O %B"
# show rough thumbnails in text mode for images
git config diff.image.textconv "./bin/image-textconv"
git config diff.image.binary "true"
git config diff.image.cachetextconv "true"
# show some extra information about binary files
git config diff.binary.textconv "./bin/binary-textconv"
git config diff.binary.binary "true"
@echo "All git drivers done."
Where files merge-po-files
, image-textconv
and binary-textconv
are suitable executables in the project subdirectory bin
. 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 git
to render ASCII presentation of images in diffs, merge gettext .PO files with special merge driver and prevent merging selected binary files even if git
heuristics declare those as text. Instead require selecting one version or the other for files marked as BINARY
. And show special user visible summary for the BINARY
files in diffs.
This way all developers just need to run make gitdrivers
once 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/config
is not included in the repository but you can include a script that re-creates suitable config using git config
commands. 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 use git 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With