Merge branch 'mt/fix-add-rm-with-sparse-index'

Fix-up to a topic already merged to 'master'.

* mt/fix-add-rm-with-sparse-index:
  add, rm, mv: fix bug that prevents the update of non-sparse dirs
This commit is contained in:
Junio C Hamano 2021-10-29 15:43:16 -07:00
Родитель 7b3fd03e6a 20141e322c
Коммит 68fb83b58e
4 изменённых файлов: 96 добавлений и 11 удалений

29
dir.c
Просмотреть файл

@ -1504,8 +1504,9 @@ static int path_in_sparse_checkout_1(const char *path,
struct index_state *istate,
int require_cone_mode)
{
const char *base;
int dtype = DT_REG;
enum pattern_match_result match = UNDECIDED;
const char *end, *slash;
/*
* We default to accepting a path if there are no patterns or
@ -1516,11 +1517,27 @@ static int path_in_sparse_checkout_1(const char *path,
!istate->sparse_checkout_patterns->use_cone_patterns))
return 1;
base = strrchr(path, '/');
return path_matches_pattern_list(path, strlen(path), base ? base + 1 : path,
&dtype,
istate->sparse_checkout_patterns,
istate) > 0;
/*
* If UNDECIDED, use the match from the parent dir (recursively), or
* fall back to NOT_MATCHED at the topmost level. Note that cone mode
* never returns UNDECIDED, so we will execute only one iteration in
* this case.
*/
for (end = path + strlen(path);
end > path && match == UNDECIDED;
end = slash) {
for (slash = end - 1; slash > path && *slash != '/'; slash--)
; /* do nothing */
match = path_matches_pattern_list(path, end - path,
slash > path ? slash + 1 : path, &dtype,
istate->sparse_checkout_patterns, istate);
/* We are going to match the parent dir now */
dtype = DT_DIR;
}
return match > 0;
}
int path_in_sparse_checkout(const char *path,

Просмотреть файл

@ -40,14 +40,20 @@ done
test_expect_success 'recursive rm does not remove sparse entries' '
git reset --hard &&
git sparse-checkout set sub/dir &&
test_must_fail git rm -r sub &&
git rm --sparse -r sub &&
git rm -r sub &&
git status --porcelain -uno >actual &&
cat >expected <<-\EOF &&
D sub/dir/e
EOF
test_cmp expected actual &&
git rm --sparse -r sub &&
git status --porcelain -uno >actual2 &&
cat >expected2 <<-\EOF &&
D sub/d
D sub/dir/e
EOF
test_cmp expected actual
test_cmp expected2 actual2
'
test_expect_success 'recursive rm --sparse removes sparse entries' '
@ -105,4 +111,29 @@ test_expect_success 'refuse to rm a non-skip-worktree path outside sparse cone'
test_path_is_missing b
'
test_expect_success 'can remove files from non-sparse dir' '
git reset --hard &&
git sparse-checkout disable &&
mkdir -p w x/y &&
test_commit w/f &&
test_commit x/y/f &&
git sparse-checkout set w !/x y/ &&
git rm w/f.t x/y/f.t 2>stderr &&
test_must_be_empty stderr
'
test_expect_success 'refuse to remove non-skip-worktree file from sparse dir' '
git reset --hard &&
git sparse-checkout disable &&
mkdir -p x/y/z &&
test_commit x/y/z/f &&
git sparse-checkout set !/x y/ !x/y/z &&
git update-index --no-skip-worktree x/y/z/f.t &&
test_must_fail git rm x/y/z/f.t 2>stderr &&
echo x/y/z/f.t | cat sparse_error_header - sparse_hint >expect &&
test_cmp expect stderr
'
test_done

Просмотреть файл

@ -214,4 +214,21 @@ test_expect_success 'add allows sparse entries with --sparse' '
test_must_be_empty stderr
'
test_expect_success 'can add files from non-sparse dir' '
git sparse-checkout set w !/x y/ &&
mkdir -p w x/y &&
touch w/f x/y/f &&
git add w/f x/y/f 2>stderr &&
test_must_be_empty stderr
'
test_expect_success 'refuse to add non-skip-worktree file from sparse dir' '
git sparse-checkout set !/x y/ !x/y/z &&
mkdir -p x/y/z &&
touch x/y/z/f &&
test_must_fail git add x/y/z/f 2>stderr &&
echo x/y/z/f | cat sparse_error_header - sparse_hint >expect &&
test_cmp expect stderr
'
test_done

Просмотреть файл

@ -143,8 +143,6 @@ test_expect_success 'recursive mv refuses to move (possible) sparse' '
cat >>expect <<-\EOF &&
sub/d
sub2/d
sub/dir/e
sub2/dir/e
sub/dir2/e
sub2/dir2/e
EOF
@ -186,4 +184,26 @@ test_expect_success 'recursive mv refuses to move sparse' '
git reset --hard HEAD~1
'
test_expect_success 'can move files to non-sparse dir' '
git reset --hard &&
git sparse-checkout init --no-cone &&
git sparse-checkout set a b c w !/x y/ &&
mkdir -p w x/y &&
git mv a w/new-a 2>stderr &&
git mv b x/y/new-b 2>stderr &&
test_must_be_empty stderr
'
test_expect_success 'refuse to move file to non-skip-worktree sparse path' '
git reset --hard &&
git sparse-checkout init --no-cone &&
git sparse-checkout set a !/x y/ !x/y/z &&
mkdir -p x/y/z &&
test_must_fail git mv a x/y/z/new-a 2>stderr &&
echo x/y/z/new-a | cat sparse_error_header - sparse_hint >expect &&
test_cmp expect stderr
'
test_done