aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerrick Stolee <dstolee@microsoft.com>2020-01-24 21:19:36 +0000
committerJunio C Hamano <gitster@pobox.com>2020-01-24 13:26:54 -0800
commit41de0c6fbcc3d2544ebada3a9f26dec0f32f42de (patch)
tree3b9147a8baec6ddb105d107bd9b1000da70e1abe
parent7aa9ef2fcaa986d7f11064adab6d1c010d4f2ead (diff)
downloadgit-41de0c6fbcc3d2544ebada3a9f26dec0f32f42de.tar.xz
sparse-checkout: cone mode does not recognize "**"
When core.sparseCheckoutCone is enabled, the 'git sparse-checkout set' command creates a restricted set of possible patterns that are used by a custom algorithm to quickly match those patterns. If a user manually edits the sparse-checkout file, then they could create patterns that do not match these expectations. The cone-mode matching algorithm can return incorrect results. The solution is to detect these incorrect patterns, warn that we do not recognize them, and revert to the standard algorithm. Check each pattern for the "**" substring, and revert to the old logic if seen. While technically a "/<dir>/**" pattern matches the meaning of "/<dir>/", it is not one that would be written by the sparse-checkout builtin in cone mode. Attempting to accept that pattern change complicates the logic and instead we punt and do not accept any instance of "**". Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--dir.c7
-rwxr-xr-xt/t1091-sparse-checkout-builtin.sh34
2 files changed, 40 insertions, 1 deletions
diff --git a/dir.c b/dir.c
index 22d08e61c2..40fed73a94 100644
--- a/dir.c
+++ b/dir.c
@@ -651,11 +651,16 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern
return;
}
+ if (strstr(given->pattern, "**")) {
+ /* Not a cone pattern. */
+ warning(_("unrecognized pattern: '%s'"), given->pattern);
+ goto clear_hashmaps;
+ }
+
if (given->patternlen > 2 &&
!strcmp(given->pattern + given->patternlen - 2, "/*")) {
if (!(given->flags & PATTERN_FLAG_NEGATIVE)) {
/* Not a cone pattern. */
- pl->use_cone_patterns = 0;
warning(_("unrecognized pattern: '%s'"), given->pattern);
goto clear_hashmaps;
}
diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh
index cf4a595c86..e2e45dc7fd 100755
--- a/t/t1091-sparse-checkout-builtin.sh
+++ b/t/t1091-sparse-checkout-builtin.sh
@@ -305,4 +305,38 @@ test_expect_success 'different sparse-checkouts with worktrees' '
check_files worktree a deep
'
+check_read_tree_errors () {
+ REPO=$1
+ FILES=$2
+ ERRORS=$3
+ git -C $REPO read-tree -mu HEAD 2>err &&
+ if test -z "$ERRORS"
+ then
+ test_must_be_empty err
+ else
+ test_i18ngrep "$ERRORS" err
+ fi &&
+ check_files $REPO $FILES
+}
+
+test_expect_success 'pattern-checks: /A/**' '
+ cat >repo/.git/info/sparse-checkout <<-\EOF &&
+ /*
+ !/*/
+ /folder1/**
+ EOF
+ check_read_tree_errors repo "a folder1" "disabling cone pattern matching"
+'
+
+test_expect_success 'pattern-checks: /A/**/B/' '
+ cat >repo/.git/info/sparse-checkout <<-\EOF &&
+ /*
+ !/*/
+ /deep/**/deepest
+ EOF
+ check_read_tree_errors repo "a deep" "disabling cone pattern matching" &&
+ check_files repo/deep "deeper1" &&
+ check_files repo/deep/deeper1 "deepest"
+'
+
test_done