Skip to content

Commit 2b4c6ef

Browse files
dschogitster
authored andcommitted
read-cache: optionally disallow NTFS .git variants
The point of disallowing ".git" in the index is that we would never want to accidentally overwrite files in the repository directory. But this means we need to respect the filesystem's idea of when two paths are equal. The prior commit added a helper to make such a comparison for NTFS and FAT32; let's use it in verify_path(). We make this check optional for two reasons: 1. It restricts the set of allowable filenames, which is unnecessary for people who are not on NTFS nor FAT32. In practice this probably doesn't matter, though, as the restricted names are rather obscure and almost certainly would never come up in practice. 2. It has a minor performance penalty for every path we insert into the index. This patch ties the check to the core.protectNTFS config option. Though this is expected to be most useful on Windows, we allow it to be set everywhere, as NTFS may be mounted on other platforms. The variable does default to on for Windows, though. Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1d1d69b commit 2b4c6ef

File tree

7 files changed

+34
-0
lines changed

7 files changed

+34
-0
lines changed

Documentation/config.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,12 @@ core.protectHFS::
239239
be considered equivalent to `.git` on an HFS+ filesystem.
240240
Defaults to `true` on Mac OS, and `false` elsewhere.
241241

242+
core.protectNTFS::
243+
If set to true, do not allow checkout of paths that would
244+
cause problems with the NTFS filesystem, e.g. conflict with
245+
8.3 "short" names.
246+
Defaults to `true` on Windows, and `false` elsewhere.
247+
242248
core.trustctime::
243249
If false, the ctime differences between the index and the
244250
working tree are ignored; useful when the inode change time

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ extern int core_preload_index;
585585
extern int core_apply_sparse_checkout;
586586
extern int precomposed_unicode;
587587
extern int protect_hfs;
588+
extern int protect_ntfs;
588589

589590
/*
590591
* The character that begins a commented line in user-editable file

config.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,11 @@ static int git_default_core_config(const char *var, const char *value)
886886
return 0;
887887
}
888888

889+
if (!strcmp(var, "core.protectntfs")) {
890+
protect_ntfs = git_config_bool(var, value);
891+
return 0;
892+
}
893+
889894
/* Add other config variables here and to Documentation/config.txt. */
890895
return 0;
891896
}

config.mak.uname

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ ifeq ($(uname_S),Windows)
362362
EXTLIBS = user32.lib advapi32.lib shell32.lib wininet.lib ws2_32.lib
363363
PTHREAD_LIBS =
364364
lib =
365+
BASIC_CFLAGS += -DPROTECT_NTFS_DEFAULT=1
365366
ifndef DEBUG
366367
BASIC_CFLAGS += -GL -Os -MT
367368
BASIC_LDFLAGS += -LTCG
@@ -506,6 +507,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
506507
COMPAT_OBJS += compat/mingw.o compat/winansi.o \
507508
compat/win32/pthread.o compat/win32/syslog.o \
508509
compat/win32/dirent.o
510+
BASIC_CFLAGS += -DPROTECT_NTFS_DEFAULT=1
509511
BASIC_LDFLAGS += -Wl,--large-address-aware
510512
EXTLIBS += -lws2_32
511513
GITLIBS += git.res

environment.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ unsigned long pack_size_limit_cfg;
6868
#endif
6969
int protect_hfs = PROTECT_HFS_DEFAULT;
7070

71+
#ifndef PROTECT_NTFS_DEFAULT
72+
#define PROTECT_NTFS_DEFAULT 0
73+
#endif
74+
int protect_ntfs = PROTECT_NTFS_DEFAULT;
75+
7176
/*
7277
* The character that begins a commented line in user-editable file
7378
* that is subject to stripspace.

read-cache.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,8 @@ int verify_path(const char *path)
789789
inside:
790790
if (protect_hfs && is_hfs_dotgit(path))
791791
return 0;
792+
if (protect_ntfs && is_ntfs_dotgit(path))
793+
return 0;
792794
c = *path++;
793795
if ((c == '.' && !verify_dotfile(path)) ||
794796
is_dir_sep(c) || c == '\0')

t/t1014-read-tree-confusing.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,17 @@ test_expect_success 'enable core.protectHFS for rejection tests' '
1515
git config core.protectHFS true
1616
'
1717

18+
test_expect_success 'enable core.protectNTFS for rejection tests' '
19+
git config core.protectNTFS true
20+
'
21+
1822
while read path pretty; do
1923
: ${pretty:=$path}
24+
case "$path" in
25+
*SPACE)
26+
path="${path%SPACE} "
27+
;;
28+
esac
2029
test_expect_success "reject $pretty at end of path" '
2130
printf "100644 blob %s\t%s" "$blob" "$path" >tree &&
2231
bogus=$(git mktree <tree) &&
@@ -36,6 +45,10 @@ done <<-EOF
3645
${u200c}.Git {u200c}.Git
3746
.gI${u200c}T .gI{u200c}T
3847
.GiT${u200c} .GiT{u200c}
48+
git~1
49+
.git.SPACE .git.{space}
50+
.\\\\.GIT\\\\foobar backslashes
51+
.git\\\\foobar backslashes2
3952
EOF
4053

4154
test_expect_success 'utf-8 paths allowed with core.protectHFS off' '

0 commit comments

Comments
 (0)