Skip to content

Commit 056ccdc

Browse files
committed
set LC_TIME even if locale dir is not present
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 git-for-windows#2959 Signed-off-by: Matthias Aßhauer <mha1993@live.de>
1 parent abf474a commit 056ccdc

3 files changed

Lines changed: 40 additions & 1 deletion

File tree

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,10 @@ include shared.mak
410410
# If it isn't set, fallback to $LC_ALL, $LANG or use the first utf-8
411411
# locale returned by "locale -a".
412412
#
413+
# Define GIT_TEST_TIME_LOCALE to preferred non-us locale for testing.
414+
# If it isn't set, fallback to $LC_ALL, $LANG or use the first non-us
415+
# locale returned by "locale -a".
416+
#
413417
# Define HAVE_CLOCK_GETTIME if your platform has clock_gettime.
414418
#
415419
# Define HAVE_CLOCK_MONOTONIC if your platform has CLOCK_MONOTONIC.
@@ -2862,6 +2866,9 @@ ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT
28622866
endif
28632867
ifdef GIT_TEST_UTF8_LOCALE
28642868
@echo GIT_TEST_UTF8_LOCALE=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_UTF8_LOCALE)))'\' >>$@+
2869+
endif
2870+
ifdef GIT_TEST_TIME_LOCALE
2871+
@echo GIT_TEST_TIME_LOCALE=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_TIME_LOCALE)))'\' >>$@+
28652872
endif
28662873
@echo NO_GETTEXT=\''$(subst ','\'',$(subst ','\'',$(NO_GETTEXT)))'\' >>$@+
28672874
ifdef GIT_PERF_REPEAT_COUNT

gettext.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ void git_setup_gettext(void)
107107
const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT);
108108
char *p = NULL;
109109

110+
setlocale(LC_TIME, "");
111+
110112
if (!podir)
111113
podir = p = system_path(GIT_LOCALE_PATH);
112114

@@ -117,7 +119,6 @@ void git_setup_gettext(void)
117119

118120
bindtextdomain("git", podir);
119121
setlocale(LC_MESSAGES, "");
120-
setlocale(LC_TIME, "");
121122
init_gettext_charset("git");
122123
textdomain("git");
123124

t/t4205-log-pretty-formats.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,29 @@ commit_msg () {
2525
fi
2626
}
2727

28+
prepare_time_locale () {
29+
if test -z "$GIT_TEST_TIME_LOCALE"
30+
then
31+
case "${LC_ALL:-$LANG}" in
32+
C | C.* | POSIX | POSIX.* | en_US | en_US.* )
33+
GIT_TEST_TIME_LOCALE=$(locale -a | sed -n '/^\(C\|POSIX\|en_US\)/I !{
34+
p
35+
q
36+
}')
37+
;;
38+
*)
39+
GIT_TEST_TIME_LOCALE="${LC_ALL:-$LANG}"
40+
;;
41+
esac
42+
fi
43+
if test -n "$GIT_TEST_TIME_LOCALE"
44+
then
45+
test_set_prereq TIME_LOCALE
46+
else
47+
say "# No non-us locale available, some tests are skipped"
48+
fi
49+
}
50+
2851
test_expect_success 'set up basic repos' '
2952
>foo &&
3053
>bar &&
@@ -544,6 +567,14 @@ test_expect_success '--date=human %ad%cd is the same as %ah%ch' '
544567
test_cmp expected actual
545568
'
546569

570+
prepare_time_locale
571+
test_expect_success TIME_LOCALE '--date=format:%c does not need gettext' '
572+
rm -fr no-such-dir &&
573+
LC_ALL=$GIT_TEST_TIME_LOCALE git log --date=format:%c HEAD^1..HEAD >expected &&
574+
GIT_TEXTDOMAINDIR=no-such-dir LC_ALL=$GIT_TEST_TIME_LOCALE git log --date=format:%c HEAD^1..HEAD >actual &&
575+
test_cmp expected actual
576+
'
577+
547578
# get new digests (with no abbreviations)
548579
test_expect_success 'set up log decoration tests' '
549580
head1=$(git rev-parse --verify HEAD~0) &&

0 commit comments

Comments
 (0)