-
-
Save mezis/1605647 to your computer and use it in GitHub Desktop.
#!/bin/sh | |
# | |
# ******************************************* | |
# WARNING: this does *not* handle 3-way merges properly. | |
# Anything modified on the local branch since the common base will get ignored. | |
# | |
# FOR ANYONE LANDING HERE: | |
# This script is now updated as part of the git-whistles gem. | |
# https://github.com/mezis/git-whistles | |
# ******************************************* | |
# | |
# Custom Git merge driver - merges PO files using msgcat(1) | |
# | |
# - Install gettext | |
# | |
# - Place this script in your PATH | |
# | |
# - Add this to your .git/config : | |
# | |
# [merge "pofile"] | |
# name = Gettext merge driver | |
# driver = git merge-po %O %A %B | |
# | |
# - Add this to .gitattributes : | |
# | |
# *.po merge=pofile | |
# *.pot merge=pofile | |
# | |
# - When merging branches, conflicts in PO files will be maked with "#-#-#-#" | |
# | |
O=$1 | |
A=$2 | |
B=$3 | |
# Extract the PO header from the current branch (top of file until first empty line) | |
header=$(mktemp /tmp/merge-po.XXXX) | |
sed -e '/^$/q' < $A > $header | |
# Merge files, then repair header | |
temp=$(mktemp /tmp/merge-po.XXXX) | |
msgcat -o $temp $A $B | |
msgcat --use-first -o $A $header $temp | |
# Clean up | |
rm $header $temp | |
# Check for conflicts | |
conflicts=$(grep -c "#-#" $A) | |
test $conflicts -gt 0 && exit 1 | |
exit 0 |
I had a problem to set it up because of the name of the file, it must be named 'git-merge-po' without the '.sh' for this solution to work.
I didn't know that git rename application to command: git-merge-po become the command git merge-po, nifty.
Thanks you very much for this solutions !
Additional merge drivers can be found at http://stackoverflow.com/questions/16214067/wheres-the-3-way-git-merge-driver-for-po-gettext-files
In case your diffs look bad because of .po files in the repo, see http://stackoverflow.com/questions/2006351/gettext-po-files-under-version-control/11291001#11291001
What is a po files?
dbolser-ebi: I don't know how you hit this page without knowing what is a PO file.
A .po
file is used as a source for GNU gettext
tools. It's usually converted to .mo
file format with command msgfmt
which is also part of gettext. A .po
file looks a lot like a normal text file but it really is a database format for gettext localizations. And if you allow normal git merge driver to do the merge as if the file was a normal text file, you'll end up with a corrupted .po
file. The gettext does include a command called msgmerge
but despite its name, it is not suitable for merging different versions of localizations.
There was a pull request to add msg3way
to gettext around 4 years ago (http://lists.gnu.org/archive/html/bug-gnu-utils/2010-11/msg00051.html) but it never got any traction.
@mikkorantalainen: I found this page by searching on how to build a custom git merge strategy. This is one of the only examples that shows how you can build one and integrate it into your project.
For anyone still interested, git-whistles
is getting a proper 3-way PO merger. Doesn't rely on Perl and string wrangling line the SO suggestions pointed to by @mikkorantalainen (which were a great source of inspiration).
Here's a link to 3-way merge for PO files that I currently use: https://stackoverflow.com/a/68799310/334451
It has some ideas from my older driver and some ideas that @mezis used and I partially re-wrote it to run on multiple CPU cores as much as possible. I've been using it for a couple of years without any invalid merges so I consider that the best solution until gettext includes proper 3-way merge one day.
@mikkorantalainen: I found this page by searching on how to build a custom git merge strategy. This is one of the only examples that shows how you can build one and integrate it into your project.
me too
Thank you very much, this is very useful!