From 15edb002c66b75856f5de9fd955f1bba9cdfd7d4 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 14 Mar 2017 12:25:48 +0100 Subject: [PATCH 1/3] gettext: handle GIT_TEXTDOMAINDIR relative to $(prefix) On Windows, there is no single root directory. And what Git thinks is a root directory is not a root directory at all: everything is relative to the location where Git is installed. To handle this situation better, let's just allow for GIT_TEXTDOMAINDIR to be a path relative to the (runtime) prefix. To that end, we have to switch the order in which common-main handles argv0 and sets up gettext: in order to have access to the runtime prefix, we need it to be inferred from argv0 already. This patch also prepares for GIT_LOCALE_PATH to be relative to prefix, which is the even more important fix. Signed-off-by: Johannes Schindelin --- common-main.c | 4 ++-- gettext.c | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/common-main.c b/common-main.c index c654f95551..548da64ab6 100644 --- a/common-main.c +++ b/common-main.c @@ -31,10 +31,10 @@ int main(int argc, const char **argv) */ sanitize_stdfds(); - git_setup_gettext(); - git_extract_argv0_path(argv[0]); + git_setup_gettext(); + restore_sigpipe_to_default(); return cmd_main(argc, argv); diff --git a/gettext.c b/gettext.c index 7d9e2c27ef..edce53a4e3 100644 --- a/gettext.c +++ b/gettext.c @@ -6,6 +6,8 @@ #include "gettext.h" #include "strbuf.h" #include "utf8.h" +#include "cache.h" +#include "exec_cmd.h" #ifndef NO_GETTEXT # include @@ -160,14 +162,20 @@ static void init_gettext_charset(const char *domain) void git_setup_gettext(void) { const char *podir = getenv("GIT_TEXTDOMAINDIR"); + char *p = NULL; if (!podir) podir = GIT_LOCALE_PATH; + if (!is_absolute_path(podir)) + podir = p = system_path(podir); + bindtextdomain("git", podir); setlocale(LC_MESSAGES, ""); setlocale(LC_TIME, ""); init_gettext_charset("git"); textdomain("git"); + + free(p); } /* return the number of columns of string 's' in current locale */ From 0b81bf408c53d606e92fd70344fa50d378964444 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 14 Mar 2017 12:25:48 +0100 Subject: [PATCH 2/3] gettext: use a GIT_LOCALE_PATH relative to $(prefix) On Windows, we simply pass a POSIX path to bindtextdomain(), relying on the current libintl-8.dll implementation to handle that gracefully by resolving the path relative to the "root" directory inferred from the location of the .dll file itself. However, not only does this rely on the custom patches of the gettext library as shipped with MSYS2 (gettext's own source code is not prepared to handle POSIX paths on Windows), it also means that Git itself cannot use the `podir` variable at all because it does not handle absolute POSIX paths in system_path() correctly, leaving them as-is. This patch fixes that behavior by always using a GIT_LOCALE_PATH relative to the (runtime) prefix. Signed-off-by: Johannes Schindelin --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d7c97870c4..a6d9f2854c 100644 --- a/Makefile +++ b/Makefile @@ -445,6 +445,7 @@ lib = lib # DESTDIR = pathsep = : +localedir_relative = $(patsubst $(prefix)/%,%,$(localedir)) mandir_relative = $(patsubst $(prefix)/%,%,$(mandir)) infodir_relative = $(patsubst $(prefix)/%,%,$(infodir)) htmldir_relative = $(patsubst $(prefix)/%,%,$(htmldir)) @@ -1603,6 +1604,7 @@ bindir_relative_SQ = $(subst ','\'',$(bindir_relative)) mandir_relative_SQ = $(subst ','\'',$(mandir_relative)) infodir_relative_SQ = $(subst ','\'',$(infodir_relative)) localedir_SQ = $(subst ','\'',$(localedir)) +localedir_relative_SQ = $(subst ','\'',$(localedir_relative)) gitexecdir_SQ = $(subst ','\'',$(gitexecdir)) template_dir_SQ = $(subst ','\'',$(template_dir)) htmldir_relative_SQ = $(subst ','\'',$(htmldir_relative)) @@ -2039,7 +2041,7 @@ attr.sp attr.s attr.o: EXTRA_CPPFLAGS = \ gettext.sp gettext.s gettext.o: GIT-PREFIX gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \ - -DGIT_LOCALE_PATH='"$(localedir_SQ)"' + -DGIT_LOCALE_PATH='"$(localedir_relative_SQ)"' http-push.sp http.sp http-walker.sp remote-curl.sp imap-send.sp: SPARSE_FLAGS += \ -DCURL_DISABLE_TYPECHECK From b41fd4c3a1099a986b671faf9b671b78a568f74f Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 14 Mar 2017 12:39:54 +0100 Subject: [PATCH 3/3] gettext: avoid initialization if the locale dir is not present The runtime of a simple `git.exe version` call on Windows is currently dominated by the gettext setup, adding a whopping ~150ms to the ~210ms total. Given that this cost is added to each and every git.exe invocation goes through common-main's invocation of git_setup_gettext(), and given that scripts have to call git.exe dozens, if not hundreds, of times, this is a substantial performance penalty. This is particularly pointless when considering that Git for Windows ships without localization (to keep the installer's size to a bearable ~34MB): all that time setting up gettext is for naught. So let's be smart about it and skip setting up gettext if the locale directory is not even present. Signed-off-by: Johannes Schindelin --- gettext.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gettext.c b/gettext.c index edce53a4e3..0a974f9cd1 100644 --- a/gettext.c +++ b/gettext.c @@ -169,11 +169,13 @@ void git_setup_gettext(void) if (!is_absolute_path(podir)) podir = p = system_path(podir); - bindtextdomain("git", podir); - setlocale(LC_MESSAGES, ""); - setlocale(LC_TIME, ""); - init_gettext_charset("git"); - textdomain("git"); + if (is_directory(podir)) { + bindtextdomain("git", podir); + setlocale(LC_MESSAGES, ""); + setlocale(LC_TIME, ""); + init_gettext_charset("git"); + textdomain("git"); + } free(p); }