From: Derrick Stolee Date: Mon, 4 May 2020 18:27:43 +0000 (+0000) Subject: sparse-checkout: stop blocking empty workdirs X-Git-Tag: v2.27.0-rc0~31^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ace224ac5fb120e9cae894e31713ab60e91f141f;p=thirdparty%2Fgit.git sparse-checkout: stop blocking empty workdirs Remove the error condition when updating the sparse-checkout leaves an empty working directory. This behavior was added in 9e1afb167 (sparse checkout: inhibit empty worktree, 2009-08-20). The comment was added in a7bc906f2 (Add explanation why we do not allow to sparse checkout to empty working tree, 2011-09-22) in response to a "dubious" comment in 84563a624 (unpack-trees.c: cosmetic fix, 2010-12-22). With the recent "cone mode" and "git sparse-checkout init [--cone]" command, it is common to set a reasonable sparse-checkout pattern set of /* !/*/ which matches only files at root. If the repository has no such files, then their "git sparse-checkout init" command will fail. Now that we expect this to be a common pattern, we should not have the commands fail on an empty working directory. If it is a confusing result, then the user can recover with "git sparse-checkout disable" or "git sparse-checkout set". This is especially simple when using cone mode. Reported-by: Lars Schneider Signed-off-by: Derrick Stolee Signed-off-by: Junio C Hamano --- diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh index 63223e13bd..140f459977 100755 --- a/t/t1011-read-tree-sparse-checkout.sh +++ b/t/t1011-read-tree-sparse-checkout.sh @@ -74,13 +74,19 @@ test_expect_success 'read-tree --no-sparse-checkout with empty .git/info/sparse- test_expect_success 'read-tree with empty .git/info/sparse-checkout' ' git config core.sparsecheckout true && echo >.git/info/sparse-checkout && - read_tree_u_must_fail -m -u HEAD && + read_tree_u_must_succeed -m -u HEAD && git ls-files --stage >result && test_cmp expected result && git ls-files -t >result && + cat >expected.swt <<-\EOF && + S init.t + S sub/added + S sub/addedtoo + S subsub/added + EOF test_cmp expected.swt result && - test -f init.t && - test -f sub/added + ! test -f init.t && + ! test -f sub/added ' test_expect_success 'match directories with trailing slash' ' diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index dee99eeec3..88cdde255c 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -106,10 +106,8 @@ test_expect_success 'set enables config' ' cd empty-config && test_commit test file && test_path_is_missing .git/config.worktree && - test_must_fail git sparse-checkout set nothing && + git sparse-checkout set nothing && test_path_is_file .git/config.worktree && - test_must_fail git config core.sparseCheckout && - git sparse-checkout set "/*" && test_cmp_config true core.sparseCheckout ) ' @@ -302,8 +300,8 @@ test_expect_success 'revert to old sparse-checkout on empty update' ' echo >file && git add file && git commit -m "test" && - test_must_fail git sparse-checkout set nothing 2>err && - test_i18ngrep "Sparse checkout leaves no entry on working directory" err && + git sparse-checkout set nothing 2>err && + test_i18ngrep ! "Sparse checkout leaves no entry on working directory" err && test_i18ngrep ! ".git/index.lock" err && git sparse-checkout set file ) diff --git a/unpack-trees.c b/unpack-trees.c index b43f3e775a..9a3ccd9d08 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1677,8 +1677,6 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options } if (!o->skip_sparse_checkout) { - int empty_worktree = 1; - /* * Sparse checkout loop #2: set NEW_SKIP_WORKTREE on entries not in loop #1 * If they will have NEW_SKIP_WORKTREE, also set CE_SKIP_WORKTREE @@ -1706,19 +1704,6 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options if (apply_sparse_checkout(&o->result, ce, o)) ret = 1; - - if (!ce_skip_worktree(ce)) - empty_worktree = 0; - } - /* - * Sparse checkout is meant to narrow down checkout area - * but it does not make sense to narrow down to empty working - * tree. This is usually a mistake in sparse checkout rules. - * Do not allow users to do that. - */ - if (o->result.cache_nr && empty_worktree) { - ret = unpack_failed(o, "Sparse checkout leaves no entry on working directory"); - goto done; } if (ret == 1) { /* @@ -1779,7 +1764,7 @@ enum update_sparsity_result update_sparsity(struct unpack_trees_options *o) { enum update_sparsity_result ret = UPDATE_SPARSITY_SUCCESS; struct pattern_list pl; - int i, empty_worktree; + int i; unsigned old_show_all_errors; int free_pattern_list = 0; @@ -1810,7 +1795,6 @@ enum update_sparsity_result update_sparsity(struct unpack_trees_options *o) /* Then loop over entries and update/remove as needed */ ret = UPDATE_SPARSITY_SUCCESS; - empty_worktree = 1; for (i = 0; i < o->src_index->cache_nr; i++) { struct cache_entry *ce = o->src_index->cache[i]; @@ -1824,28 +1808,12 @@ enum update_sparsity_result update_sparsity(struct unpack_trees_options *o) if (apply_sparse_checkout(o->src_index, ce, o)) ret = UPDATE_SPARSITY_WARNINGS; - - if (!ce_skip_worktree(ce)) - empty_worktree = 0; - } - - /* - * Sparse checkout is meant to narrow down checkout area - * but it does not make sense to narrow down to empty working - * tree. This is usually a mistake in sparse checkout rules. - * Do not allow users to do that. - */ - if (o->src_index->cache_nr && empty_worktree) { - unpack_failed(o, "Sparse checkout leaves no entry on working directory"); - ret = UPDATE_SPARSITY_INDEX_UPDATE_FAILURES; - goto done; } skip_sparse_checkout: if (check_updates(o, o->src_index)) ret = UPDATE_SPARSITY_WORKTREE_UPDATE_FAILURES; -done: display_warning_msgs(o); o->show_all_errors = old_show_all_errors; if (free_pattern_list)