How to use Git for GNOME translators

This HowTo has a summary for the git commands that a GNOME translator (with coordinator or committer status in l10n.gnome.org) is likely to use for common translation tasks, and also a walkthrough that explains in detail how to use git to get the translation job done.

Summary of commands

Clone module from git.gnome.org (creates a directory called PACKAGENAME with the local repository)
$ git clone ssh://MYUSERNAME@git.gnome.org/git/PACKAGENAME

Now you update the translation file LL.po with your PO editor, scripts, etc.

Add a new file to the repository (required when you add a new file)
$ git add LL.po 

View if files have been modified/added, and not committed yet. 
$ git status

Commit the change to the LL.po file to your local repository, adding a commit message. Please mention if you are committing for someone else.
$ git commit LL.po -m "Updated MYLANGUAGE translation"
or
$ git commit LL.po -m "Updated MYLANGUAGE translation" --author "Rupert Monkey <rupert@banana-inc.com>"

View what you committed and is about to be sent (pushed) to git.gnome.org
$ git log origin..master

Push the commit to git.gnome.org
$ git push

Update your local repository
$ git pull --rebase

Contents

Detailed guide

Verify your account

We assume that you have already configured your SSH key and have an account. See the existing documentation when you got your commit account for more details. To verify that all is OK at this stage, run

$ ssh MYUSERNAME@git.gnome.org
PTY allocation request failed on channel 0
SSH authentication succeeded. Interactive login is not allowed.
Connection to git.gnome.org closed.
$_

The message SSH authentication succeeded is the important point here. If you see this, then your account is correctly configured, and you can continue with the rest of this document.

In case of a problem, try the same command with the -v parameter (for verbose). You should get lot of output, which is useful when you want to ask for help in diagnosing the problem. When asking for help, please submit all the output.

$ ssh -v MYUSERNAME@git.gnome.org
...
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = en_GB.UTF-8
PTY allocation request failed on channel 0
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
SSH authentication succeeded. Interactive login is not allowed.
                                                               debug1: channel 0: free: client-session, nchannels 1
Connection to git.gnome.org closed.
Transferred: sent 2992, received 2776 bytes, in 0.8 seconds
Bytes per second: sent 3730.5, received 3461.2
debug1: Exit status 1

Although it may sound weird, the above message means that SSH is configured correctly for you. The message SSH authentication succeeded. Interactive login is not allowed. says that everything worked fine! You can now clone repositories.

If you are prompted instead for a password, or you get Permission denied (publickey), this means that there is something wrong with your configuration. You either put the wrong username, or you do not have the correct SSH private key in your ~/.ssh/ Contact the gnome-i18n list for some help.

The currently available repositories are those found at http://git.gnome.org/, under the heading GNOME git repositories. As a translator, you would normally visit http://l10n.gnome.org/languages/, find your language, select the GNOME release and pick the module name from the GNOME release page.

Configure your git

There are a few one-off configuration commands for git.

$ git config --global user.name "Your Full Name Goes Here"
$ git config --global user.email you@yourdomain.example.com

This is important to do. Here you specify your name and e-mail address. This information is used when you commit your changes to the repository.

$ git config --global color.ui auto

This tells git to use color to the output of common commands. It is good to have this enabled.

In addition, add the following alias to your configuration.

$ git config --global alias.up "pull --rebase"
$ _

The default git pull is not suitable for development with a central repository, so we need to add --rebase. Since there is no git update command, we use the git up alias. We got this tip from the VLC GIT instructions page.

Finally, specify the default push type. We recommend upstream, which means we push commits from the current branch only.

$ git config --global push.default "upstream"
$ _

You can verify your current settings with

$ git config -l
user.name=Your Full Name Goes Here
user.email=you@yourdomain.example.com
color.ui=auto
alias.up=pull --rebase
push.default=upstream
$ _

Clone (download) a repository

Suppose we want to update our translation for zenity (displays dialogs). In Subversion (SVN) and CVS, we would 'checkout' in order to retrieve a snapshot of the source code of a module. In Git, we clone, which means we make a full standalone offline copy of the repository for the module. Actually, in Git, 'checkout' is still used for some other process, when switching between branches. The command to clone the repository is

$ git clone ssh://MYUSERNAME@git.gnome.org/git/zenity
Initialized empty Git repository in /media/GNOME/vcs/zenity/.git/
remote: Counting objects: 10221, done.
remote: Compressing objects: 100% (2603/2603), done.
remote: Total 10221 (delta 8127), reused 9416 (delta 7580)
Receiving objects: 100% (10221/10221), 5.69 MiB | 393 KiB/s, done.
Resolving deltas: 100% (8127/8127), done.
$ _

This creates a directory zenity with the source code of the module. The name zenity is derived from the repository name. We could actually specify a different directory name, by adding it as a last argument of the command, as we did with Subversion. It is simpler to keep the original repository name. In our case, this full repository of zenity occupied 16MB of disk space. Remember that when you clone a repository using your GNOME account, the command is

git clone ssh://MYUSERNAME@git.gnome.org/git/MODULENAME

When you use anonymous Git (anyone can do this), the command is however

git clone git://git.gnome.org/MODULENAME

Notice that there is no '/git/' after the hostname.

It is possible to convert an 'anonymous' clone into one that you can use to commit and push your translations (and vice versa). See tips below.

Update your local repository

Suppose you already have a local repository, created with the process described in the previous section. A few weeks have passed and you want to update your local copy (as in  svn update) so that you can update your translations.

$ cd zenity
$ git up
Current branch master is up to date.
$ _

In this case there was no development, no commits to zenity, therefore our clone of zenity is in synch with zenity at git.gnome.org.

$ cd zenity
$ git up
remote: Counting objects: 81, done.
remote: Compressing objects: 100% (46/46), done.
remote: Total 46 (delta 34), reused 0 (delta 0)
Unpacking objects: 100% (46/46), done.
From ssh://simos@git.gnome.org/git/zenity
   f60b04f..f84793e  master     -> origin/master
First, rewinding head to replay your work on top of it...
Fast-forwarded master to f84793e87c4fa62f1dbcb6b70dee8dff840d8d79.
$ _

In this case there have been commits and our local clone of zenity has just been updated. We are in synch with zenity at git.gnome.org.

Commit your changes

Now we enter the zenity/po directory and we update our translation.
Since the Git migration, translators do not have to edit ChangeLog files any more. The commit message is sufficient (the message you type with '-m'). The convention is for the commit message to start with a capital letter (as in Updated Greek translation), and be at most 72 characters long. We follow this convention in this HowTo.

So, now we are about send our changes. We recommend to type 'git status' to get a view of the changed files. This command shows what files have changed, and require to be committed.

$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   el.po
#
no changes added to commit (use "git add" and/or "git commit -a")
$ _

Only 'el.po' is modified and requires to be sent (pushed). In Git, we can explicitly add files, or we can use the '-a' parameter which adds automatically all modified files shown when we ran 'git status'. It is more straightforward to always specify the file when doing the commit. It is important to remember that we are not sending anything yet to git.gnome.org. We only 'commit' the changes to our local repository. There is a subsequent step to send the commits to git.gnome.org.

$ git commit -m "Updated Greek translation" el.po
[master]: created 941e444: "Updated Greek translation"
 1 files changed, 1 insertions(+), 1 deletions(-)
$ _

We append at the git commit line the files that we modified and we want to get committed. Now the translation update has been committed to our local repository.

If you're committing the changes someone else did, please respect him or her as the author and commit like this:

$ git commit -m "Updated Greek translation" --author "Rupert Monkey <rupert@banana-inc.com>" el.po
[master]: created 941e444: "Updated Greek translation"
 1 files changed, 1 insertions(+), 1 deletions(-)
$ _

Here we add the author of the translation changes (in this case Rupert Monkey) to the commit. It will then have Rupert being stored as the author of that change and you will be recorded as the committer of this change.

When you commit a change to the repository, make sure your change reflects a single purpose: the fixing of a specific bug, the addition of a new feature, or some particular task. For example, take care to not break to tree by committing a new entry in the LINGUAS file without committing the corresponding PO file.

$ git commit -m "Added LL translation" LINGUAS LL.po 
[master]: created 7412e91: "Added LL translation"
 2 files changed, n insertions(+), m deletions(-)

Push (send) your commits to git.gnome.org

We are ready to finally 'push' the translation to git.gnome.org.

$ cd zenity
$ git push
Counting objects: 7, done.
Delta compression using 2 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 375 bytes, done.
Total 4 (delta 3), reused 0 (delta 0)
To ssh://MYUSERNAME@git.gnome.org/git/zenity
   0b4069d..941e444  master -> master
$ _

This command does not take any parameters.

Working with branches

When you clone a repository with git clone, you download all necessary files for all branches. By default, git activates the master (HEAD) branch, shown as master in your local repository. You can verify with

$ git branch
* master
$ _

How can you view other available branches, so that you can checkout and submit translations? You use the -a parameter in git branch in order to show All available branches.

$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/gnome-2-10
  remotes/origin/gnome-2-12
  remotes/origin/gnome-2-14
  remotes/origin/gnome-2-16
  remotes/origin/gnome-2-18
  remotes/origin/gnome-2-20
  remotes/origin/gnome-2-22
  remotes/origin/gnome-2-26
  remotes/origin/gnome-2-28
  remotes/origin/gnome-2-30
  remotes/origin/gnome-2-32
  remotes/origin/gnome-2-4
  remotes/origin/gnome-2-6
  remotes/origin/gnome-2-8
  remotes/origin/master
$ _

Let's assume we want to commit a translation on the origin/gnome-2-32 branch. Normally would find the proper branch name from l10n.gnome.org, at the module page. We need to checkout that branch into our local repository. That branch name is traditionally of the type 'origin/gnome-VERSIONNUMBER'.

$ git checkout --track origin/gnome-2-32
Branch gnome-2-32 set up to track remote branch gnome-2-32 from origin.
Switched to a new branch 'gnome-2-32'
$ _

Now, we have checked out and switched to the gnome-2-32 branch. Let's verify,

$ git branch
* gnome-2-32
 master
$ _

At this stage, we can update our translation and commit it in our local repository. See the relevant section in this web page.

Finally, let's push the changes upstream.

$ git push
Counting objects: 6, done.
Delta compression using 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 337 bytes, done.
Total 4 (delta 2), reused 0 (delta 0)
To ssh://MYUSERNAME@git.gnome.org/git/zenity
  2bb284a..519c40c  gnome-2-32 -> gnome-2-32
$ _

Let's verify again which branch is active,

$ git branch
* zenity
 master
$ _

Let's switch back to master and keep the repository files for the next translation update.

$ git checkout master
Switched to branch "master"
$ git branch
 zenity
* master
$ _

If you aren't going to use the previous branch anymore you can delete it.

$ git checkout master
Switched to branch "master"
$ git branch
* master
  gnome-2-32
$ git branch -d gnome-2-32
Deleted branch gnome-2-32.
$ _

If git tells you that you can't delete the branch because it has some changes not upstreamed, just change the -d with -D.

View your changes online

We can view the pushed change at the CGIT web interface. If the project is zenity, visit http://git.gnome.org/browse/zenity From the list of branches, notice the one called master. This is what used to be called HEAD or trunk in SVN.

Commit to both branch and master

If you want to commit your changes to both a stable branch (such as gnome-2-32) and to master, you can use 'git cherry-pick' with the appropriate parameters. We used to advise here to use 'git merge', however that is not endorsed anymore.

First of all, make the change in the branch and commit it. Subsequently, checkout master and finally merge the changes from the branch. In detail,

# We assume you checked out the branch gnome-2-32 and you updated your LL.po, and you are about to commit the change as normal.
$ git commit -m "Updated Greek translation" el.po 
[gnome-2-32 4d7a0af] Updated Greek translation
 1 files changed, 3 insertions(+), 3 deletions(-)
$ git checkout master
Switched to branch "master"
$ git cherry-pick 4d7a0af
Finished one cherry-pick.
[master fdb65b4] Updated Greek translation
 1 files changed, 3 insertions(+), 3 deletions(-)
$ git push
Counting objects: 12, done.
Delta compression using 4 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 745 bytes, done.
Total 7 (delta 5), reused 0 (delta 0)
To ssh://MYUSERNAME@git.gnome.org/git/zenity/
   9861647..4d7a0af  gnome-2-32 -> gnome-2-32
   152258a..fdb65b4  master -> master
$ _

Note that when you commit your work, you get the unique hash of the change you did, 4d7a0af in our case, which you can then use with git cherry-pick in order to retrieve that commit from your repository (in the 'gnome-2-32' branch) and apply it in master.

Convert an anonymous clone into an eponymous one

So you managed to find an anonymous clone and you want to use it to commit your translations. Why would you end up with an anonymous clone? It is easier to get all the GNOME repositories as anonymous clones by DVD, FTP or Bittorrent, and then add your account details! Here is how you do it.

$ cd MODULENAME
$ git config remote.origin.url ssh://MYUSERNAME@git.gnome.org/git/MODULENAME
$ _

That's it! You can now update in order to verify that it works.

$ git up
...
$ _

Undo my last commit on my clone

If you want to undo your last commit on your clone, perhaps in order to be able to pull and update your clone, you can

$ git reset --hard HEAD^
HEAD is now at 8cbf74e Fixed bug #509192
$ _

HEAD^ corresponds to the last but one (previous) commit, so the above command removes altogether the last commit. When you remove commits, it is good to run git up so that you make sure your clone is properly in sync with git.gnome.org. You normally would undo the last commit if your clone has not been updated for a long time and there is problem with pushing your commit.

How do I revert (undo) a published commit?

Suppose you pushed a commit and you realise that it was a mistake. For example, you may have pushed a commit for the documentation in the place of a UI PO file. In this case, use

$ git log
commit f0788cc29124ac2bf3623c9624ea7c74d237ae4e
Author: Marios Zindilis <m.zindilis@dmajor.org>
Date:   Sat May 9 14:48:36 2009 +0100

    Updated Greek translation

...

in order to locate the hash of the published commit that you want to revert. In this case, it is f0788cc29124ac2bf3623c9624ea7c74d237ae4e. Then

$ git revert f0788cc29124ac2bf3623c9624ea7c74d237ae4e
<here you are prompted to type a comment for the reason of the revert; write your reason>
Finished one revert.
Created commit 6654584: Revert "Updated Greek translation"
 1 files changed, 1335 insertions(+), 3362 deletions(-)
 rewrite po/el.po (98%)
$ git push
Counting objects: 7, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 10.68 KiB, done.
Total 4 (delta 2), reused 1 (delta 0)
To ssh://simos@git.gnome.org/git/zenity
   29287a4..6654584  gnome-2-32 -> gnome-2-32
$ _

Finally, have a look at the revert log

$ git log
commit ea4333129ee092400697966c82143f2bfc5e5d96
Author: Simos Xenitellis <simos@gnome.org>
Date:   Sat May 9 14:54:07 2009 +0100

    Revert "Updated Greek translation"
    
    This reverts commit f0788cc29124ac2bf3623c9624ea7c74d237ae4e.
    I accidentaly committed the documentation on the UI PO file.
...

I messed up. Now?

If your local repository is messed up, you can try to reset any changes so that it matches what you have in git.gnome.org In this way, you can avoid cloning again.

$ git reset --hard
HEAD is now at f4e0fe0 Push this additional commit..
$ _

Any file that is already tracked (i.e. has been 'git add-ed') will change back to the tracked version. That is, any modifications you did and did not commit will disappear.

However, this does not mean that your local copy is the same with what is available upstream at the origin, git.gnome.org. You might either 1) made one or more commits in your local repository and therefore you are ahead of the origin, or 2) you might have removed one or more commits from your local repository and therefore you are behind the origin.

To figure out whether your repository is ahead of the origin, run git log origin..master. If you see any commit entries, then you are indeed ahead of the origin. You can take off those commits using the command git reset --hard HEAD^, which takes off one commit at a time.

To figure out whether your repository is behind the origin, run git log master..origin. If you see any commit entries, then you are indeed behind the origin (your local repository is missing some commits that are available at git.gnome.org). You can update your local repository using the command git up, which is the normal command described in this page to update your repository.

In either of the two cases above, it is important to run git up at the end to verify that your local repository is in sync with upstream.

If you report any problems with your local repository, show in your email that you have followed the steps above.

For the untracked files, you can view them with git status and erase manually, or more easily

$ git clean -n
Would remove el.po
$ git clean -f
Removing el.po
$ _

Tips n' Tricks

  • In the command git clone ssh://MYUSERNAME@git.gnome.org/git/PACKAGENAME PKGNAME, you can safely omit PKGNAME because git will put by default PACKAGENAME.

  • It is good to keep the cloned repositories for future use. When you want to use them again, remember to pull in order to update your local repository, with git up.

  • A small module should take under 20MB in space, while a bigger repository can be a few hundred MBs. For example, gtk+ is 175MB.
  • You can view the pushed changes at http://git.gnome.org/browse/PACKAGENAME under the master branch.

  • When you git clone, you create a full offline repository of a module. You can use the --depth 1 parameter to limit the history of your clone, however in most cases, this does not save significantly in terms of clone speed, or space savings.

  • When you clone with '--depth 1', you create a shallow clone; you omit the history, so you do not create a full local repository. git clone --help says that you cannot push your changes from your shallow clone. Reading the Git release notes, it mentions that pushing from a shallow clone is not expected to work which is slightly different. Practice shows that you are able to execute a push of the changes of your shallow clone. Considering however that there are no significant savings, it is better to take full clones for now. In addition, the part about is not expected to work might manifest in a repository mess in the future, so please do not use shallow clones unless we know better. This advice might still change in the future.

Troubleshooting

Error: refusing to pull with rebase: your working tree is not up-to-date

When you try to pull, you need to have your local changes at least committed locally. If not, then you cannot pull. If you would like to fix and you do not happen to need the changes, see section above "I messed up. Now?". Otherwise, commit the changes and run git pull --rebase.

XYZ: needs update, why all files need update?

When you try to perform git operations and you notice that files you did not modify are reported that they have been modified, then you should investigate for the source of the issue further. One case is when the file permissions of the files change (possibly when copying or moving to a different partition). Therefore, when you notice that files are modified while you did not actually modify them, please investigate further or contact the gnome-i18n mailing list. Do avoid filesystems where the native encoding is not UTF-8 (such as FAT and probably NTFS). You might be able to salvage your clones by moving them to a UTF-8 encoded filesystem (such as ext2, ext3, ext4 or others) and performing the steps described in this page in the section titled 'I messed up, Now?'.

TranslationProject/GitHowTo (last edited 2015-06-16 19:32:44 by AndersJonsson)