-Localizing git-gui for your language
-====================================
-
-This short note is to help you, who reads and writes English and your
-own language, help us getting git-gui localized for more languages. It
-does not try to be a comprehensive manual of GNU gettext, which is the
-i18n framework we use, but tries to help you get started by covering the
-basics and how it is used in this project.
-
-1. Getting started.
-
-You would first need to have a working "git". Your distribution may
-have it as "git-core" package (do not get "GNU Interactive Tools" --
-that is a different "git"). You would also need GNU gettext toolchain
-to test the resulting translation out. Although you can work on message
-translation files with a regular text editor, it is a good idea to have
-specialized so-called "po file editors" (e.g. emacs po-mode, KBabel,
-poedit, GTranslator --- any of them would work well). Please install
-them.
-
-You would then need to clone the git-gui internationalization project
-repository, so that you can work on it:
-
- $ git clone mob@repo.or.cz:/srv/git/git-gui/git-gui-i18n.git/
- $ cd git-gui-i18n
- $ git checkout --track -b mob origin/mob
- $ git config remote.origin.push mob
-
-The "git checkout" command creates a 'mob' branch from upstream's
-corresponding branch and makes it your current branch. You will be
-working on this branch.
-
-The "git config" command records in your repository configuration file
-that you would push "mob" branch to the upstream when you say "git
-push".
-
-
-2. Starting a new language.
-
-In the git-gui-i18n directory is a po/ subdirectory. It has a
-handful files whose names end with ".po". Is there a file that has
-messages in your language?
-
-If you do not know what your language should be named, you need to find
-it. This currently follows ISO 639-1 two letter codes:
-
- http://www.loc.gov/standards/iso639-2/php/code_list.php
-
-For example, if you are preparing a translation for Afrikaans, the
-language code is "af". If there already is a translation for your
-language, you do not have to perform any step in this section, but keep
-reading, because we are covering the basics.
-
-If you did not find your language, you would need to start one yourself.
-Copy po/git-gui.pot file to po/af.po (replace "af" with the code for
-your language). Edit the first several lines to match existing *.po
-files to make it clear this is a translation table for git-gui project,
-and you are the primary translator. The result of your editing would
-look something like this:
-
- # Translation of git-gui to Afrikaans
- # Copyright (C) 2007 Shawn Pearce
- # This file is distributed under the same license as the git-gui package.
- # YOUR NAME <YOUR@E-MAIL.ADDRESS>, 2007.
- #
- #, fuzzy
- msgid ""
- msgstr ""
- "Project-Id-Version: git-gui\n"
- "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2007-07-24 22:19+0300\n"
- "PO-Revision-Date: 2007-07-25 18:00+0900\n"
- "Last-Translator: YOUR NAME <YOUR@E-MAIL.ADDRESS>\n"
- "Language-Team: Afrikaans\n"
- "MIME-Version: 1.0\n"
- "Content-Type: text/plain; charset=UTF-8\n"
- "Content-Transfer-Encoding: 8bit\n"
-
-You will find many pairs of a "msgid" line followed by a "msgstr" line.
-These pairs define how messages in git-gui application are translated to
-your language. Your primarily job is to fill in the empty double quote
-pairs on msgstr lines with the translation of the strings on their
-matching msgid lines. A few tips:
-
- - Control characters, such as newlines, are written in backslash
- sequence similar to string literals in the C programming language.
- When the string given on a msgid line has such a backslash sequence,
- you would typically want to have corresponding ones in the string on
- your msgstr line.
-
- - Some messages contain an optional context indicator at the end,
- for example "@@noun" or "@@verb". This indicator allows the
- software to select the correct translation depending upon the use.
- The indicator is not actually part of the message and will not
- be shown to the end-user.
-
- If your language does not require a different translation you
- will still need to translate both messages.
-
- - Often the messages being translated are format strings given to
- "printf()"-like functions. Make sure "%s", "%d", and "%%" in your
- translated messages match the original.
-
- When you have to change the order of words, you can add "<number>\$"
- between '%' and the conversion ('s', 'd', etc.) to say "<number>-th
- parameter to the format string is used at this point". For example,
- if the original message is like this:
-
- "Length is %d, Weight is %d"
-
- and if for whatever reason your translation needs to say weight first
- and then length, you can say something like:
-
- "WEIGHT IS %2\$d, LENGTH IS %1\$d"
-
- The reason you need a backslash before dollar sign is because
- this is a double quoted string in Tcl language, and without
- it the letter introduces a variable interpolation, which you
- do not want here.
-
- - A long message can be split across multiple lines by ending the
- string with a double quote, and starting another string on the next
- line with another double quote. They will be concatenated in the
- result. For example:
-
- #: lib/remote_branch_delete.tcl:189
- #, tcl-format
- msgid ""
- "One or more of the merge tests failed because you have not fetched the "
- "necessary commits. Try fetching from %s first."
- msgstr ""
- "HERE YOU WILL WRITE YOUR TRANSLATION OF THE ABOVE LONG "
- "MESSAGE IN YOUR LANGUAGE."
-
-You can test your translation by running "make install", which would
-create po/af.msg file and installs the result, and then running the
-resulting git-gui under your locale:
-
- $ make install
- $ LANG=af git-gui
-
-There is a trick to test your translation without first installing:
-
- $ make
- $ LANG=af ./git-gui.sh
-
-When you are satisfied with your translation, commit your changes, and
-push it back to the 'mob' branch:
-
- $ edit po/af.po
- ... be sure to update Last-Translator: and
- ... PO-Revision-Date: lines.
- $ git add po/af.po
- $ git commit -m 'Started Afrikaans translation.'
- $ git push
-
-
-3. Updating your translation.
-
-There may already be a translation for your language, and you may want
-to contribute an update. This may be because you would want to improve
-the translation of existing messages, or because the git-gui software
-itself was updated and there are new messages that need translation.
-
-In any case, make sure you are up-to-date before starting your work:
-
- $ git pull
-
-In the former case, you will edit po/af.po (again, replace "af" with
-your language code), and after testing and updating the Last-Translator:
-and PO-Revision-Date: lines, "add/commit/push" as in the previous
-section.
-
-By comparing "POT-Creation-Date:" line in po/git-gui.pot file and
-po/af.po file, you can tell if there are new messages that need to be
-translated. You would need the GNU gettext package to perform this
-step.
-
- $ msgmerge -U po/af.po po/git-gui.pot
-
-[NEEDSWORK: who is responsible for updating po/git-gui.pot file by
-running xgettext? IIRC, Christian recommended against running it
-nilly-willy because it can become a source of unnecessary merge
-conflicts. Perhaps we should mention something like "
-
-The po/git-gui.pot file is updated by the internationalization
-coordinator from time to time. You _could_ update it yourself, but
-translators are discouraged from doing so because we would want all
-language teams to be working off of the same version of git-gui.pot.
+Core GIT Translations
+=====================
-" here?]
+This directory holds the translations for the core of Git. This document
+describes how you can contribute to the effort of enhancing the language
+coverage and maintaining the translation.
-This updates po/af.po (again, replace "af" with your language
-code) so that it contains msgid lines (i.e. the original) that
-your translation did not have before. There are a few things to
-watch out for:
+The localization (l10n) coordinator, Jiang Xin <worldhello.net@gmail.com>,
+coordinates our localization effort in the l10 coordinator repository:
- - The original text in English of an older message you already
- translated might have been changed. You will notice a comment line
- that begins with "#, fuzzy" in front of such a message. msgmerge
- tool made its best effort to match your old translation with the
- message from the updated software, but you may find cases that it
- matched your old translated message to a new msgid and the pairing
- does not make any sense -- you would need to fix them, and then
- remove the "#, fuzzy" line from the message (your fixed translation
- of the message will not be used before you remove the marker).
+ https://github.com/git-l10n/git-po/
- - New messages added to the software will have msgstr lines with empty
- strings. You would need to translate them.
+As a contributor for a language XX, you should first check TEAMS file in
+this directory to see whether a dedicated repository for your language XX
+exists. Fork the dedicated repository and start to work if it exists.
+
+If you are the first contributor for the language XX, please fork this
+repository, prepare and/or update the translated message file po/XX.po
+(described later), and ask the l10n coordinator to pull your work.
+
+If there are multiple contributors for the same language, please first
+coordinate among yourselves and nominate the team leader for your
+language, so that the l10n coordinator only needs to interact with one
+person per language.
+
+The overall data-flow looks like this:
+
+ +-------------------+ +------------------+
+ | Git source code | ---(1)---> | L10n coordinator |
+ | repository | <---(4)--- | repository |
+ +-------------------+ +------------------+
+ | ^
+ (2) (3)
+ V |
+ +------------------+
+ | Language Team XX |
+ +------------------+
+
+ * Translatable strings are marked in the source file.
+ * L10n coordinator pulls from the source (1)
+ * L10n coordinator updates the message template po/git.pot
+ * Language team pulls from L10n coordinator (2)
+ * Language team updates the message file po/XX.po
+ * L10n coordinator pulls from Language team (3)
+ * L10n coordinator asks the result to be pulled (4).
+
+
+Maintaining the po/git.pot file
+-------------------------------
+
+(This is done by the l10n coordinator).
+
+The po/git.pot file contains a message catalog extracted from Git's
+sources. The l10n coordinator maintains it by adding new translations with
+msginit(1), or update existing ones with msgmerge(1). In order to update
+the Git sources to extract the messages from, the l10n coordinator is
+expected to pull from the main git repository at strategic point in
+history (e.g. when a major release and release candidates are tagged),
+and then run "make pot" at the top-level directory.
+
+Language contributors use this file to prepare translations for their
+language, but they are not expected to modify it.
+
+
+Initializing a XX.po file
+-------------------------
+
+(This is done by the language teams).
+
+If your language XX does not have translated message file po/XX.po yet,
+you add a translation for the first time by running:
+
+ msginit --locale=XX
+
+in the po/ directory, where XX is the locale, e.g. "de", "is", "pt_BR",
+"zh_CN", etc.
+
+Then edit the automatically generated copyright info in your new XX.po
+to be correct, e.g. for Icelandic:
+
+ @@ -1,6 +1,6 @@
+ -# Icelandic translations for PACKAGE package.
+ -# Copyright (C) 2010 THE PACKAGE'S COPYRIGHT HOLDER
+ -# This file is distributed under the same license as the PACKAGE package.
+ +# Icelandic translations for Git.
+ +# Copyright (C) 2010 Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ +# This file is distributed under the same license as the Git package.
+ # Ævar Arnfjörð Bjarmason <avarab@gmail.com>, 2010.
+
+And change references to PACKAGE VERSION in the PO Header Entry to
+just "Git":
+
+ perl -pi -e 's/(?<="Project-Id-Version: )PACKAGE VERSION/Git/' XX.po
+
+Once you are done testing the translation (see below), commit the result
+and ask the l10n coordinator to pull from you.
+
+
+Updating a XX.po file
+---------------------
+
+(This is done by the language teams).
+
+If you are replacing translation strings in an existing XX.po file to
+improve the translation, just edit the file.
+
+If there's an existing XX.po file for your language, but the repository
+of the l10n coordinator has newer po/git.pot file, you would need to first
+pull from the l10n coordinator (see the beginning of this document for its
+URL), and then update the existing translation by running:
+
+ msgmerge --add-location --backup=off -U XX.po git.pot
+
+in the po/ directory, where XX.po is the file you want to update.
+
+Once you are done testing the translation (see below), commit the result
+and ask the l10n coordinator to pull from you.
+
+
+Testing your changes
+--------------------
+
+(This is done by the language teams, after creating or updating XX.po file).
+
+Before you submit your changes go back to the top-level and do:
+
+ make
+
+On systems with GNU gettext (i.e. not Solaris) this will compile your
+changed PO file with `msgfmt --check`, the --check option flags many
+common errors, e.g. missing printf format strings, or translated
+messages that deviate from the originals in whether they begin/end
+with a newline or not.
+
+
+Marking strings for translation
+-------------------------------
+
+(This is done by the core developers).
+
+Before strings can be translated they first have to be marked for
+translation.
+
+Git uses an internationalization interface that wraps the system's
+gettext library, so most of the advice in your gettext documentation
+(on GNU systems `info gettext` in a terminal) applies.
+
+General advice:
+
+ - Don't mark everything for translation, only strings which will be
+ read by humans (the porcelain interface) should be translated.
+
+ The output from Git's plumbing utilities will primarily be read by
+ programs and would break scripts under non-C locales if it was
+ translated. Plumbing strings should not be translated, since
+ they're part of Git's API.
+
+ - Adjust the strings so that they're easy to translate. Most of the
+ advice in `info '(gettext)Preparing Strings'` applies here.
+
+ - If something is unclear or ambiguous you can use a "TRANSLATORS"
+ comment to tell the translators what to make of it. These will be
+ extracted by xgettext(1) and put in the po/*.po files, e.g. from
+ git-am.sh:
+
+ # TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
+ # in your translation. The program will only accept English
+ # input at this point.
+ gettext "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
+
+ Or in C, from builtin/revert.c:
+
+ /* TRANSLATORS: %s will be "revert" or "cherry-pick" */
+ die(_("%s: Unable to write new index file"), action_name(opts));
+
+We provide wrappers for C, Shell and Perl programs. Here's how they're
+used:
+
+C:
+
+ - Include builtin.h at the top, it'll pull in gettext.h, which
+ defines the gettext interface. Consult with the list if you need to
+ use gettext.h directly.
+
+ - The C interface is a subset of the normal GNU gettext
+ interface. We currently export these functions:
+
+ - _()
+
+ Mark and translate a string. E.g.:
+
+ printf(_("HEAD is now at %s"), hex);
+
+ - Q_()
+
+ Mark and translate a plural string. E.g.:
+
+ printf(Q_("%d commit", "%d commits", number_of_commits));
+
+ This is just a wrapper for the ngettext() function.
+
+ - N_()
+
+ A no-op pass-through macro for marking strings inside static
+ initializations, e.g.:
+
+ static const char *reset_type_names[] = {
+ N_("mixed"), N_("soft"), N_("hard"), N_("merge"), N_("keep"), NULL
+ };
+
+ And then, later:
+
+ die(_("%s reset is not allowed in a bare repository"),
+ _(reset_type_names[reset_type]));
+
+ Here _() couldn't have statically determined what the translation
+ string will be, but since it was already marked for translation
+ with N_() the look-up in the message catalog will succeed.
+
+Shell:
+
+ - The Git gettext shell interface is just a wrapper for
+ gettext.sh. Import it right after git-sh-setup like this:
+
+ . git-sh-setup
+ . git-sh-i18n
+
+ And then use the gettext or eval_gettext functions:
+
+ # For constant interface messages:
+ gettext "A message for the user"; echo
+
+ # To interpolate variables:
+ details="oh noes"
+ eval_gettext "An error occured: \$details"; echo
+
+ In addition we have wrappers for messages that end with a trailing
+ newline. I.e. you could write the above as:
+
+ # For constant interface messages:
+ gettextln "A message for the user"
+
+ # To interpolate variables:
+ details="oh noes"
+ eval_gettextln "An error occured: \$details"
+
+ More documentation about the interface is available in the GNU info
+ page: `info '(gettext)sh'`. Looking at git-am.sh (the first shell
+ command to be translated) for examples is also useful:
+
+ git log --reverse -p --grep=i18n git-am.sh
+
+Perl:
+
+ - The Git::I18N module provides a limited subset of the
+ Locale::Messages functionality, e.g.:
+
+ use Git::I18N;
+ print __("Welcome to Git!\n");
+ printf __("The following error occured: %s\n"), $error;
+
+ Run `perldoc perl/Git/I18N.pm` for more info.
+
+
+Testing marked strings
+----------------------
+
+Even if you've correctly marked porcelain strings for translation
+something in the test suite might still depend on the US English
+version of the strings, e.g. to grep some error message or other
+output.
+
+To smoke out issues like these Git can be compiled with gettext poison
+support, at the top-level:
+
+ make GETTEXT_POISON=YesPlease
+
+That'll give you a git which emits gibberish on every call to
+gettext. It's obviously not meant to be installed, but you should run
+the test suite with it:
+
+ cd t && prove -j 9 ./t[0-9]*.sh
+
+If tests break with it you should inspect them manually and see if
+what you're translating is sane, i.e. that you're not translating
+plumbing output.
+
+If not you should replace calls to grep with test_i18ngrep, or
+test_cmp calls with test_i18ncmp. If that's not enough you can skip
+the whole test by making it depend on the C_LOCALE_OUTPUT
+prerequisite. See existing test files with this prerequisite for
+examples.