@matheusbsbs / matheus-bagliano / commits / eec3fc0309
Fork 0

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 <pclouds@gmail.com> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Jul 31, 2010 at 13:14 UTC eec3fc03092e308694d56b875a858065730822e2
2 files changed +24 -14
t/t1011-read-tree-sparse-checkout.sh
+12
@@ -155,4 +155,16 @@ test_expect_success 'read-tree adds to worktree, dirty case' '
155 grep -q dirty sub/added
156 '
157
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 +
170 test_done
unpack-trees.c
+12 -14
@@ -164,13 +164,18 @@ static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_opt
164 ce->ce_flags &= ~CE_SKIP_WORKTREE;
165
166 /*
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 + * }
170 */
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);
179
180 if (!was_skip_worktree && ce_skip_worktree(ce)) {
181 /*
@@ -796,14 +801,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
801 ret = -1;
802 goto done;
803 }
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))
805 empty_worktree = 0;
806
807 }