-
-
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 |
Thanks Pete. This will save us an awful lot of time ;)
Thank you very much, this is very useful!
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
Very cool.