Skip to content

Commit 2dccad3

Browse files
committed
Merge branch 'ab/enable-i18n'
* ab/enable-i18n: i18n: add infrastructure for translating Git with gettext Conflicts: Makefile
2 parents 85878dd + 5e9637c commit 2dccad3

37 files changed

+1291
-39
lines changed

Documentation/CodingGuidelines

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ For shell scripts specifically (not exhaustive):
8181
are ERE elements not BRE (note that \? and \+ are not even part
8282
of BRE -- making them accessible from BRE is a GNU extension).
8383

84+
- Use Git's gettext wrappers in git-sh-i18n to make the user
85+
interface translatable. See "Marking strings for translation" in
86+
po/README.
87+
8488
For C programs:
8589

8690
- We use tabs to indent, and interpret tabs as taking up to
@@ -144,6 +148,9 @@ For C programs:
144148
- When we pass <string, length> pair to functions, we should try to
145149
pass them in that order.
146150

151+
- Use Git's gettext wrappers to make the user interface
152+
translatable. See "Marking strings for translation" in po/README.
153+
147154
Writing Documentation:
148155

149156
Every user-visible change should be reflected in the documentation.

INSTALL

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,18 @@ Issues of note:
106106
history graphically, and in git-gui. If you don't want gitk or
107107
git-gui, you can use NO_TCLTK.
108108

109+
- A gettext library is used by default for localizing Git. The
110+
primary target is GNU libintl, but the Solaris gettext
111+
implementation also works.
112+
113+
We need a gettext.h on the system for C code, gettext.sh (or
114+
Solaris gettext(1)) for shell scripts, and libintl-perl for Perl
115+
programs.
116+
117+
Set NO_GETTEXT to disable localization support and make Git only
118+
use English. Under autoconf the configure script will do this
119+
automatically if it can't find libintl on the system.
120+
109121
- Some platform specific issues are dealt with Makefile rules,
110122
but depending on your specific installation, you may not
111123
have all the libraries/tools needed, or you may have

Makefile

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ all::
4343
# Define EXPATDIR=/foo/bar if your expat header and library files are in
4444
# /foo/bar/include and /foo/bar/lib directories.
4545
#
46+
# Define NO_GETTEXT if you don't want Git output to be translated.
47+
# A translated Git requires GNU libintl or another gettext implementation,
48+
# plus libintl-perl at runtime.
49+
#
50+
# Define HAVE_LIBCHARSET_H if you haven't set NO_GETTEXT and you can't
51+
# trust the langinfo.h's nl_langinfo(CODESET) function to return the
52+
# current character set. GNU and Solaris have a nl_langinfo(CODESET),
53+
# FreeBSD can use either, but MinGW and some others need to use
54+
# libcharset.h's locale_charset() instead.
55+
#
56+
# Define LIBC_CONTAINS_LIBINTL if your gettext implementation doesn't
57+
# need -lintl when linking.
58+
#
59+
# Define NO_MSGFMT_EXTENDED_OPTIONS if your implementation of msgfmt
60+
# doesn't support GNU extensions like --check and --statistics
61+
#
4662
# Define HAVE_PATHS_H if you have paths.h and want to use the default PATH
4763
# it specifies.
4864
#
@@ -309,6 +325,7 @@ gitexecdir = libexec/git-core
309325
mergetoolsdir = $(gitexecdir)/mergetools
310326
sharedir = $(prefix)/share
311327
gitwebdir = $(sharedir)/gitweb
328+
localedir = $(sharedir)/locale
312329
template_dir = share/git-core/templates
313330
htmldir = share/doc/git-doc
314331
ETC_GITCONFIG = $(sysconfdir)/gitconfig
@@ -317,7 +334,7 @@ lib = lib
317334
# DESTDIR=
318335
pathsep = :
319336

320-
export prefix bindir sharedir sysconfdir gitwebdir
337+
export prefix bindir sharedir sysconfdir gitwebdir localedir
321338

322339
CC = gcc
323340
AR = ar
@@ -330,6 +347,7 @@ RPMBUILD = rpmbuild
330347
TCL_PATH = tclsh
331348
TCLTK_PATH = wish
332349
XGETTEXT = xgettext
350+
MSGFMT = msgfmt
333351
PTHREAD_LIBS = -lpthread
334352
PTHREAD_CFLAGS =
335353
GCOV = gcov
@@ -640,6 +658,7 @@ LIB_OBJS += environment.o
640658
LIB_OBJS += exec_cmd.o
641659
LIB_OBJS += fsck.o
642660
LIB_OBJS += gpg-interface.o
661+
LIB_OBJS += gettext.o
643662
LIB_OBJS += graph.o
644663
LIB_OBJS += grep.o
645664
LIB_OBJS += hash.o
@@ -836,12 +855,14 @@ ifeq ($(uname_S),Linux)
836855
NO_STRLCPY = YesPlease
837856
NO_MKSTEMPS = YesPlease
838857
HAVE_PATHS_H = YesPlease
858+
LIBC_CONTAINS_LIBINTL = YesPlease
839859
endif
840860
ifeq ($(uname_S),GNU/kFreeBSD)
841861
NO_STRLCPY = YesPlease
842862
NO_MKSTEMPS = YesPlease
843863
HAVE_PATHS_H = YesPlease
844864
DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease
865+
LIBC_CONTAINS_LIBINTL = YesPlease
845866
endif
846867
ifeq ($(uname_S),UnixWare)
847868
CC = cc
@@ -908,6 +929,7 @@ ifeq ($(uname_S),SunOS)
908929
NO_MKSTEMPS = YesPlease
909930
NO_REGEX = YesPlease
910931
NO_FNMATCH_CASEFOLD = YesPlease
932+
NO_MSGFMT_EXTENDED_OPTIONS = YesPlease
911933
ifeq ($(uname_R),5.6)
912934
SOCKLEN_T = int
913935
NO_HSTRERROR = YesPlease
@@ -1031,6 +1053,7 @@ ifeq ($(uname_S),GNU)
10311053
NO_STRLCPY=YesPlease
10321054
NO_MKSTEMPS = YesPlease
10331055
HAVE_PATHS_H = YesPlease
1056+
LIBC_CONTAINS_LIBINTL = YesPlease
10341057
endif
10351058
ifeq ($(uname_S),IRIX)
10361059
NO_SETENV = YesPlease
@@ -1249,6 +1272,7 @@ ifneq (,$(wildcard ../THIS_IS_MSYSGIT))
12491272
EXTLIBS += /mingw/lib/libz.a
12501273
NO_R_TO_GCC_LINKER = YesPlease
12511274
INTERNAL_QSORT = YesPlease
1275+
HAVE_LIBCHARSET_H = YesPlease
12521276
else
12531277
NO_CURL = YesPlease
12541278
endif
@@ -1437,6 +1461,11 @@ endif
14371461
ifdef NEEDS_LIBGEN
14381462
EXTLIBS += -lgen
14391463
endif
1464+
ifndef NO_GETTEXT
1465+
ifndef LIBC_CONTAINS_LIBINTL
1466+
EXTLIBS += -lintl
1467+
endif
1468+
endif
14401469
ifdef NEEDS_SOCKET
14411470
EXTLIBS += -lsocket
14421471
endif
@@ -1479,9 +1508,11 @@ ifdef NO_SYMLINK_HEAD
14791508
BASIC_CFLAGS += -DNO_SYMLINK_HEAD
14801509
endif
14811510
ifdef GETTEXT_POISON
1482-
LIB_OBJS += gettext.o
14831511
BASIC_CFLAGS += -DGETTEXT_POISON
14841512
endif
1513+
ifdef NO_GETTEXT
1514+
BASIC_CFLAGS += -DNO_GETTEXT
1515+
endif
14851516
ifdef NO_STRCASESTR
14861517
COMPAT_CFLAGS += -DNO_STRCASESTR
14871518
COMPAT_OBJS += compat/strcasestr.o
@@ -1650,6 +1681,10 @@ ifdef HAVE_PATHS_H
16501681
BASIC_CFLAGS += -DHAVE_PATHS_H
16511682
endif
16521683

1684+
ifdef HAVE_LIBCHARSET_H
1685+
BASIC_CFLAGS += -DHAVE_LIBCHARSET_H
1686+
endif
1687+
16531688
ifdef DIR_HAS_BSD_GROUP_SEMANTICS
16541689
COMPAT_CFLAGS += -DDIR_HAS_BSD_GROUP_SEMANTICS
16551690
endif
@@ -1670,6 +1705,10 @@ ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT
16701705
export GIT_TEST_CMP_USE_COPIED_CONTEXT
16711706
endif
16721707

1708+
ifndef NO_MSGFMT_EXTENDED_OPTIONS
1709+
MSGFMT += --check --statistics
1710+
endif
1711+
16731712
ifeq ($(TCLTK_PATH),)
16741713
NO_TCLTK=NoThanks
16751714
endif
@@ -1700,6 +1739,7 @@ ifndef V
17001739
QUIET_GEN = @echo ' ' GEN $@;
17011740
QUIET_LNCP = @echo ' ' LN/CP $@;
17021741
QUIET_XGETTEXT = @echo ' ' XGETTEXT $@;
1742+
QUIET_MSGFMT = @echo ' ' MSGFMT $@;
17031743
QUIET_GCOV = @echo ' ' GCOV $@;
17041744
QUIET_SP = @echo ' ' SP $<;
17051745
QUIET_SUBDIR0 = +@subdir=
@@ -1726,6 +1766,7 @@ bindir_SQ = $(subst ','\'',$(bindir))
17261766
bindir_relative_SQ = $(subst ','\'',$(bindir_relative))
17271767
mandir_SQ = $(subst ','\'',$(mandir))
17281768
infodir_SQ = $(subst ','\'',$(infodir))
1769+
localedir_SQ = $(subst ','\'',$(localedir))
17291770
gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
17301771
template_dir_SQ = $(subst ','\'',$(template_dir))
17311772
htmldir_SQ = $(subst ','\'',$(htmldir))
@@ -1781,7 +1822,7 @@ ifndef NO_TCLTK
17811822
$(QUIET_SUBDIR0)gitk-git $(QUIET_SUBDIR1) all
17821823
endif
17831824
ifndef NO_PERL
1784-
$(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' all
1825+
$(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' localedir='$(localedir_SQ)' all
17851826
endif
17861827
ifndef NO_PYTHON
17871828
$(QUIET_SUBDIR0)git_remote_helpers $(QUIET_SUBDIR1) PYTHON_PATH='$(PYTHON_PATH_SQ)' prefix='$(prefix_SQ)' all
@@ -1831,6 +1872,7 @@ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
18311872
-e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \
18321873
-e 's|@@DIFF@@|$(DIFF_SQ)|' \
18331874
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
1875+
-e 's|@@LOCALEDIR@@|$(localedir_SQ)|g' \
18341876
-e 's/@@NO_CURL@@/$(NO_CURL)/g' \
18351877
-e $(BROKEN_PATH_FIX) \
18361878
@@ -2083,6 +2125,9 @@ config.sp config.s config.o: EXTRA_CPPFLAGS = \
20832125
attr.sp attr.s attr.o: EXTRA_CPPFLAGS = \
20842126
-DETC_GITATTRIBUTES='"$(ETC_GITATTRIBUTES_SQ)"'
20852127

2128+
gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \
2129+
-DGIT_LOCALE_PATH='"$(localedir_SQ)"'
2130+
20862131
http.sp http.s http.o: EXTRA_CPPFLAGS = \
20872132
-DGIT_HTTP_USER_AGENT='"git/$(GIT_VERSION)"'
20882133

@@ -2156,17 +2201,37 @@ XGETTEXT_FLAGS = \
21562201
XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) --language=C \
21572202
--keyword=_ --keyword=N_ --keyword="Q_:1,2"
21582203
XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell
2204+
XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl
21592205
LOCALIZED_C := $(C_OBJ:o=c)
21602206
LOCALIZED_SH := $(SCRIPT_SH)
2207+
LOCALIZED_PERL := $(SCRIPT_PERL)
2208+
2209+
ifdef XGETTEXT_INCLUDE_TESTS
2210+
LOCALIZED_C += t/t0200/test.c
2211+
LOCALIZED_SH += t/t0200/test.sh
2212+
LOCALIZED_PERL += t/t0200/test.perl
2213+
endif
21612214

21622215
po/git.pot: $(LOCALIZED_C)
21632216
$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C)
21642217
$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_SH) \
21652218
$(LOCALIZED_SH)
2219+
$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_PERL) \
2220+
$(LOCALIZED_PERL)
21662221
mv $@+ $@
21672222

21682223
pot: po/git.pot
21692224

2225+
POFILES := $(wildcard po/*.po)
2226+
MOFILES := $(patsubst po/%.po,po/build/locale/%/LC_MESSAGES/git.mo,$(POFILES))
2227+
2228+
ifndef NO_GETTEXT
2229+
all:: $(MOFILES)
2230+
endif
2231+
2232+
po/build/locale/%/LC_MESSAGES/git.mo: po/%.po
2233+
$(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<
2234+
21702235
FIND_SOURCE_FILES = ( git ls-files '*.[hcS]' 2>/dev/null || \
21712236
$(FIND) . \( -name .git -type d -prune \) \
21722237
-o \( -name '*.[hcS]' -type f -print \) )
@@ -2185,7 +2250,8 @@ cscope:
21852250

21862251
### Detect prefix changes
21872252
TRACK_CFLAGS = $(CC):$(subst ','\'',$(ALL_CFLAGS)):\
2188-
$(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
2253+
$(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ):\
2254+
$(localedir_SQ)
21892255

21902256
GIT-CFLAGS: FORCE
21912257
@FLAGS='$(TRACK_CFLAGS)'; \
@@ -2222,6 +2288,7 @@ endif
22222288
ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT
22232289
@echo GIT_TEST_CMP_USE_COPIED_CONTEXT=YesPlease >>$@
22242290
endif
2291+
@echo NO_GETTEXT=\''$(subst ','\'',$(subst ','\'',$(NO_GETTEXT)))'\' >>$@
22252292
@echo GETTEXT_POISON=\''$(subst ','\'',$(subst ','\'',$(GETTEXT_POISON)))'\' >>$@
22262293
@echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@
22272294

@@ -2338,6 +2405,11 @@ install: all
23382405
$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
23392406
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
23402407
$(INSTALL) -m 644 mergetools/* '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
2408+
ifndef NO_GETTEXT
2409+
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(localedir_SQ)'
2410+
(cd po/build/locale && $(TAR) cf - .) | \
2411+
(cd '$(DESTDIR_SQ)$(localedir_SQ)' && umask 022 && $(TAR) xof -)
2412+
endif
23412413
ifndef NO_PERL
23422414
$(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
23432415
$(MAKE) -C gitweb install
@@ -2474,6 +2546,7 @@ clean:
24742546
$(RM) $(TEST_PROGRAMS)
24752547
$(RM) -r bin-wrappers
24762548
$(RM) -r $(dep_dirs)
2549+
$(RM) -r po/build/
24772550
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h $(ETAGS_TARGET) tags cscope*
24782551
$(RM) -r autom4te.cache
24792552
$(RM) config.log config.mak.autogen config.mak.append config.status config.cache

config.mak.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ NO_CURL=@NO_CURL@
3535
NO_EXPAT=@NO_EXPAT@
3636
NO_LIBGEN_H=@NO_LIBGEN_H@
3737
HAVE_PATHS_H=@HAVE_PATHS_H@
38+
HAVE_LIBCHARSET_H=@HAVE_LIBCHARSET_H@
39+
NO_GETTEXT=@NO_GETTEXT@
40+
LIBC_CONTAINS_LIBINTL=@LIBC_CONTAINS_LIBINTL@
3841
NEEDS_LIBICONV=@NEEDS_LIBICONV@
3942
NEEDS_SOCKET=@NEEDS_SOCKET@
4043
NEEDS_RESOLV=@NEEDS_RESOLV@

configure.ac

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,12 @@ AC_CHECK_LIB([c], [basename],
636636
AC_SUBST(NEEDS_LIBGEN)
637637
test -n "$NEEDS_LIBGEN" && LIBS="$LIBS -lgen"
638638

639+
AC_CHECK_LIB([c], [gettext],
640+
[LIBC_CONTAINS_LIBINTL=YesPlease],
641+
[LIBC_CONTAINS_LIBINTL=])
642+
AC_SUBST(LIBC_CONTAINS_LIBINTL)
643+
test -n "$LIBC_CONTAINS_LIBINTL" || LIBS="$LIBS -lintl"
644+
639645
## Checks for header files.
640646
AC_MSG_NOTICE([CHECKS for header files])
641647
#
@@ -818,6 +824,19 @@ AC_CHECK_HEADER([paths.h],
818824
[HAVE_PATHS_H=])
819825
AC_SUBST(HAVE_PATHS_H)
820826
#
827+
# Define NO_GETTEXT if you don't want Git output to be translated.
828+
# A translated Git requires GNU libintl or another gettext implementation
829+
AC_CHECK_HEADER([libintl.h],
830+
[NO_GETTEXT=],
831+
[NO_GETTEXT=YesPlease])
832+
AC_SUBST(NO_GETTEXT)
833+
#
834+
# Define HAVE_LIBCHARSET_H if have libcharset.h
835+
AC_CHECK_HEADER([libcharset.h],
836+
[HAVE_LIBCHARSET_H=YesPlease],
837+
[HAVE_LIBCHARSET_H=])
838+
AC_SUBST(HAVE_LIBCHARSET_H)
839+
#
821840
# Define NO_STRCASESTR if you don't have strcasestr.
822841
GIT_CHECK_FUNC(strcasestr,
823842
[NO_STRCASESTR=],

daemon.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,8 @@ int main(int argc, char **argv)
10991099
struct credentials *cred = NULL;
11001100
int i;
11011101

1102+
git_setup_gettext();
1103+
11021104
git_extract_argv0_path(argv[0]);
11031105

11041106
for (i = 1; i < argc; i++) {

fast-import.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3305,6 +3305,8 @@ int main(int argc, const char **argv)
33053305

33063306
git_extract_argv0_path(argv[0]);
33073307

3308+
git_setup_gettext();
3309+
33083310
if (argc == 2 && !strcmp(argv[1], "-h"))
33093311
usage(fast_import_usage);
33103312

0 commit comments

Comments
 (0)