diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh index eb44bafb59..63223e13bd 100755 --- a/t/t1011-read-tree-sparse-checkout.sh +++ b/t/t1011-read-tree-sparse-checkout.sh @@ -233,18 +233,19 @@ test_expect_success 'read-tree --reset removes outside worktree' ' test_must_be_empty result ' -test_expect_success 'print errors when failed to update worktree' ' +test_expect_success 'print warnings when some worktree updates disabled' ' echo sub >.git/info/sparse-checkout && git checkout -f init && mkdir sub && touch sub/added sub/addedtoo && - test_must_fail git checkout top 2>actual && + # Use -q to suppress "Previous HEAD position" and "Head is now at" msgs + git checkout -q top 2>actual && cat >expected <<\EOF && -error: The following untracked working tree files would be overwritten by checkout: +warning: The following paths were already present and thus not updated despite sparse patterns: sub/added sub/addedtoo -Please move or remove them before you switch branches. -Aborting + +After fixing the above paths, you may want to run `git sparse-checkout reapply`. EOF test_i18ncmp expected actual ' diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh index bbca7ef8da..21583154d8 100755 --- a/t/t2018-checkout-branch.sh +++ b/t/t2018-checkout-branch.sh @@ -238,4 +238,26 @@ test_expect_success 'checkout -b after clone --no-checkout does a checkout of HE test_path_is_file dest/a.t ' +test_expect_success 'checkout -b to a new branch preserves mergeable changes despite sparse-checkout' ' + test_when_finished " + git reset --hard && + git checkout branch1-scratch && + test_might_fail git branch -D branch3 && + git config core.sparseCheckout false && + rm .git/info/sparse-checkout" && + + test_commit file2 && + + echo stuff >>file1 && + echo file2 >.git/info/sparse-checkout && + git config core.sparseCheckout true && + + CURHEAD=$(git rev-parse HEAD) && + do_checkout branch3 $CURHEAD && + + echo file1 >expect && + git diff --name-only >actual && + test_cmp expect actual +' + test_done diff --git a/unpack-trees.c b/unpack-trees.c index dec044339d..b43f3e775a 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1701,23 +1701,15 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options * correct CE_NEW_SKIP_WORKTREE */ if (ce->ce_flags & CE_ADDED && - verify_absent(ce, ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o)) { - if (!o->show_all_errors) - goto return_failed; - ret = -1; - } + verify_absent(ce, WARNING_SPARSE_ORPHANED_NOT_OVERWRITTEN, o)) + ret = 1; + + if (apply_sparse_checkout(&o->result, ce, o)) + ret = 1; - if (apply_sparse_checkout(&o->result, ce, o)) { - if (!o->show_all_errors) - goto return_failed; - ret = -1; - } if (!ce_skip_worktree(ce)) empty_worktree = 0; - } - if (ret < 0) - goto return_failed; /* * Sparse checkout is meant to narrow down checkout area * but it does not make sense to narrow down to empty working @@ -1728,6 +1720,15 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options ret = unpack_failed(o, "Sparse checkout leaves no entry on working directory"); goto done; } + if (ret == 1) { + /* + * Inability to sparsify or de-sparsify individual + * paths is not an error, but just a warning. + */ + if (o->show_all_errors) + display_warning_msgs(o); + ret = 0; + } } ret = check_updates(o, &o->result) ? (-2) : 0; @@ -1759,10 +1760,8 @@ done: return ret; return_failed: - if (o->show_all_errors) { + if (o->show_all_errors) display_error_msgs(o); - display_warning_msgs(o); - } mark_all_ce_unused(o->src_index); ret = unpack_failed(o, NULL); if (o->exiting_early)