Code

gettext: add infrastructure for translating Git with gettext
authorÆvar Arnfjörð Bjarmason <avarab@gmail.com>
Sat, 10 Jul 2010 20:47:47 +0000 (20:47 +0000)
committerÆvar Arnfjörð Bjarmason <avarab@gmail.com>
Sat, 30 Oct 2010 07:10:04 +0000 (07:10 +0000)
commit0def2e1ce62e316b57434184280edb8a129c18f5
treec8f2d1cf88b6ed643296aec27406388d6ea69e03
parentb002c656fa5221b999ca7b01c946b738644e9739
gettext: add infrastructure for translating Git with gettext

All of the interface messages in Git core are currently hardcoded in
English. Change that by optionally enabling translation of the core C,
Shell and Perl programs via GNU or Solaris gettext. If you set the
appropriate LC_* variables Git will speak your language, provided that
someone has submitted a translation.

If gettext isn't available, or if Git is compiled with
NO_GETTEXT=YesPlease, then Git fall back on its previous behavior of
only speaking English. When using ./configure the autoconf script will
auto-detect if the gettext libraries are installed and act
appropriately.

With NO_GETTEXT=YesPlease gettext support will be #defined away for C
programs. For Shell and Perl programs we rely on the git message
catalog not being available. That's a reasonable assumption since then
the message catalog won't be installed on the system during make
install.

The gettext wrappers that are provided in the patch are only the bare
minimum required to begin translation work. In particular I haven't
added wrappers for the gettext functions that enable plural support,
or those that provide message context (msgctxt).

Those can be added later. The intent is to start with a small subset
and see what we need later, not to start with something that's
unnecessarily large right away.

Implementation and usage notes:

 * General:

   Gettext .mo files will be installed and looked for in the standard
   $(prefix)/share/locale path. GIT_TEXTDOMAINDIR can also be set to
   override that, but that's only intended to be used to test Git
   itself.

 * Perl:

   Perl code that wants to be localized should use the new Git::I18n
   module. It imports a __ function into the caller's package by
   default.

   Instead of using the high level Locale::TextDomain interface I've
   opted to use the low-level (equivalent to the C interface)
   Locale::Messages module, which Locale::TextDomain itself uses.

   Locale::TextDomain does a lot of redundant work we don't need, and
   some of it would potentially introduce bugs. It tries to set the
   $TEXTDOMAIN based on package of the caller, and has its own
   hardcoded paths where it'll search for messages.

   I found it easier just to completely avoid it rather than try to
   circumvent its behavior. In any case, this is an issue wholly
   internal Git::I18N. Its guts can be changed later if that's deemed
   necessary.

   See <AANLkTilYD_NyIZMyj9dHtVk-ylVBfvyxpCC7982LWnVd@mail.gmail.com>
   for a further elaboration on this topic.

 * Shell:

   Shell code that's to be localized should use the new git-sh-i18n
   library. It's just a wrapper for the system's gettext.sh.

   If gettext.sh isn't available we'll fall back gettext(1) if it's
   available. The latter is available without the former on Solaris,
   which has its own non-GNU gettext implementation. We also need to
   emulate eval_gettext() there.

   If neither are present we'll use a dumb printf(1) fall-through
   wrapper.

   I originally tried to detect if the system supported `echo -n' but
   I found this to be a waste of time. My benchmarks on Linux, Solaris
   and FreeBSD reveal that printf(1) is fast enough, especially since
   we aren't calling gettext() from within any tight loops, and
   unlikely to ever do so.

Solaris has its own non-GNU gettext implementation which this patch
supports, although that may change in the future if it turns out that
we need some GNU libintl features that SunOS doesn't provide.

This patch is based on work by Jeff Epler <jepler@unpythonic.net> who
did the initial Makefile / C work, and a lot of comments from the Git
mailing list, including Jonathan Nieder, Jakub Narebski, Johannes
Sixt, Peter Krefting, Junio C Hamano, Thomas Rast and others.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
32 files changed:
.gitignore
INSTALL
Makefile
config.mak.in
configure.ac
daemon.c
fast-import.c
gettext.c [new file with mode: 0644]
gettext.h [new file with mode: 0644]
git-sh-i18n.sh [new file with mode: 0644]
git.c
http-backend.c
http-fetch.c
http-push.c
imap-send.c
perl/Git/I18N.pm [new file with mode: 0644]
perl/Makefile
perl/Makefile.PL
po/.gitignore [new file with mode: 0644]
po/is.po [new file with mode: 0644]
shell.c
show-index.c
t/lib-gettext.sh [new file with mode: 0644]
t/t0200-gettext.sh [new file with mode: 0755]
t/t0200/test.c [new file with mode: 0644]
t/t0200/test.perl [new file with mode: 0644]
t/t0200/test.sh [new file with mode: 0644]
t/t0201-gettext-fallbacks.sh [new file with mode: 0755]
t/t0202-gettext-perl.sh [new file with mode: 0755]
t/t0202/test.pl [new file with mode: 0644]
t/test-lib.sh
upload-pack.c