On 1/30/2020 1:52 PM, Derrick Stolee wrote: > On 1/30/2020 10:25 AM, Finn Bryant wrote: >> $ git sparse-checkout init --cone >> $ git read-tree -mu HEAD >> $ ls -1 >> a_file_or_folder >> some_file >> $ git sparse-checkout set a_file_or_folder >> $ git read-tree -mu HEAD >> $ ls -1 >> some_file >> $ cat .git/info/sparse-checkout >> /* >> !/*/ >> /a_file_or_folder/ > > This is an interesting test, because I would expect the /a_file_or_folder/ > pattern to not cause the _file_ to not match. It does match the first two > patterns, and just because it doesn't match the third pattern shouldn't > remove it. > > This is actually a bug in the hashset-based pattern-matching algorithm, > since setting core.sparseCheckoutCone=false does not have this behavior. > I'll make a patch to fix this. And here is a patch. I'll add this on top of my "Harden the sparse-checkout builtin" series in its v4. -->8-- >From bf2115670e8ef79844ec7e87f3ba99d1f776a44d Mon Sep 17 00:00:00 2001 From: Derrick Stolee <dstolee@xxxxxxxxxxxxx> Date: Thu, 30 Jan 2020 19:11:26 +0000 Subject: [PATCH] sparse-checkout: fix cone mode behavior mismatch The intention of the special "cone mode" in the sparse-checkout feature is to always match the same patterns that are matched by the same sparse-checkout file as when cone mode is disabled. When a file path is given to "git sparse-checkout set" in cone mode, then the cone mode improperly matches the file as a recursive path. When setting the skip-worktree bits, files were not expecting the MATCHED_RECURSIVE response, and hence these were left out of the matched cone. Fix this bug by checking for MATCHED_RECURSIVE in addition to MATCHED and add a test that prevents regression. Reported-by: Finn Bryant <finnbryant@xxxxxxxxx> Signed-off-by: Derrick Stolee <dstolee@xxxxxxxxxxxxx> --- t/t1091-sparse-checkout-builtin.sh | 12 ++++++++++++ unpack-trees.c | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index 37e9304ef3..7d982096fb 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -305,6 +305,18 @@ test_expect_success 'different sparse-checkouts with worktrees' ' check_files worktree a deep ' +test_expect_success 'set using filename keeps file on-disk' ' + git -C repo sparse-checkout set a deep && + cat >expect <<-\EOF && + /* + !/*/ + /a/ + /deep/ + EOF + test_cmp expect repo/.git/info/sparse-checkout && + check_files repo a deep +' + check_read_tree_errors () { REPO=$1 FILES=$2 diff --git a/unpack-trees.c b/unpack-trees.c index 3789a22cf0..78425ce74b 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1416,7 +1416,7 @@ static int clear_ce_flags_1(struct index_state *istate, name, &dtype, pl, istate); if (ret == UNDECIDED) ret = default_match; - if (ret == MATCHED) + if (ret == MATCHED || ret == MATCHED_RECURSIVE) ce->ce_flags &= ~clear_mask; cache++; progress_nr++; -- 2.25.0.vfs.1.1