diff options
Diffstat (limited to 'po/README.md')
-rw-r--r-- | po/README.md | 460 |
1 files changed, 460 insertions, 0 deletions
diff --git a/po/README.md b/po/README.md new file mode 100644 index 0000000..3e4f897 --- /dev/null +++ b/po/README.md @@ -0,0 +1,460 @@ +# Core GIT Translations + +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. + +The localization (l10n) coordinator, Jiang Xin <worldhello.net@gmail.com>, +coordinates our localization effort in the l10n coordinator repository: + + https://github.com/git-l10n/git-po/ + +We will use XX as an alias to refer to the language translation code in +the following paragraphs, for example we use "po/XX.po" to refer to the +translation file for a specific language. But this doesn't mean that +the language code has only two letters. The language code can be in one +of two forms: "ll" or "ll\_CC". Here "ll" is the ISO 639 two-letter +language code and "CC" is the ISO 3166 two-letter code for country names +and subdivisions. For example: "de" for German language code, "zh\_CN" +for Simplified Chinese language code. + + +## Contributing to an existing translation + +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. + +Sometime, contributors may find that the translations of their Git +distributions are quite different with the translations of the +corresponding version from Git official. This is because some Git +distributions (such as from Ubuntu, etc.) have their own l10n workflow. +For this case, wrong translations should be reported and fixed through +their workflows. + + +## Creating a new language translation + +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. + + +## Translation Process Flow + +The overall data-flow looks like this: + + +-------------------+ +------------------+ + | Git source code | ----(2)---> | L10n coordinator | + | repository | <---(5)---- | repository | + +-------------------+ +------------------+ + | | ^ + (1) (3) (4) + V v | + +----------------------------------+ + | Language Team XX | + +----------------------------------+ + +- Translatable strings are marked in the source file. +- Language teams can start translation iterations at any time, even + before the l10n window opens: + + + Pull from the master branch of the source (1) + + Update the message file by running "make po-update PO\_FILE=po/XX.po" + + Translate the message file "po/XX.po" + +- The L10n coordinator pulls from source and announces the l10n window + open (2) +- Language team pulls from the l10n coordinator, starts another + translation iteration against the l10n coordinator's tree (3) + + + Run "git pull --rebase" from the l10n coordinator + + Update the message file by running "make po-update PO\_FILE=po/XX.po" + + Translate the message file "po/XX.po" + + Squash trivial l10n git commits using "git rebase -i" + +- Language team sends pull request to the l10n coordinator (4) +- L10n coordinator checks and merges +- L10n coordinator asks the result to be pulled (5). + + +## Dynamically generated POT files + +POT files are templates for l10n contributors to create or update their +translation files. We used to have the "po/git.pot" file which was +generated by the l10n coordinator, but this file had been removed from +the tree. + +The two POT files "po/git.pot" and "po/git-core.pot" can be created +dynamically when necessary. + +L10n contributors use "po/git.pot" to prepare translations for their +languages, but they are not expected to modify it. The "po/git.pot" file +can be generated manually with the following command: + +```shell +make po/git.pot +``` + +The "po/git-core.pot" file is the template for core translations. A core +translation is the minimum set of work necessary to complete a +translation of a new language. Since there are more than 5000 messages +in the full set of template message file "po/git.pot" that need to be +translated, this is not a piece of cake for new language contributors. + +The "core" template file "po/git-core.pot" can be generated manually +by running: + +```shell +make po/git-core.pot +``` + + +## 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: + +```shell +make po-init PO_FILE=po/XX.po +``` + +where XX is the locale, e.g. "de", "is", "pt\_BR", "zh\_CN", etc. + +The newly generated message file "po/XX.po" is based on the core pot +file "po/git-core.pot", so it contains only a minimal set of messages +and it's a good start for a new language contribution. + +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 you want to find new translatable strings in source files of upstream +repository and propagate them to your "po/XX.po", run command: + +```shell +make po-update PO_FILE=po/XX.po +``` + +It will: + +- Call "make po/git.pot" to generate new "po/git.pot" file +- Call "msgmerge --add-location --backup=off -U po/XX.po po/git.pot" + to update your "po/XX.po" +- The "--add-location" option for msgmerge will add location lines, + and these location lines will help translation tools to locate + translation context easily. + +Once you are done testing the translation (see below), it's better +to commit a location-less "po/XX.po" file to save repository space +and make a user-friendly patch for review. + +To save a location-less "po/XX.po" automatically in repository, you +can: + +First define a new attribute for "po/XX.po" by appending the following +line in ".git/info/attributes": + +``` +/po/XX.po filter=gettext-no-location +``` + +Then define the driver for the "gettext-no-location" clean filter to +strip out both filenames and locations from the contents as follows: + +```shell +git config --global filter.gettext-no-location.clean \ + "msgcat --no-location -" +``` + +For users who have gettext version 0.20 or higher, it is also possible +to define a clean filter to preserve filenames but not locations: + +```shell +git config --global filter.gettext-no-location.clean \ + "msgcat --add-location=file -" +``` + +You're now ready to ask the l10n coordinator to pull from you. + + +## Fuzzy translation + +Fuzzy translation is a translation marked by comment "fuzzy" to let you +know that the translation is out of date because the "msgid" has been +changed. A fuzzy translation will be ignored when compiling using "msgfmt". +Fuzzy translation can be marked by hands, but for most cases they are +marked automatically when running "msgmerge" to update your "XX.po" file. + +After fixing the corresponding translation, you must remove the "fuzzy" +tag in the comment. + + +## 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: + +```shell +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. + +L10n coordinator will check your contributions using a helper program +(see "PO helper" section below): + +```shell +git-po-helper check-po po/XX.po +git-po-helper check-commits <rev-list-opts> +``` + + +## 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. + +- Strings referencing numbers of items may need to be split into singular and + plural forms; see the Q\_() wrapper in the C sub-section below for an + example. + +- 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: + + ```shell + # 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: + + ```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.: + + ```c + printf(_("HEAD is now at %s"), hex); + ``` + +- Q\_() + + Mark and translate a plural string. E.g.: + + ```c + 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.: + + ```c + static const char *reset_type_names[] = { + N_("mixed"), N_("soft"), N_("hard"), N_("merge"), N_("keep"), NULL + }; + ``` + + And then, later: + + ```c + 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: + +```shell +. git-sh-setup +. git-sh-i18n +``` + +And then use the `gettext` or `eval_gettext` functions: + +```shell +# For constant interface messages: +gettext "A message for the user"; echo + +# To interpolate variables: +details="oh noes" +eval_gettext "An error occurred: \$details"; echo +``` + +In addition we have wrappers for messages that end with a trailing +newline. I.e. you could write the above as: + +```shell +# For constant interface messages: +gettextln "A message for the user" + +# To interpolate variables: +details="oh noes" +eval_gettextln "An error occurred: \$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: + +```shell +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.: + +```perl +use Git::I18N; +print __("Welcome to Git!\n"); +printf __("The following error occurred: %s\n"), $error; +``` + +Run `perldoc perl/Git/I18N.pm` for more info. + + +## Testing marked strings + +Git's tests are run under `LANG=C LC_ALL=C`. So the tests do not need be +changed to account for translations as they're added. + + +## PO helper + +To make the maintenance of "XX.po" easier, the l10n coordinator and l10n +team leaders can use a helper program named "git-po-helper". It is a +wrapper to gettext suite, specifically written for the purpose of Git +l10n workflow. + +To build and install the helper program from source, see +[git-po-helper/README][]. + + +## Conventions + +There are some conventions that l10n contributors must follow: + +- The subject of each l10n commit should be prefixed with "l10n: ". + +- Do not use non-ASCII characters in the subject of a commit. + +- The length of commit subject (first line of the commit log) should + be less than 50 characters, and the length of other lines of the + commit log should be no more than 72 characters. + +- Add "Signed-off-by" trailer to your commit log, like other commits + in Git. You can automatically add the trailer by committing with + the following command: + + ```shell + git commit -s + ``` + +- Check syntax with "msgfmt" or the following command before creating + your commit: + + ```shell + git-po-helper check-po <XX.po> + ``` + +- Squash trivial commits to make history clear. + +- DO NOT edit files outside "po/" directory. + +- Other subsystems ("git-gui", "gitk", and Git itself) have their + own workflow. See [Documentation/SubmittingPatches][] for + instructions on how to contribute patches to these subsystems. + + +To contribute for a new l10n language, contributor should follow +additional conventions: + +- Initialize proper filename of the "XX.po" file conforming to + iso-639 and iso-3166. + +- Must complete a minimal translation based on the "Core + translation". See that section above. + +- Add a new entry in the "po/TEAMS" file with proper format, and check + the syntax of "po/TEAMS" by running the following command: + + ```shell + git-po-helper team --check + ``` + + +[git-po-helper/README]: https://github.com/git-l10n/git-po-helper#readme +[Documentation/SubmittingPatches]: Documentation/SubmittingPatches |