I already have following
[attr]POFILE merge=merge-po-files
locale/*.po POFILE
in the .gitattributes
and I'd like to get merging of branches to work correctly when the same localization file (e.g. locale/en.po
) has been modified in paraller branches. I'm currently using following merge driver:
#!/bin/bash
# git merge driver for .PO files (gettext localizations)
# Install:
# git config merge.merge-po-files.driver "./bin/merge-po-files %A %O %B"
LOCAL="${1}._LOCAL_"
BASE="${2}._BASE_"
REMOTE="${3}._REMOTE_"
# rename to bit more meaningful filenames to get better conflict results
cp "${1}" "$LOCAL"
cp "${2}" "$BASE"
cp "${3}" "$REMOTE"
# merge files and overwrite local file with the result
msgcat "$LOCAL" "$BASE" "$REMOTE" -o "${1}" || exit 1
# cleanup
rm -f "$LOCAL" "$BASE" "$REMOTE"
# check if merge has conflicts
fgrep -q '#-#-#-#-#' "${1}" && exit 1
# if we get here, merge is successful
exit 0
However, the msgcat
is too dumb and this is not a true three way merge.
For example, if I have
BASE version
msgid "foo" msgstr "foo"
LOCAL version
msgid "foo" msgstr "bar"
REMOTE version
msgid "foo" msgstr "foo"
I'll end up with a conflict. However, a true three way merge driver would output correct merge:
msgid "foo"
msgstr "bar"
Note that I cannot simply add --use-first
to msgcat
because the REMOTE could contain the updated translation. In addition, if BASE, LOCAL and REMOTE are all unique, I still want a conflict, because that would really be a conflict.
What do I need to change to make this work? Bonus points for less insane conflict marker than '#-#-#-#-#', if possible.