From 7b13301c03be2e886675ee5dfc09be191678f3b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20A=C3=9Fhauer?= Date: Sat, 26 Mar 2022 09:47:17 +0100 Subject: [PATCH 1/2] set LC_TIME even if locale dir is not present MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since Commit aa1462c (introduce "format" date-mode, 2015-06-25) git log can pass user specified format strings directly to strftime(). One special format string we explicitly mention in our documentation is %c, which depends on the system locale. To accommodate for %c we added a call to setlocale() in git_setup_gettext(). In Commit cc5e1bf (gettext: avoid initialization if the locale dir is not present, 2018-04-21) we added an early exit to git_setup_gettext() in case no textdomain directory is present. This early exit is so early, that we don't even set the locale for %c in that case, despite strftime() not needing the textdomain directory at all. This leads to a subtle bug where `git log --date=format:%c` will use C locale instead of the system locale on systems without a valid textdomain directory. This fixes https://github.com/git-for-windows/git/issues/2959 Helped-by: Ævar Arnfjörð Bjarmason Signed-off-by: Matthias Aßhauer --- gettext.c | 33 ++++++++++++++++++----------- t/t0203-gettext-setlocale-sanity.sh | 10 +++++++++ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/gettext.c b/gettext.c index 8d08a61f8487dc..ef890eff857613 100644 --- a/gettext.c +++ b/gettext.c @@ -102,6 +102,21 @@ static void init_gettext_charset(const char *domain) setlocale(LC_CTYPE, "C"); } +static void git_setup_gettext_no_podir(void) +{ + setlocale(LC_TIME, ""); +} + +static void git_setup_gettext_podir(const char *podir) +{ + bindtextdomain("git", podir); + setlocale(LC_MESSAGES, ""); + init_gettext_charset("git"); + textdomain("git"); + + git_gettext_enabled = 1; +} + int git_gettext_enabled = 0; void git_setup_gettext(void) @@ -109,22 +124,16 @@ void git_setup_gettext(void) const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT); char *p = NULL; + git_setup_gettext_no_podir(); + if (!podir) podir = p = system_path(GIT_LOCALE_PATH); - if (!is_directory(podir)) { - free(p); - return; - } - - bindtextdomain("git", podir); - setlocale(LC_MESSAGES, ""); - setlocale(LC_TIME, ""); - init_gettext_charset("git"); - textdomain("git"); - - git_gettext_enabled = 1; + if (!is_directory(podir)) + goto done; + git_setup_gettext_podir(podir); +done: free(p); } diff --git a/t/t0203-gettext-setlocale-sanity.sh b/t/t0203-gettext-setlocale-sanity.sh index 0ce1f22eff6628..4e54ca0badb5ec 100755 --- a/t/t0203-gettext-setlocale-sanity.sh +++ b/t/t0203-gettext-setlocale-sanity.sh @@ -23,4 +23,14 @@ test_expect_success GETTEXT_LOCALE 'git show a ISO-8859-1 commit under a UTF-8 l grep -q "iso-utf8-commit" out ' +test_expect_success GETTEXT_LOCALE 'the %c date format works even without a localedir (LC_TIME)' ' + LANGUAGE=is LC_ALL="$is_IS_locale" GIT_TEXTDOMAINDIR="$PWD/nonexisting" \ + git log --pretty=format:%ad --date=format:%c HEAD^1..HEAD >actual && + + # Avoid testing the raw format (it might differ?). But + # Thursday is Fimmtudagur in Icelandic, so grepping "fim" is + # pretty certain to test that the locale was used. + grep -iF fim actual +' + test_done From 5f370dc67e5be6def36bbf422d3128bff7f5f5f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20A=C3=9Fhauer?= Date: Mon, 6 Jul 2026 18:47:07 +0200 Subject: [PATCH 2/2] TO DROP: tests should fail --- gettext.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gettext.c b/gettext.c index ef890eff857613..27a3e68e0315eb 100644 --- a/gettext.c +++ b/gettext.c @@ -124,14 +124,13 @@ void git_setup_gettext(void) const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT); char *p = NULL; - git_setup_gettext_no_podir(); - if (!podir) podir = p = system_path(GIT_LOCALE_PATH); if (!is_directory(podir)) goto done; + git_setup_gettext_no_podir(); git_setup_gettext_podir(podir); done: free(p);