From fc5e90b848e07cc3b8b0e590dbd261ee1b40ffb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Thu, 7 Oct 2021 22:31:01 +0200 Subject: [PATCH 1/3] t3905: show failure to ignore sub-repo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "git stash" used to ignore sub-repositories until 6e773527b6 (sparse-index: convert from full to sparse, 2021-03-30). Add a test that demonstrates this regression. Reported-by: Robert Leftwich Signed-off-by: René Scharfe Signed-off-by: Junio C Hamano --- t/t3905-stash-include-untracked.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh index 8314ab21d43..f213c7327e0 100755 --- a/t/t3905-stash-include-untracked.sh +++ b/t/t3905-stash-include-untracked.sh @@ -405,4 +405,10 @@ test_expect_success 'stash show --include-untracked errors on duplicate files' ' test_i18ngrep "worktree and untracked commit have duplicate entries: tracked" err ' +test_expect_failure 'stash -u ignores sub-repository' ' + test_when_finished "rm -rf sub-repo" && + git init sub-repo && + git stash -u +' + test_done From 2a1ae649a4c485b833d75cd5bb14b53ff9bae2c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Thu, 7 Oct 2021 22:31:44 +0200 Subject: [PATCH 2/3] read-cache: add verify_path_internal() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turn verify_path() into an internal function that distinguishes between valid paths and those with trailing directory separators and rename it to verify_path_internal(). Provide a wrapper with the old behavior under the old name. No functional change intended. The new function will be used in the next patch. Suggested-by: Junio C Hamano Signed-off-by: René Scharfe Signed-off-by: Junio C Hamano --- read-cache.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/read-cache.c b/read-cache.c index 72a1d339c97..c823580fb07 100644 --- a/read-cache.c +++ b/read-cache.c @@ -844,6 +844,19 @@ struct cache_entry *make_empty_transient_cache_entry(size_t len) return xcalloc(1, cache_entry_size(len)); } +enum verify_path_result { + PATH_OK, + PATH_INVALID, + PATH_DIR_WITH_SEP, +}; + +static enum verify_path_result verify_path_internal(const char *, unsigned); + +int verify_path(const char *path, unsigned mode) +{ + return verify_path_internal(path, mode) != PATH_INVALID; +} + struct cache_entry *make_cache_entry(struct index_state *istate, unsigned int mode, const struct object_id *oid, @@ -985,60 +998,62 @@ static int verify_dotfile(const char *rest, unsigned mode) return 1; } -int verify_path(const char *path, unsigned mode) +static enum verify_path_result verify_path_internal(const char *path, + unsigned mode) { char c = 0; if (has_dos_drive_prefix(path)) - return 0; + return PATH_INVALID; if (!is_valid_path(path)) - return 0; + return PATH_INVALID; goto inside; for (;;) { if (!c) - return 1; + return PATH_OK; if (is_dir_sep(c)) { inside: if (protect_hfs) { if (is_hfs_dotgit(path)) - return 0; + return PATH_INVALID; if (S_ISLNK(mode)) { if (is_hfs_dotgitmodules(path)) - return 0; + return PATH_INVALID; } } if (protect_ntfs) { #ifdef GIT_WINDOWS_NATIVE if (c == '\\') - return 0; + return PATH_INVALID; #endif if (is_ntfs_dotgit(path)) - return 0; + return PATH_INVALID; if (S_ISLNK(mode)) { if (is_ntfs_dotgitmodules(path)) - return 0; + return PATH_INVALID; } } c = *path++; if ((c == '.' && !verify_dotfile(path, mode)) || is_dir_sep(c)) - return 0; + return PATH_INVALID; /* * allow terminating directory separators for * sparse directory entries. */ if (c == '\0') - return S_ISDIR(mode); + return S_ISDIR(mode) ? PATH_DIR_WITH_SEP : + PATH_INVALID; } else if (c == '\\' && protect_ntfs) { if (is_ntfs_dotgit(path)) - return 0; + return PATH_INVALID; if (S_ISLNK(mode)) { if (is_ntfs_dotgitmodules(path)) - return 0; + return PATH_INVALID; } } From c8ad9d04c6a51cb5c73ebc9e42b627314eeafe2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Thu, 7 Oct 2021 22:31:58 +0200 Subject: [PATCH 3/3] read-cache: let verify_path() reject trailing dir separators again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 6e773527b6 (sparse-index: convert from full to sparse, 2021-03-30) made verify_path() accept trailing directory separators for directories, which is necessary for sparse directory entries. This clemency causes "git stash" to stumble over sub-repositories, though, and there may be more unintended side-effects. Avoid them by restoring the old verify_path() behavior and accepting trailing directory separators only in places that are supposed to handle sparse directory entries. Signed-off-by: René Scharfe Signed-off-by: Junio C Hamano --- read-cache.c | 6 +++--- t/t3905-stash-include-untracked.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/read-cache.c b/read-cache.c index c823580fb07..42d804f9623 100644 --- a/read-cache.c +++ b/read-cache.c @@ -854,7 +854,7 @@ static enum verify_path_result verify_path_internal(const char *, unsigned); int verify_path(const char *path, unsigned mode) { - return verify_path_internal(path, mode) != PATH_INVALID; + return verify_path_internal(path, mode) == PATH_OK; } struct cache_entry *make_cache_entry(struct index_state *istate, @@ -867,7 +867,7 @@ struct cache_entry *make_cache_entry(struct index_state *istate, struct cache_entry *ce, *ret; int len; - if (!verify_path(path, mode)) { + if (verify_path_internal(path, mode) == PATH_INVALID) { error(_("invalid path '%s'"), path); return NULL; } @@ -1356,7 +1356,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e if (!ok_to_add) return -1; - if (!verify_path(ce->name, ce->ce_mode)) + if (verify_path_internal(ce->name, ce->ce_mode) == PATH_INVALID) return error(_("invalid path '%s'"), ce->name); if (!skip_df_check && diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh index f213c7327e0..c59bcffabbb 100755 --- a/t/t3905-stash-include-untracked.sh +++ b/t/t3905-stash-include-untracked.sh @@ -405,7 +405,7 @@ test_expect_success 'stash show --include-untracked errors on duplicate files' ' test_i18ngrep "worktree and untracked commit have duplicate entries: tracked" err ' -test_expect_failure 'stash -u ignores sub-repository' ' +test_expect_success 'stash -u ignores sub-repository' ' test_when_finished "rm -rf sub-repo" && git init sub-repo && git stash -u