summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xt/t1011-read-tree-sparse-checkout.sh12
-rw-r--r--unpack-trees.c26
2 files changed, 24 insertions, 14 deletions
diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh
index 9189de8461..81ab4c6f37 100755
--- a/t/t1011-read-tree-sparse-checkout.sh
+++ b/t/t1011-read-tree-sparse-checkout.sh
@@ -155,4 +155,16 @@ test_expect_success 'read-tree adds to worktree, dirty case' '
grep -q dirty sub/added
'
+test_expect_success 'index removal and worktree narrowing at the same time' '
+ >empty &&
+ echo init.t >.git/info/sparse-checkout &&
+ echo sub/added >>.git/info/sparse-checkout &&
+ git checkout -f top &&
+ echo init.t >.git/info/sparse-checkout &&
+ git checkout removed &&
+ git ls-files sub/added >result &&
+ test ! -f sub/added &&
+ test_cmp empty result
+'
+
test_done
diff --git a/unpack-trees.c b/unpack-trees.c
index 75f54cac97..ae5e6bff52 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -164,13 +164,18 @@ static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_opt
ce->ce_flags &= ~CE_SKIP_WORKTREE;
/*
- * We only care about files getting into the checkout area
- * If merge strategies want to remove some, go ahead, this
- * flag will be removed eventually in unpack_trees() if it's
- * outside checkout area.
+ * if (!was_skip_worktree && !ce_skip_worktree()) {
+ * This is perfectly normal. Move on;
+ * }
*/
- if (ce->ce_flags & CE_REMOVE)
- return 0;
+
+ /*
+ * Merge strategies may set CE_UPDATE|CE_REMOVE outside checkout
+ * area as a result of ce_skip_worktree() shortcuts in
+ * verify_absent() and verify_uptodate(). Clear them.
+ */
+ if (was_skip_worktree && ce_skip_worktree(ce))
+ ce->ce_flags &= ~(CE_UPDATE | CE_REMOVE);
if (!was_skip_worktree && ce_skip_worktree(ce)) {
/*
@@ -796,14 +801,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
ret = -1;
goto done;
}
- /*
- * Merge strategies may set CE_UPDATE|CE_REMOVE outside checkout
- * area as a result of ce_skip_worktree() shortcuts in
- * verify_absent() and verify_uptodate(). Clear them.
- */
- if (ce_skip_worktree(ce))
- ce->ce_flags &= ~(CE_UPDATE | CE_REMOVE);
- else
+ if (!ce_skip_worktree(ce))
empty_worktree = 0;
}