Skip to content

Commit 7d78241

Browse files
dturner-twgitster
authored andcommitted
unpack-trees: don't update files with CE_WT_REMOVE set
Don't update files in the worktree from cache entries which are flagged with CE_WT_REMOVE. When a user does a sparse checkout, git removes files that are marked with CE_WT_REMOVE (because they are out-of-scope for the sparse checkout). If those files are also marked CE_UPDATE (for instance, because they differ in the branch that is being checked out and the outgoing branch), git would previously recreate them. This patch prevents them from being recreated. These erroneously-created files would also interfere with merges, causing pre-merge revisions of out-of-scope files to appear in the worktree. apply_sparse_checkout() is the function where all "action" manipulation (add, delete, update files..) for sparse checkout occurs; it should not ask to delete and update both at the same time. Signed-off-by: Anatole Shaw <[email protected]> Signed-off-by: David Turner <[email protected]> Helped-by: Duy Nguyen <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 282616c commit 7d78241

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

t/t1090-sparse-checkout-scope.sh

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/bin/sh
2+
3+
test_description='sparse checkout scope tests'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success 'setup' '
8+
echo "initial" >a &&
9+
echo "initial" >b &&
10+
echo "initial" >c &&
11+
git add a b c &&
12+
git commit -m "initial commit"
13+
'
14+
15+
test_expect_success 'create feature branch' '
16+
git checkout -b feature &&
17+
echo "modified" >b &&
18+
echo "modified" >c &&
19+
git add b c &&
20+
git commit -m "modification"
21+
'
22+
23+
test_expect_success 'perform sparse checkout of master' '
24+
git config --local --bool core.sparsecheckout true &&
25+
echo "!/*" >.git/info/sparse-checkout &&
26+
echo "/a" >>.git/info/sparse-checkout &&
27+
echo "/c" >>.git/info/sparse-checkout &&
28+
git checkout master &&
29+
test_path_is_file a &&
30+
test_path_is_missing b &&
31+
test_path_is_file c
32+
'
33+
34+
test_expect_success 'merge feature branch into sparse checkout of master' '
35+
git merge feature &&
36+
test_path_is_file a &&
37+
test_path_is_missing b &&
38+
test_path_is_file c &&
39+
test "$(cat c)" = "modified"
40+
'
41+
42+
test_expect_success 'return to full checkout of master' '
43+
git checkout feature &&
44+
echo "/*" >.git/info/sparse-checkout &&
45+
git checkout master &&
46+
test_path_is_file a &&
47+
test_path_is_file b &&
48+
test_path_is_file c &&
49+
test "$(cat b)" = "modified"
50+
'
51+
52+
test_done

unpack-trees.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ static int check_updates(struct unpack_trees_options *o)
227227
struct cache_entry *ce = index->cache[i];
228228

229229
if (ce->ce_flags & CE_UPDATE) {
230+
if (ce->ce_flags & CE_WT_REMOVE)
231+
die("BUG: both update and delete flags are set on %s",
232+
ce->name);
230233
display_progress(progress, ++cnt);
231234
ce->ce_flags &= ~CE_UPDATE;
232235
if (o->update && !o->dry_run) {
@@ -290,6 +293,7 @@ static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_opt
290293
if (!(ce->ce_flags & CE_UPDATE) && verify_uptodate_sparse(ce, o))
291294
return -1;
292295
ce->ce_flags |= CE_WT_REMOVE;
296+
ce->ce_flags &= ~CE_UPDATE;
293297
}
294298
if (was_skip_worktree && !ce_skip_worktree(ce)) {
295299
if (verify_absent_sparse(ce, ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o))

0 commit comments

Comments
 (0)