Skip to content

Commit eec3fc0

Browse files
pcloudsgitster
authored andcommitted
unpack-trees: only clear CE_UPDATE|CE_REMOVE when skip-worktree is always set
The purpose of this clearing is, as explained in comment, because verify_*() may set those bits before apply_sparse_checkout() is called. By that time, it's not clear whether an entry will stay in checkout area or out. After $GIT_DIR/info/sparse-checkout is applied, we know what entries will be in finally. It's time to clean unwanted bits. That works perfectly when checkout area remains unchanged. When checkout area changes, apply_sparse_checkout() may set CE_UPDATE or CE_WT_REMOVE to widen/narrow checkout area. Doing the clearing after apply_sparse_checkout() may clear those widening/narrowing bits unexpectedly. So, only do that on entries that are not affected by checkout area changes (i.e. skip-worktree bit does not change after apply_sparse_checkout). This code does not actually fix anything though, just future-proof. The removed code and the narrow/widen code inside apply_sparse_checkout are currently independent (narrow code never sets CE_REMOVE, widen code sets CE_UPDATE, but ce_skip_worktree() would be false). Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Reviewed-by: Jonathan Nieder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7f71a6a commit eec3fc0

File tree

2 files changed

+24
-14
lines changed

2 files changed

+24
-14
lines changed

t/t1011-read-tree-sparse-checkout.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,16 @@ test_expect_success 'read-tree adds to worktree, dirty case' '
155155
grep -q dirty sub/added
156156
'
157157

158+
test_expect_success 'index removal and worktree narrowing at the same time' '
159+
>empty &&
160+
echo init.t >.git/info/sparse-checkout &&
161+
echo sub/added >>.git/info/sparse-checkout &&
162+
git checkout -f top &&
163+
echo init.t >.git/info/sparse-checkout &&
164+
git checkout removed &&
165+
git ls-files sub/added >result &&
166+
test ! -f sub/added &&
167+
test_cmp empty result
168+
'
169+
158170
test_done

unpack-trees.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,18 @@ static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_opt
164164
ce->ce_flags &= ~CE_SKIP_WORKTREE;
165165

166166
/*
167-
* We only care about files getting into the checkout area
168-
* If merge strategies want to remove some, go ahead, this
169-
* flag will be removed eventually in unpack_trees() if it's
170-
* outside checkout area.
167+
* if (!was_skip_worktree && !ce_skip_worktree()) {
168+
* This is perfectly normal. Move on;
169+
* }
171170
*/
172-
if (ce->ce_flags & CE_REMOVE)
173-
return 0;
171+
172+
/*
173+
* Merge strategies may set CE_UPDATE|CE_REMOVE outside checkout
174+
* area as a result of ce_skip_worktree() shortcuts in
175+
* verify_absent() and verify_uptodate(). Clear them.
176+
*/
177+
if (was_skip_worktree && ce_skip_worktree(ce))
178+
ce->ce_flags &= ~(CE_UPDATE | CE_REMOVE);
174179

175180
if (!was_skip_worktree && ce_skip_worktree(ce)) {
176181
/*
@@ -796,14 +801,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
796801
ret = -1;
797802
goto done;
798803
}
799-
/*
800-
* Merge strategies may set CE_UPDATE|CE_REMOVE outside checkout
801-
* area as a result of ce_skip_worktree() shortcuts in
802-
* verify_absent() and verify_uptodate(). Clear them.
803-
*/
804-
if (ce_skip_worktree(ce))
805-
ce->ce_flags &= ~(CE_UPDATE | CE_REMOVE);
806-
else
804+
if (!ce_skip_worktree(ce))
807805
empty_worktree = 0;
808806

809807
}

0 commit comments

Comments
 (0)