mirror of
https://github.com/git/git.git
synced 2024-11-28 04:23:30 +08:00
6cdccfce1e
Change the GETTEXT_POISON compile-time + runtime GIT_GETTEXT_POISON test parameter to only be a GIT_TEST_GETTEXT_POISON=<non-empty?> runtime parameter, to be consistent with other parameters documented in "Running tests with special setups" in t/README. When I added GETTEXT_POISON inbb946bba76
("i18n: add GETTEXT_POISON to simulate unfriendly translator", 2011-02-22) I was concerned with ensuring that the _() function would get constant folded if NO_GETTEXT was defined, and likewise that GETTEXT_POISON would be compiled out unless it was defined. But as the benchmark in my [1] shows doing a one-off runtime getenv("GIT_TEST_[...]") is trivial, and since GETTEXT_POISON was originally added the GIT_TEST_* env variables have become the common idiom for turning on special test setups. So change GETTEXT_POISON to work the same way. Now the GETTEXT_POISON=YesPlease compile-time option is gone, and running the tests with GIT_TEST_GETTEXT_POISON=[YesPlease|] can be toggled on/off without recompiling. This allows for conditionally amending tests to test with/without poison, similar to what859fdc0c3c
("commit-graph: define GIT_TEST_COMMIT_GRAPH", 2018-08-29) did for GIT_TEST_COMMIT_GRAPH. Do some of that, now we e.g. always run the t0205-gettext-poison.sh test. I did enough there to remove the GETTEXT_POISON prerequisite, but its inverse C_LOCALE_OUTPUT is still around, and surely some tests using it can be converted to e.g. always set GIT_TEST_GETTEXT_POISON=. Notes on the implementation: * We still compile a dedicated GETTEXT_POISON build in Travis CI. Perhaps this should be revisited and integrated into the "linux-gcc" build, seeae59a4e44f
("travis: run tests with GIT_TEST_SPLIT_INDEX", 2018-01-07) for prior art in that area. Then again maybe not, see [2]. * We now skip a test in t0000-basic.sh under GIT_TEST_GETTEXT_POISON=YesPlease that wasn't skipped before. This test relies on C locale output, but due to an edge case in how the previous implementation of GETTEXT_POISON worked (reading it from GIT-BUILD-OPTIONS) wasn't enabling poison correctly. Now it does, and needs to be skipped. * The getenv() function is not reentrant, so out of paranoia about code of the form: printf(_("%s"), getenv("some-env")); call use_gettext_poison() in our early setup in git_setup_gettext() so we populate the "poison_requested" variable in a codepath that's won't suffer from that race condition. * We error out in the Makefile if you're still saying GETTEXT_POISON=YesPlease to prompt users to change their invocation. * We should not print out poisoned messages during the test initialization itself to keep it more readable, so the test library hides the variable if set in $GIT_TEST_GETTEXT_POISON_ORIG during setup. See [3]. See also [4] for more on the motivation behind this patch, and the history of the GETTEXT_POISON facility. 1. https://public-inbox.org/git/871s8gd32p.fsf@evledraar.gmail.com/ 2. https://public-inbox.org/git/20181102163725.GY30222@szeder.dev/ 3. https://public-inbox.org/git/20181022202241.18629-2-szeder.dev@gmail.com/ 4. https://public-inbox.org/git/878t2pd6yu.fsf@evledraar.gmail.com/ Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
307 lines
10 KiB
Plaintext
307 lines
10 KiB
Plaintext
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 l10 coordinator repository:
|
|
|
|
https://github.com/git-l10n/git-po/
|
|
|
|
The two character language translation codes are defined by ISO_639-1, as
|
|
stated in the gettext(1) full manual, appendix A.1, Usual Language Codes.
|
|
|
|
|
|
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 | ---(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 occurred: \$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 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:
|
|
|
|
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 occurred: %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 tested with a translation mode that
|
|
emits gibberish on every call to gettext. To use it run the test suite
|
|
with it, e.g.:
|
|
|
|
cd t && GIT_TEST_GETTEXT_POISON=YesPlease 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.
|