Git for GNOME Translators
Og Maciel provides an overview of using git to help translate GNOME, including setting up git, translating strings, and pushing changes to GNOME.
About the migration from subversion to git
Shortly after GNOME 2.26.1 was released, the GNOME project made the long waited migration from hosting most of their modules in Subversion to using Git as their main DVCS. The decision was taken after a long and painstaking process that included an online survey as well as many different threads and heated discussions taking place on mailing lists. It is not the objective of this article to discuss the merits of this decision and suffice to say that the task of migrating the many modules that comprises the entire GNOME cosmos was brilliantly handled by the migration team who were able to ensure that everyone had their modules available for use once the smoke settled.
Having spent most of my open source time dealing with Subversion to do translations for the Brazilian team, it was time then for me to let go of the past and embark on a new voyage of learning. It is the objective of this article to show how I’ve adapted my existing process of doing translations to use Git as well as share some tips that may be helpful to my fellow translators out there.
Getting started with git
The first thing we’re going to do is configure git so that it “knows” a little bit about you, so open up a console and run the following commands:
$ git config --global user.name "Og Maciel"
$ git config --global user.email email@example.com
$ git config --global color.ui auto
These commands will garantee that all of your commits will contain your user credentials as well as provide colored output for most commands we issue. You can verify what your current settings are by looking at your $HOME/.gitconfig file or running:
$ git config -l
I also like to add a couple of alias to some common commands, specially the one that is recommended to run when you update an existing checkout:
$ git config --global alias.up "pull --rebase"
As explained by the official GNOME GitHowTo, “the—rebase parameter is very important. Suppose that while you were updating your translation, another person pushed their own work. In this case, your local repository will be missing those commits and your attempt to push your work will fail. The—rebase parameter in git pull—rebase updates your local repository and any commits you performed are adapted so that they appear as if they have been done at the moment you run this command.”
Here is what my current $HOME/.gitconfig file looks like:
name = Og Maciel
email = firstname.lastname@example.org
ui = auto
up = pull --rebase
ci = commit
stat = status
st = status
co = checkout
br = branch
df = diff
For the remaining of this article I will use the Deskbar Applet module to demonstrate how you would use both Damned Lies and Git to do some serious translation!
Checking out a module
For those who do not have commit access to the GNOME repositories, you can check out the source code for the deskbar-applet module running the command:
$ git clone git://git.gnome.org/deskbar-applet
If you do however have commit access, you can then check out using the following syntax:
$ git clone ssh://USERNAME@git.gnome.org/git/deskbar-applet
where USERNAME is your valid user name associated to your ssh key. Once you run one of these commands you should have a deskbar-applet directory created in your current directory. That’s not too complicated but are you sure you’re going to remember this syntax say, 2 weeks from today? I don’t know about you but I really like shortcuts and simpler things to remember, and a really nice tip for checking out GNOME modules is to run the following command:
$ git config --global url.ssh://email@example.com/git/.insteadof gnome:
This will add the following section to your global git configuration in your $HOME/.gitconfig:
insteadof = gnome:
Once you’ve added this little nugget you will then be able to checkout any GNOME module by running:
$ git clone gnome:deskbar-applet
Obviously, if you don’t have commit access you should change the url to use the generic git://git.gnome.org form.
We now can take a look at the contents of the deskbar-applet:
$ cd deskbar-applet/
$ ls -l
<del>rw-rw-r</del>- 1 omaciel omaciel 967 2009-06-07 20:01 acinclude.m4
<del>rw-rw-r</del>- 1 omaciel omaciel 161 2009-06-07 20:01 AUTHORS
-rwxrwxr-x 1 omaciel omaciel 1014 2009-06-07 20:01 autogen.sh*
<del>rw-rw-r</del>- 1 omaciel omaciel 266205 2009-06-07 20:01 ChangeLog.pre-git
<del>rw-rw-r</del>- 1 omaciel omaciel 6759 2009-06-07 20:01 configure.ac
<del>rw-rw-r</del>- 1 omaciel omaciel 17992 2009-06-07 20:01 COPYING
drwxrwxr-x 3 omaciel omaciel 4096 2009-06-07 20:01 data/
drwxrwxr-x 7 omaciel omaciel 4096 2009-06-07 20:01 deskbar/
<del>rw-rw-r</del>- 1 omaciel omaciel 1221 2009-06-07 20:01 deskbar-applet.doap
drwxrwxr-x 3 omaciel omaciel 4096 2009-06-07 20:01 doc/
drwxrwxr-x 16 omaciel omaciel 4096 2009-06-07 20:01 help/
<del>rw-rw-r</del>- 1 omaciel omaciel 9498 2009-06-07 20:01 INSTALL
drwxrwxr-x 2 omaciel omaciel 4096 2009-06-07 20:01 m4/
<del>rw-rw-r</del>- 1 omaciel omaciel 119 2009-06-07 20:01 MAINTAINERS
<del>rw-rw-r</del>- 1 omaciel omaciel 309 2009-06-07 20:01 Makefile.am
<del>rw-rw-r</del>- 1 omaciel omaciel 104649 2009-06-07 20:01 NEWS
drwxrwxr-x 2 omaciel omaciel 4096 2009-06-07 20:01 po/
<del>rw-rw-r</del>- 1 omaciel omaciel 1524 2009-06-07 20:01 README
<del>rw-rw-r</del>- 1 omaciel omaciel 2819 2009-06-07 20:01 TODO
We can also take a look at all the existing branches:
$ git branch -a
Doing translations using the master branch
So now let us roll up our sleeves and do some real work! Assuming that you want to work with the translation of the current development branch, once you’ve checked out the module, you could start editing the messages catalog (your *.po file) using a text editor or any other graphical tool such as gtranslator or poedit.
I usually like to update the messages catalog template (*.pot file) first, followed by updating the messages catalog itself in order to have an up to date working copy. If I wanted to update the Brazilian Portuguese catalog, I’d run:
$ cd po/
$ intltool-update --pot
$ intltool-update pt_BR
Now that I have an updated message catalog I can start doing my work and translate whatever strings need to be translated or fix anything that is marked as being “fuzzy”. I could also take the work done by other collaborators and apply here, which is something I do quite often as I shall relate now.
You see, for those who don’t enjoy working with the command line or playing with versioning control systems, there is the “Damned Lies” system (or as I like to call it, “Djamned Lies” ever since it was ported to Django), a web interface that allows you to download the messages catalog and later on submit it back for revision and approval by someone with commit access. Damned Lies is much more than just a place to download and submit translations, as it allows for the administration of a team and lets registered users reserve a module for translation and request feedback when in doubt about the meaning of a word. So for this demonstration I will then reserve the Deskbar Applet for translation under the master branch.
I could then download the message catalog from the web site and start working on it, but as I already have the source code checked out, I used my local copy instead. After fixing the only 2 fuzzy strings remaining, I validated the format of my message catalog so as to make sure the file can be properly parsed and compiled, as well as not get yelled at! 🙂
$ msgfmt -cvo /dev/null pt_BR.po
357 translated messages.
Great! The file was validated and we can now submit it back via the web interface for revision and approval.
The moment I submit this file all those members from the Brazilian Portuguese team with commit access will be notified by email of the event. As I happen to be one of those with commit access, I can now commit my changes and push it upstream.
$ git commit -a -m "Updated Brazilian Portuguese translation."
$ git push
It is now up to me to mark Deskbar Applet as committed in Damned Lies and this way notify whoever submitted the translation that their work has been committed. I usually like to append the actual log message in the Comment field so that people can follow the commit if they so choose.
You could also send the translation back for more review along with some feedback and wait until the new translation comes back again.
Committing on behalf of someone else:
So far the example I used had only one player in the roles of translator and committer, but what if I had received a notification that Vladimir Melo, a fellow translator from the Brazilian team, had finished translating the Evince module and had uploaded his work waiting for someone to commit it?
To make things more interesting, what if he had worked in the GNOME 2.26 branch and not master as I had before? So let us first clone the Evince module:
$ git clone gnome:evince
$ cd evince
It is very important to remember that this time around we’re not working with the master branch, but the 2.26 branch (more specifically, the origin/gnome-2-26 branch as seen by running git branch -a). What that means is that you should then create a new branch that will clone the origin/gnome-2-26 branch in your current checkout.
$ git checkout --track -b gnome-2-26 origin/gnome-2-26
You should now have a brand new gnome-2-26 branch and should have been automatically switched to it:
$ git branch -a
* gnome-2-26 master
As I mentioned before, I like to make sure I have an up to date copy of the messages catalog template around:
$ intltool-update --pot
You then go to the corresponding page in Damned Lies (the notification email you get has the link for the newly submitted translation for Evince) and download the translation file, using it to replace the current message catalog in your checkout folder.
As different translators will use different text editors or graphical tools, I then like to handle issues that arise when lines get wrapped around and yield a much bigger delta due to the lines shifting around. In other words, I like my diffs to be as small as possible and only show what really changed! The magic incantation I use is:
msgmerge --update --previous pt_BR.po *.pot
Remember to validate the format of your final messages catalog file as well:
$ msgfmt -cvo /dev/null pt_BR.po
325 translated messages.
Now all there is left to do is commit the changes and push it through:
$ git commit -a -m "Updated Brazilian Portuguese translation." --author "Vladimir Melo <firstname.lastname@example.org>"
Created commit 1535a8e: Updated Brazilian Portuguese translation.
1 files changed, 264 insertions(+), 194 deletions(-)
$ git push
Wait, have you noticed anything different in the syntax for this commit? The—author bit there is used when you are committing changes on behalf of someone else. Once my commit goes through, Vladimir will be credited as having done the translation.
One more scenario before wrapping up? What if you wanted to apply the same changes done in the origin/gnome-2-26 branch to the master branch? Easy! First let’s go back to the master branch and then “transplant” our changes to it:
$ git checkout master
$ git branch -a
gnome-2-26 * master
Now we perform the transplant:
$ git cherry-pick 1535a8e
Finished one cherry-pick.
Created commit 1535a8e: Updated Brazilian Portuguese translation. 1 files changed, 264 insertions(+), 194 deletions(-)
$ git push
“But Og, what the heck is the ‘1535a8e’ piece you added to the cherry-pick command?”, you ask. That is the revision number from the previous commit we did when pushing our changes to the origin/gnome-2-26 branch. If you forget this information, just switch back to the other branch and let git log show you the way.
Well, I hope that I haven’t lost you by now with this lengthy article, but if you’ve made it all this way and feel as lost as you were when you started, have no fear! Take a look at the documentation written up for translators or just ask someone in the mailing lists. You can also find me on irc hanging out at the #gnome-hackers channel on GimpNet and I’ll try my best to help you.
About the author
Og Maciel is a QA Engineer for rPath and a long time contributor to the translation efforts of several upstream projects. When not spearheading new projects or communities, he likes to fish, watch ice hockey and spend time with his 2 lovely daughters and wife in Chapel Hill, North Carolina.