]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'ab/enable-i18n'
authorJunio C Hamano <gitster@pobox.com>
Tue, 20 Dec 2011 00:06:41 +0000 (16:06 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 20 Dec 2011 00:06:41 +0000 (16:06 -0800)
* ab/enable-i18n:
  i18n: add infrastructure for translating Git with gettext

Conflicts:
Makefile

1  2 
Makefile
fast-import.c
git.c
http-fetch.c
http-push.c
imap-send.c
t/test-lib.sh

diff --combined Makefile
index 898278d58bf972a42bc8b8deb5a7dcf93b23df9f,08b92970843cd453f344954964b7d78c202a0db7..9470a1034396a5f3ee36c5d0e6ffc54e21bb3820
+++ b/Makefile
@@@ -43,6 -43,22 +43,22 @@@ all:
  # Define EXPATDIR=/foo/bar if your expat header and library files are in
  # /foo/bar/include and /foo/bar/lib directories.
  #
+ # Define NO_GETTEXT if you don't want Git output to be translated.
+ # A translated Git requires GNU libintl or another gettext implementation,
+ # plus libintl-perl at runtime.
+ #
+ # Define HAVE_LIBCHARSET_H if you haven't set NO_GETTEXT and you can't
+ # trust the langinfo.h's nl_langinfo(CODESET) function to return the
+ # current character set. GNU and Solaris have a nl_langinfo(CODESET),
+ # FreeBSD can use either, but MinGW and some others need to use
+ # libcharset.h's locale_charset() instead.
+ #
+ # Define LIBC_CONTAINS_LIBINTL if your gettext implementation doesn't
+ # need -lintl when linking.
+ #
+ # Define NO_MSGFMT_EXTENDED_OPTIONS if your implementation of msgfmt
+ # doesn't support GNU extensions like --check and --statistics
+ #
  # Define HAVE_PATHS_H if you have paths.h and want to use the default PATH
  # it specifies.
  #
@@@ -57,8 -73,8 +73,8 @@@
  #
  # Define NO_STRLCPY if you don't have strlcpy.
  #
 -# Define NO_STRTOUMAX if you don't have strtoumax in the C library.
 -# If your compiler also does not support long long or does not have
 +# Define NO_STRTOUMAX if you don't have both strtoimax and strtoumax in the
 +# C library. If your compiler also does not support long long or does not have
  # strtoull, define NO_STRTOULL.
  #
  # Define NO_SETENV if you don't have setenv in the C library.
  #
  # Define NO_IPV6 if you lack IPv6 support and getaddrinfo().
  #
 +# Define NO_UNIX_SOCKETS if your system does not offer unix sockets.
 +#
  # Define NO_SOCKADDR_STORAGE if your platform does not have struct
  # sockaddr_storage.
  #
  #   DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
  #   DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'
  #
 +# Define COMPUTE_HEADER_DEPENDENCIES to "yes" if you want dependencies on
 +# header files to be automatically computed, to avoid rebuilding objects when
 +# an unrelated header file changes.  Define it to "no" to use the hard-coded
 +# dependency rules.  The default is "auto", which means to use computed header
 +# dependencies if your compiler is detected to support it.
 +#
  # Define CHECK_HEADER_DEPENDENCIES to check for problems in the hard-coded
  # dependency rules.
  #
@@@ -309,6 -317,7 +325,7 @@@ gitexecdir = libexec/git-cor
  mergetoolsdir = $(gitexecdir)/mergetools
  sharedir = $(prefix)/share
  gitwebdir = $(sharedir)/gitweb
+ localedir = $(sharedir)/locale
  template_dir = share/git-core/templates
  htmldir = share/doc/git-doc
  ETC_GITCONFIG = $(sysconfdir)/gitconfig
@@@ -317,7 -326,7 +334,7 @@@ lib = li
  # DESTDIR=
  pathsep = :
  
- export prefix bindir sharedir sysconfdir gitwebdir
+ export prefix bindir sharedir sysconfdir gitwebdir localedir
  
  CC = gcc
  AR = ar
@@@ -330,6 -339,7 +347,7 @@@ RPMBUILD = rpmbuil
  TCL_PATH = tclsh
  TCLTK_PATH = wish
  XGETTEXT = xgettext
+ MSGFMT = msgfmt
  PTHREAD_LIBS = -lpthread
  PTHREAD_CFLAGS =
  GCOV = gcov
@@@ -429,17 -439,14 +447,17 @@@ PROGRAM_OBJS += show-index.
  PROGRAM_OBJS += upload-pack.o
  PROGRAM_OBJS += http-backend.o
  PROGRAM_OBJS += sh-i18n--envsubst.o
 +PROGRAM_OBJS += credential-store.o
  
  PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
  
  TEST_PROGRAMS_NEED_X += test-chmtime
 +TEST_PROGRAMS_NEED_X += test-credential
  TEST_PROGRAMS_NEED_X += test-ctype
  TEST_PROGRAMS_NEED_X += test-date
  TEST_PROGRAMS_NEED_X += test-delta
  TEST_PROGRAMS_NEED_X += test-dump-cache-tree
 +TEST_PROGRAMS_NEED_X += test-scrap-cache-tree
  TEST_PROGRAMS_NEED_X += test-genrandom
  TEST_PROGRAMS_NEED_X += test-index-version
  TEST_PROGRAMS_NEED_X += test-line-buffer
@@@ -516,7 -523,6 +534,7 @@@ LIB_H += argv-array.
  LIB_H += attr.h
  LIB_H += blob.h
  LIB_H += builtin.h
 +LIB_H += bulk-checkin.h
  LIB_H += cache.h
  LIB_H += cache-tree.h
  LIB_H += color.h
@@@ -530,8 -536,6 +548,8 @@@ LIB_H += compat/win32/syslog.
  LIB_H += compat/win32/poll.h
  LIB_H += compat/win32/dirent.h
  LIB_H += connected.h
 +LIB_H += convert.h
 +LIB_H += credential.h
  LIB_H += csum-file.h
  LIB_H += decorate.h
  LIB_H += delta.h
@@@ -539,11 -543,9 +557,11 @@@ LIB_H += diffcore.
  LIB_H += diff.h
  LIB_H += dir.h
  LIB_H += exec_cmd.h
 +LIB_H += fmt-merge-msg.h
  LIB_H += fsck.h
  LIB_H += gettext.h
  LIB_H += git-compat-util.h
 +LIB_H += gpg-interface.h
  LIB_H += graph.h
  LIB_H += grep.h
  LIB_H += hash.h
@@@ -607,7 -609,6 +625,7 @@@ LIB_OBJS += base85.
  LIB_OBJS += bisect.o
  LIB_OBJS += blob.o
  LIB_OBJS += branch.o
 +LIB_OBJS += bulk-checkin.o
  LIB_OBJS += bundle.o
  LIB_OBJS += cache-tree.o
  LIB_OBJS += color.o
@@@ -619,7 -620,6 +637,7 @@@ LIB_OBJS += connect.
  LIB_OBJS += connected.o
  LIB_OBJS += convert.o
  LIB_OBJS += copy.o
 +LIB_OBJS += credential.o
  LIB_OBJS += csum-file.o
  LIB_OBJS += ctype.o
  LIB_OBJS += date.o
@@@ -639,7 -639,7 +657,8 @@@ LIB_OBJS += entry.
  LIB_OBJS += environment.o
  LIB_OBJS += exec_cmd.o
  LIB_OBJS += fsck.o
 +LIB_OBJS += gpg-interface.o
+ LIB_OBJS += gettext.o
  LIB_OBJS += graph.o
  LIB_OBJS += grep.o
  LIB_OBJS += hash.o
@@@ -836,12 -836,14 +855,14 @@@ ifeq ($(uname_S),Linux
        NO_STRLCPY = YesPlease
        NO_MKSTEMPS = YesPlease
        HAVE_PATHS_H = YesPlease
+       LIBC_CONTAINS_LIBINTL = YesPlease
  endif
  ifeq ($(uname_S),GNU/kFreeBSD)
        NO_STRLCPY = YesPlease
        NO_MKSTEMPS = YesPlease
        HAVE_PATHS_H = YesPlease
        DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease
+       LIBC_CONTAINS_LIBINTL = YesPlease
  endif
  ifeq ($(uname_S),UnixWare)
        CC = cc
@@@ -908,6 -910,7 +929,7 @@@ ifeq ($(uname_S),SunOS
        NO_MKSTEMPS = YesPlease
        NO_REGEX = YesPlease
        NO_FNMATCH_CASEFOLD = YesPlease
+       NO_MSGFMT_EXTENDED_OPTIONS = YesPlease
        ifeq ($(uname_R),5.6)
                SOCKLEN_T = int
                NO_HSTRERROR = YesPlease
@@@ -1031,6 -1034,7 +1053,7 @@@ ifeq ($(uname_S),GNU
        NO_STRLCPY=YesPlease
        NO_MKSTEMPS = YesPlease
        HAVE_PATHS_H = YesPlease
+       LIBC_CONTAINS_LIBINTL = YesPlease
  endif
  ifeq ($(uname_S),IRIX)
        NO_SETENV = YesPlease
@@@ -1110,7 -1114,6 +1133,7 @@@ ifeq ($(uname_S),Windows
        NO_SYS_POLL_H = YesPlease
        NO_SYMLINK_HEAD = YesPlease
        NO_IPV6 = YesPlease
 +      NO_UNIX_SOCKETS = YesPlease
        NO_SETENV = YesPlease
        NO_UNSETENV = YesPlease
        NO_STRCASESTR = YesPlease
@@@ -1204,7 -1207,6 +1227,7 @@@ ifneq (,$(findstring MINGW,$(uname_S))
        NO_LIBGEN_H = YesPlease
        NO_SYS_POLL_H = YesPlease
        NO_SYMLINK_HEAD = YesPlease
 +      NO_UNIX_SOCKETS = YesPlease
        NO_SETENV = YesPlease
        NO_UNSETENV = YesPlease
        NO_STRCASESTR = YesPlease
@@@ -1249,6 -1251,7 +1272,7 @@@ ifneq (,$(wildcard ../THIS_IS_MSYSGIT)
        EXTLIBS += /mingw/lib/libz.a
        NO_R_TO_GCC_LINKER = YesPlease
        INTERNAL_QSORT = YesPlease
+       HAVE_LIBCHARSET_H = YesPlease
  else
        NO_CURL = YesPlease
  endif
@@@ -1266,32 -1269,21 +1290,32 @@@ endi
  endif
  
  ifdef CHECK_HEADER_DEPENDENCIES
 -COMPUTE_HEADER_DEPENDENCIES =
 +COMPUTE_HEADER_DEPENDENCIES = no
  USE_COMPUTED_HEADER_DEPENDENCIES =
 -else
 +endif
 +
  ifndef COMPUTE_HEADER_DEPENDENCIES
 +COMPUTE_HEADER_DEPENDENCIES = auto
 +endif
 +
 +ifeq ($(COMPUTE_HEADER_DEPENDENCIES),auto)
  dep_check = $(shell $(CC) $(ALL_CFLAGS) \
        -c -MF /dev/null -MMD -MP -x c /dev/null -o /dev/null 2>&1; \
        echo $$?)
  ifeq ($(dep_check),0)
 -COMPUTE_HEADER_DEPENDENCIES=YesPlease
 -endif
 +override COMPUTE_HEADER_DEPENDENCIES = yes
 +else
 +override COMPUTE_HEADER_DEPENDENCIES = no
  endif
  endif
  
 -ifdef COMPUTE_HEADER_DEPENDENCIES
 +ifeq ($(COMPUTE_HEADER_DEPENDENCIES),yes)
  USE_COMPUTED_HEADER_DEPENDENCIES = YesPlease
 +else
 +ifneq ($(COMPUTE_HEADER_DEPENDENCIES),no)
 +$(error please set COMPUTE_HEADER_DEPENDENCIES to yes, no, or auto \
 +(not "$(COMPUTE_HEADER_DEPENDENCIES)"))
 +endif
  endif
  
  ifdef SANE_TOOL_PATH
@@@ -1437,6 -1429,11 +1461,11 @@@ endi
  ifdef NEEDS_LIBGEN
        EXTLIBS += -lgen
  endif
+ ifndef NO_GETTEXT
+ ifndef LIBC_CONTAINS_LIBINTL
+       EXTLIBS += -lintl
+ endif
+ endif
  ifdef NEEDS_SOCKET
        EXTLIBS += -lsocket
  endif
@@@ -1479,9 -1476,11 +1508,11 @@@ ifdef NO_SYMLINK_HEA
        BASIC_CFLAGS += -DNO_SYMLINK_HEAD
  endif
  ifdef GETTEXT_POISON
-       LIB_OBJS += gettext.o
        BASIC_CFLAGS += -DGETTEXT_POISON
  endif
+ ifdef NO_GETTEXT
+       BASIC_CFLAGS += -DNO_GETTEXT
+ endif
  ifdef NO_STRCASESTR
        COMPAT_CFLAGS += -DNO_STRCASESTR
        COMPAT_OBJS += compat/strcasestr.o
@@@ -1492,7 -1491,7 +1523,7 @@@ ifdef NO_STRLCP
  endif
  ifdef NO_STRTOUMAX
        COMPAT_CFLAGS += -DNO_STRTOUMAX
 -      COMPAT_OBJS += compat/strtoumax.o
 +      COMPAT_OBJS += compat/strtoumax.o compat/strtoimax.o
  endif
  ifdef NO_STRTOULL
        COMPAT_CFLAGS += -DNO_STRTOULL
@@@ -1582,12 -1581,6 +1613,12 @@@ ifdef NO_INET_PTO
        LIB_OBJS += compat/inet_pton.o
        BASIC_CFLAGS += -DNO_INET_PTON
  endif
 +ifndef NO_UNIX_SOCKETS
 +      LIB_OBJS += unix-socket.o
 +      LIB_H += unix-socket.h
 +      PROGRAM_OBJS += credential-cache.o
 +      PROGRAM_OBJS += credential-cache--daemon.o
 +endif
  
  ifdef NO_ICONV
        BASIC_CFLAGS += -DNO_ICONV
@@@ -1650,6 -1643,10 +1681,10 @@@ ifdef HAVE_PATHS_
        BASIC_CFLAGS += -DHAVE_PATHS_H
  endif
  
+ ifdef HAVE_LIBCHARSET_H
+       BASIC_CFLAGS += -DHAVE_LIBCHARSET_H
+ endif
  ifdef DIR_HAS_BSD_GROUP_SEMANTICS
        COMPAT_CFLAGS += -DDIR_HAS_BSD_GROUP_SEMANTICS
  endif
@@@ -1670,6 -1667,10 +1705,10 @@@ ifdef GIT_TEST_CMP_USE_COPIED_CONTEX
        export GIT_TEST_CMP_USE_COPIED_CONTEXT
  endif
  
+ ifndef NO_MSGFMT_EXTENDED_OPTIONS
+       MSGFMT += --check --statistics
+ endif
  ifeq ($(TCLTK_PATH),)
  NO_TCLTK=NoThanks
  endif
@@@ -1700,6 -1701,7 +1739,7 @@@ ifndef 
        QUIET_GEN      = @echo '   ' GEN $@;
        QUIET_LNCP     = @echo '   ' LN/CP $@;
        QUIET_XGETTEXT = @echo '   ' XGETTEXT $@;
+       QUIET_MSGFMT   = @echo '   ' MSGFMT $@;
        QUIET_GCOV     = @echo '   ' GCOV $@;
        QUIET_SP       = @echo '   ' SP $<;
        QUIET_SUBDIR0  = +@subdir=
@@@ -1726,6 -1728,7 +1766,7 @@@ bindir_SQ = $(subst ','\'',$(bindir)
  bindir_relative_SQ = $(subst ','\'',$(bindir_relative))
  mandir_SQ = $(subst ','\'',$(mandir))
  infodir_SQ = $(subst ','\'',$(infodir))
+ localedir_SQ = $(subst ','\'',$(localedir))
  gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
  template_dir_SQ = $(subst ','\'',$(template_dir))
  htmldir_SQ = $(subst ','\'',$(htmldir))
@@@ -1781,7 -1784,7 +1822,7 @@@ ifndef NO_TCLT
        $(QUIET_SUBDIR0)gitk-git $(QUIET_SUBDIR1) all
  endif
  ifndef NO_PERL
-       $(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' all
+       $(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' localedir='$(localedir_SQ)' all
  endif
  ifndef NO_PYTHON
        $(QUIET_SUBDIR0)git_remote_helpers $(QUIET_SUBDIR1) PYTHON_PATH='$(PYTHON_PATH_SQ)' prefix='$(prefix_SQ)' all
@@@ -1831,6 -1834,7 +1872,7 @@@ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|
      -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \
      -e 's|@@DIFF@@|$(DIFF_SQ)|' \
      -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
+     -e 's|@@LOCALEDIR@@|$(localedir_SQ)|g' \
      -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
      -e $(BROKEN_PATH_FIX) \
      $@.sh >$@+
@@@ -1944,7 -1948,7 +1986,7 @@@ OBJECTS := $(GIT_OBJS) $(XDIFF_OBJS) $(
  dep_files := $(foreach f,$(OBJECTS),$(dir $f).depend/$(notdir $f).d)
  dep_dirs := $(addsuffix .depend,$(sort $(dir $(OBJECTS))))
  
 -ifdef COMPUTE_HEADER_DEPENDENCIES
 +ifeq ($(COMPUTE_HEADER_DEPENDENCIES),yes)
  $(dep_dirs):
        @mkdir -p $@
  
@@@ -1957,7 -1961,7 +1999,7 @@@ Please unset CHECK_HEADER_DEPENDENCIES 
  endif
  endif
  
 -ifndef COMPUTE_HEADER_DEPENDENCIES
 +ifneq ($(COMPUTE_HEADER_DEPENDENCIES),yes)
  ifndef CHECK_HEADER_DEPENDENCIES
  dep_dirs =
  missing_dep_dirs =
@@@ -2047,13 -2051,13 +2089,13 @@@ builtin/branch.o builtin/checkout.o bui
  builtin/bundle.o bundle.o transport.o: bundle.h
  builtin/bisect--helper.o builtin/rev-list.o bisect.o: bisect.h
  builtin/clone.o builtin/fetch-pack.o transport.o: fetch-pack.h
 -builtin/grep.o builtin/pack-objects.o transport-helper.o: thread-utils.h
 +builtin/grep.o builtin/pack-objects.o transport-helper.o thread-utils.o: thread-utils.h
  builtin/send-pack.o transport.o: send-pack.h
  builtin/log.o builtin/shortlog.o: shortlog.h
  builtin/prune.o builtin/reflog.o reachable.o: reachable.h
  builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
  builtin/tar-tree.o archive-tar.o: tar.h
 -connect.o transport.o http-backend.o: url.h
 +connect.o transport.o url.o http-backend.o: url.h
  http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
  http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h
  
@@@ -2083,6 -2087,9 +2125,9 @@@ config.sp config.s config.o: EXTRA_CPPF
  attr.sp attr.s attr.o: EXTRA_CPPFLAGS = \
        -DETC_GITATTRIBUTES='"$(ETC_GITATTRIBUTES_SQ)"'
  
+ gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \
+       -DGIT_LOCALE_PATH='"$(localedir_SQ)"'
  http.sp http.s http.o: EXTRA_CPPFLAGS = \
        -DGIT_HTTP_USER_AGENT='"git/$(GIT_VERSION)"'
  
@@@ -2156,17 -2163,37 +2201,37 @@@ XGETTEXT_FLAGS = 
  XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) --language=C \
        --keyword=_ --keyword=N_ --keyword="Q_:1,2"
  XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell
+ XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl
  LOCALIZED_C := $(C_OBJ:o=c)
  LOCALIZED_SH := $(SCRIPT_SH)
+ LOCALIZED_PERL := $(SCRIPT_PERL)
+ ifdef XGETTEXT_INCLUDE_TESTS
+ LOCALIZED_C += t/t0200/test.c
+ LOCALIZED_SH += t/t0200/test.sh
+ LOCALIZED_PERL += t/t0200/test.perl
+ endif
  
  po/git.pot: $(LOCALIZED_C)
        $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C)
        $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_SH) \
                $(LOCALIZED_SH)
+       $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_PERL) \
+               $(LOCALIZED_PERL)
        mv $@+ $@
  
  pot: po/git.pot
  
+ POFILES := $(wildcard po/*.po)
+ MOFILES := $(patsubst po/%.po,po/build/locale/%/LC_MESSAGES/git.mo,$(POFILES))
+ ifndef NO_GETTEXT
+ all:: $(MOFILES)
+ endif
+ po/build/locale/%/LC_MESSAGES/git.mo: po/%.po
+       $(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $<
  FIND_SOURCE_FILES = ( git ls-files '*.[hcS]' 2>/dev/null || \
                        $(FIND) . \( -name .git -type d -prune \) \
                                -o \( -name '*.[hcS]' -type f -print \) )
@@@ -2185,7 -2212,8 +2250,8 @@@ cscope
  
  ### Detect prefix changes
  TRACK_CFLAGS = $(CC):$(subst ','\'',$(ALL_CFLAGS)):\
-              $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
+              $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ):\
+              $(localedir_SQ)
  
  GIT-CFLAGS: FORCE
        @FLAGS='$(TRACK_CFLAGS)'; \
@@@ -2222,8 -2250,8 +2288,9 @@@ endi
  ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT
        @echo GIT_TEST_CMP_USE_COPIED_CONTEXT=YesPlease >>$@
  endif
+       @echo NO_GETTEXT=\''$(subst ','\'',$(subst ','\'',$(NO_GETTEXT)))'\' >>$@
        @echo GETTEXT_POISON=\''$(subst ','\'',$(subst ','\'',$(GETTEXT_POISON)))'\' >>$@
 +      @echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@
  
  ### Detect Tck/Tk interpreter path changes
  ifndef NO_TCLTK
@@@ -2338,6 -2366,11 +2405,11 @@@ install: al
        $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
        $(INSTALL) -m 644 mergetools/* '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
+ ifndef NO_GETTEXT
+       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(localedir_SQ)'
+       (cd po/build/locale && $(TAR) cf - .) | \
+       (cd '$(DESTDIR_SQ)$(localedir_SQ)' && umask 022 && $(TAR) xof -)
+ endif
  ifndef NO_PERL
        $(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
        $(MAKE) -C gitweb install
@@@ -2474,6 -2507,7 +2546,7 @@@ clean
        $(RM) $(TEST_PROGRAMS)
        $(RM) -r bin-wrappers
        $(RM) -r $(dep_dirs)
+       $(RM) -r po/build/
        $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h $(ETAGS_TARGET) tags cscope*
        $(RM) -r autom4te.cache
        $(RM) config.log config.mak.autogen config.mak.append config.status config.cache
diff --combined fast-import.c
index 350b2e9e107b8dadf129f00817b6ad3e85d9d973,b59e7db6a6efe3299b95cc0d68b7f7e0f0c5a8d3..4b9c4b73a020e9eefa4caf0bd6ec833df424c9a0
@@@ -1143,11 -1143,17 +1143,11 @@@ static int store_object
        return 0;
  }
  
 -static void truncate_pack(off_t to, git_SHA_CTX *ctx)
 +static void truncate_pack(struct sha1file_checkpoint *checkpoint)
  {
 -      if (ftruncate(pack_data->pack_fd, to)
 -       || lseek(pack_data->pack_fd, to, SEEK_SET) != to)
 +      if (sha1file_truncate(pack_file, checkpoint))
                die_errno("cannot truncate pack to skip duplicate");
 -      pack_size = to;
 -
 -      /* yes this is a layering violation */
 -      pack_file->total = to;
 -      pack_file->offset = 0;
 -      pack_file->ctx = *ctx;
 +      pack_size = checkpoint->offset;
  }
  
  static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
        unsigned long hdrlen;
        off_t offset;
        git_SHA_CTX c;
 -      git_SHA_CTX pack_file_ctx;
        git_zstream s;
 +      struct sha1file_checkpoint checkpoint;
        int status = Z_OK;
  
        /* Determine if we should auto-checkpoint. */
                || (pack_size + 60 + len) < pack_size)
                cycle_packfile();
  
 -      offset = pack_size;
 -
 -      /* preserve the pack_file SHA1 ctx in case we have to truncate later */
 -      sha1flush(pack_file);
 -      pack_file_ctx = pack_file->ctx;
 +      sha1file_checkpoint(pack_file, &checkpoint);
 +      offset = checkpoint.offset;
  
        hdrlen = snprintf((char *)out_buf, out_sz, "blob %" PRIuMAX, len) + 1;
        if (out_sz <= hdrlen)
  
        if (e->idx.offset) {
                duplicate_count_by_type[OBJ_BLOB]++;
 -              truncate_pack(offset, &pack_file_ctx);
 +              truncate_pack(&checkpoint);
  
        } else if (find_sha1_pack(sha1, packed_git)) {
                e->type = OBJ_BLOB;
                e->pack_id = MAX_PACK_ID;
                e->idx.offset = 1; /* just not zero! */
                duplicate_count_by_type[OBJ_BLOB]++;
 -              truncate_pack(offset, &pack_file_ctx);
 +              truncate_pack(&checkpoint);
  
        } else {
                e->depth = 0;
@@@ -2164,11 -2173,6 +2164,11 @@@ static uintmax_t do_change_note_fanout
  
                if (tmp_hex_sha1_len == 40 && !get_sha1_hex(hex_sha1, sha1)) {
                        /* This is a note entry */
 +                      if (fanout == 0xff) {
 +                              /* Counting mode, no rename */
 +                              num_notes++;
 +                              continue;
 +                      }
                        construct_path_with_fanout(hex_sha1, fanout, realpath);
                        if (!strcmp(fullpath, realpath)) {
                                /* Note entry is in correct location */
@@@ -2375,7 -2379,7 +2375,7 @@@ static void file_change_cr(struct branc
                leaf.tree);
  }
  
 -static void note_change_n(struct branch *b, unsigned char old_fanout)
 +static void note_change_n(struct branch *b, unsigned char *old_fanout)
  {
        const char *p = command_buf.buf + 2;
        static struct strbuf uq = STRBUF_INIT;
        uint16_t inline_data = 0;
        unsigned char new_fanout;
  
 +      /*
 +       * When loading a branch, we don't traverse its tree to count the real
 +       * number of notes (too expensive to do this for all non-note refs).
 +       * This means that recently loaded notes refs might incorrectly have
 +       * b->num_notes == 0, and consequently, old_fanout might be wrong.
 +       *
 +       * Fix this by traversing the tree and counting the number of notes
 +       * when b->num_notes == 0. If the notes tree is truly empty, the
 +       * calculation should not take long.
 +       */
 +      if (b->num_notes == 0 && *old_fanout == 0) {
 +              /* Invoke change_note_fanout() in "counting mode". */
 +              b->num_notes = change_note_fanout(&b->branch_tree, 0xff);
 +              *old_fanout = convert_num_notes_to_fanout(b->num_notes);
 +      }
 +
 +      /* Now parse the notemodify command. */
        /* <dataref> or 'inline' */
        if (*p == ':') {
                char *x;
                            typename(type), command_buf.buf);
        }
  
 -      construct_path_with_fanout(sha1_to_hex(commit_sha1), old_fanout, path);
 +      construct_path_with_fanout(sha1_to_hex(commit_sha1), *old_fanout, path);
        if (tree_content_remove(&b->branch_tree, path, NULL))
                b->num_notes--;
  
@@@ -2650,7 -2637,7 +2650,7 @@@ static void parse_new_commit(void
                else if (!prefixcmp(command_buf.buf, "C "))
                        file_change_cr(b, 0);
                else if (!prefixcmp(command_buf.buf, "N "))
 -                      note_change_n(b, prev_fanout);
 +                      note_change_n(b, &prev_fanout);
                else if (!strcmp("deleteall", command_buf.buf))
                        file_change_deleteall(b);
                else if (!prefixcmp(command_buf.buf, "ls "))
@@@ -3305,6 -3292,8 +3305,8 @@@ int main(int argc, const char **argv
  
        git_extract_argv0_path(argv[0]);
  
+       git_setup_gettext();
        if (argc == 2 && !strcmp(argv[1], "-h"))
                usage(fast_import_usage);
  
diff --combined git.c
index 250f4483eae3c8184e0f4bfc65c96cbb9e32756e,fa918b5652dc333dcf08d456898adcb5811ae601..fb9029cbf17bdad1d52ea6eae0c8f4ddf6a13979
--- 1/git.c
--- 2/git.c
+++ b/git.c
@@@ -434,7 -434,6 +434,7 @@@ static void handle_internal_command(in
                { "update-ref", cmd_update_ref, RUN_SETUP },
                { "update-server-info", cmd_update_server_info, RUN_SETUP },
                { "upload-archive", cmd_upload_archive },
 +              { "upload-archive--writer", cmd_upload_archive_writer },
                { "var", cmd_var, RUN_SETUP_GENTLY },
                { "verify-pack", cmd_verify_pack },
                { "verify-tag", cmd_verify_tag, RUN_SETUP },
@@@ -538,6 -537,8 +538,8 @@@ int main(int argc, const char **argv
        if (!cmd)
                cmd = "git-help";
  
+       git_setup_gettext();
        /*
         * "git-xxxx" is the same as "git xxxx", but we obviously:
         *
diff --combined http-fetch.c
index 94d47cbb287f7d3ea76b71f3ef39ddeea3b9202c,9719d586993066563e80639dc299dccf80388e4d..ba3ea106708de01fc933e6743ab109bef2697f75
@@@ -22,6 -22,8 +22,8 @@@ int main(int argc, const char **argv
        int get_verbosely = 0;
        int get_recover = 0;
  
+       git_setup_gettext();
        git_extract_argv0_path(argv[0]);
  
        while (arg < argc && argv[arg][0] == '-') {
@@@ -67,7 -69,7 +69,7 @@@
  
        git_config(git_default_config, NULL);
  
 -      http_init(NULL, url);
 +      http_init(NULL, url, 0);
        walker = get_http_walker(url);
        walker->get_tree = get_tree;
        walker->get_history = get_history;
diff --combined http-push.c
index cdfdd4f79199261b2a62012381728d676484e424,f856299254fb7d2cf120c423fdb25748357ef926..f22f7e43caa3e804c5c8275ba0312d58611d7da3
@@@ -1748,6 -1748,8 +1748,8 @@@ int main(int argc, char **argv
        int new_refs;
        struct ref *ref, *local_refs;
  
+       git_setup_gettext();
        git_extract_argv0_path(argv[0]);
  
        repo = xcalloc(sizeof(*repo), 1);
  
        memset(remote_dir_exists, -1, 256);
  
 -      http_init(NULL, repo->url);
 +      http_init(NULL, repo->url, 1);
  
  #ifdef USE_CURL_MULTI
        is_running_queue = 0;
diff --combined imap-send.c
index 80e0e8c051ad26a3a1353a4beb21e5c6ebdd6823,9fba422f509ca9e978be0162e34b0285b2727c1a..91763d30181bed9bc6a3bf1cbc8d495d5b88f288
@@@ -161,6 -161,7 +161,6 @@@ static struct imap_server_conf server 
  struct imap_store_conf {
        struct store_conf gen;
        struct imap_server_conf *server;
 -      unsigned use_namespace:1;
  };
  
  #define NIL   (void *)0x1
@@@ -1538,6 -1539,8 +1538,8 @@@ int main(int argc, char **argv
  
        git_extract_argv0_path(argv[0]);
  
+       git_setup_gettext();
        if (argc != 1)
                usage(imap_send_usage);
  
diff --combined t/test-lib.sh
index 160479b81ea2f2f902c5e579a9a3469b92c656bf,9cfabe447b5675f6725b4b71244814d38e76998b..0e932dd9758f71cbc95c6ab20f7c11e9056d7826
@@@ -44,6 -44,7 +44,7 @@@ export LANG LC_ALL PAGER TERM T
  EDITOR=:
  unset VISUAL
  unset EMAIL
+ unset LANGUAGE
  unset $(perl -e '
        my @env = keys %ENV;
        my $ok = join("|", qw(
@@@ -379,11 -380,6 +380,11 @@@ test_config () 
        git config "$@"
  }
  
 +test_config_global () {
 +      test_when_finished "test_unconfig --global '$1'" &&
 +      git config --global "$@"
 +}
 +
  # Use test_set_prereq to tell that a particular prerequisite is available.
  # The prerequisite can later be checked for in two ways:
  #
  test -z "$NO_PERL" && test_set_prereq PERL
  test -z "$NO_PYTHON" && test_set_prereq PYTHON
  test -n "$USE_LIBPCRE" && test_set_prereq LIBPCRE
+ test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
  
  # Can we rely on git's output in the C locale?
  if test -n "$GETTEXT_POISON"
  then
        GIT_GETTEXT_POISON=YesPlease
        export GIT_GETTEXT_POISON
+       test_set_prereq GETTEXT_POISON
  else
        test_set_prereq C_LOCALE_OUTPUT
  fi