@matheusbsbs / matheus-bagliano / commits / 224c7d70fa
Fork 0

mingw: only test index entries for backslashes, not tree entries

During a clone of a repository that contained a file with a backslash in its name in the past, as of v2.24.1(2), Git for Windows prints errors like this: error: filename in tree entry contains backslash: '\' The idea is to prevent Git from even trying to write files with backslashes in their file names: while these characters are valid in file names on other platforms, on Windows it is interpreted as directory separator (which would obviously lead to ambiguities, e.g. when there is a file `a\b` and there is also a file `a/b`). Arguably, this is the wrong layer for that error: As long as the user never checks out the files whose names contain backslashes, there should not be any problem in the first place. So let's loosen the requirements: we now leave tree entries with backslashes in their file names alone, but we do require any entries that are added to the Git index to contain no backslashes on Windows. Note: just as before, the check is guarded by `core.protectNTFS` (to allow overriding the check by toggling that config setting), and it is _only_ performed on Windows, as the backslash is not a directory separator elsewhere, even when writing to NTFS-formatted volumes. An alternative approach would be to try to prevent creating files with backslashes in their file names. However, that comes with its own set of problems. For example, `git config -f C:\ProgramData\Git\config ...` is a very valid way to specify a custom config location, and we obviously do _not_ want to prevent that. Therefore, the approach chosen in this patch would appear to be better. This addresses https://github.com/git-for-windows/git/issues/2435 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Dec 31, 2019 at 22:53 UTC 224c7d70fa14ed44d8e7e3ce1e165e05b7b23725
3 files changed +9 -9
read-cache.c
+5
@@ -1278,6 +1278,11 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
1278 int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK;
1279 int new_only = option & ADD_CACHE_NEW_ONLY;
1280
1281 +#ifdef GIT_WINDOWS_NATIVE
1282 + if (protect_ntfs && strchr(ce->name, '\\'))
1283 + return error(_("filename in tree entry contains backslash: '%s'"), ce->name);
1284 +#endif
1285 +
1286 if (!(option & ADD_CACHE_KEEP_CACHE_TREE))
1287 cache_tree_invalidate_path(istate, ce->name);
1288
t/t7415-submodule-names.sh
+4 -3
@@ -207,6 +207,9 @@ test_expect_success MINGW 'prevent git~1 squatting on Windows' '
207 git hash-object -w --stdin)" &&
208 rev="$(git rev-parse --verify HEAD)" &&
209 hash="$(echo x | git hash-object -w --stdin)" &&
210 + test_must_fail git update-index --add \
211 + --cacheinfo 160000,$rev,d\\a 2>err &&
212 + test_i18ngrep backslash err &&
213 git -c core.protectNTFS=false update-index --add \
214 --cacheinfo 100644,$modules,.gitmodules \
215 --cacheinfo 160000,$rev,c \
@@ -214,9 +217,7 @@ test_expect_success MINGW 'prevent git~1 squatting on Windows' '
217 --cacheinfo 100644,$hash,d./a/x \
218 --cacheinfo 100644,$hash,d./a/..git &&
219 test_tick &&
217 - git -c core.protectNTFS=false commit -m "module" &&
218 - test_must_fail git show HEAD: 2>err &&
219 - test_i18ngrep backslash err
220 + git -c core.protectNTFS=false commit -m "module"
221 ) &&
222 test_must_fail git -c core.protectNTFS=false \
223 clone --recurse-submodules squatting squatting-clone 2>err &&
tree-walk.c
-6
@@ -43,12 +43,6 @@ static int decode_tree_entry(struct tree_desc *desc, const char *buf, unsigned l
43 strbuf_addstr(err, _("empty filename in tree entry"));
44 return -1;
45 }
46 -#ifdef GIT_WINDOWS_NATIVE
47 - if (protect_ntfs && strchr(path, '\\')) {
48 - strbuf_addf(err, _("filename in tree entry contains backslash: '%s'"), path);
49 - return -1;
50 - }
51 -#endif
46 len = strlen(path) + 1;
47
48 /* Initialize the descriptor entry */