Git mergetools help in solving merge conflicts. When a merge conflict occurs, you can run git mergetool to iterate over all files in conflict with a diffing program such as meld. If you are trying to merge encrypted files, almost all bits will differ. To add support for merging binary files we can create our own mergetool.

Mergetools are called with 4 arguments, the base file, the local file, the remote file and a file to store the result. The base file is a file containing the contents of the file to be merged at the first place in the git history where they were equal. The local file contains your changes, and the remote file contains changes from the branch you are merging or pulling from. The exit code of your merge tool should indicate if the merge was successful (0 for success, any other value for fail).

Here is a template for a bash based merge tool, however any programming language can be used:

#!/bin/bash
fbase=$1       # The first shared ancestor in git history
flocal=$2      # Your local file
fremote=$3     # File coming from the remote
fmerge=$4      # File to write the successful merge to

# write to $fmerge

exit 0    # only if successful, else exit 1 (not 0)

To let git know this script can be used as mergetool, following lines need to be added to the .git/config file of your repository (if you want to install your mergetool system wide, add then to your ~/.gitconfig):

[mergetool "my-gitmergetool"]
    cmd = scripts/git-my-gitmergetool "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
    trustExitCode = true

After adding this, you can resolve a merge conflict in FILE with:

git mergetool -t my-gitmergetool FILE

Note that you need to edit the .git/config file of your repository and that this is file cannot be shared trough git. This is a security measure, the cmd could be rm -rf ~

If you want to share a mergetool within a repository, make sure your mergetool is pushed and that notify contributors about the mergetool. This can be done by adding the code to the README or by creating a .gitconfig that needs to be appended to .git/config.

Example: KeePassXC merge

#!/bin/bash
fbase=$1       # The first shared ancestor
flocal=$2      # Your local file
fremote=$3     # File coming from the remote
fmerge=$4      # File to write the successful merge to

cp $flocal $fmerge
keepassxc-cli merge --key-file "..." -s "$fmerge" "$fremote"

exit $?        # copy exit code from keepassxc

The script above allows you to merge encrypted KeepassXC databases. This will ask you for the password of your database when using the merge tool. Note that the key file should not be added to your git repository as a security measure.