From: Junio C Hamano Date: Fri, 14 Oct 2011 02:03:18 +0000 (-0700) Subject: Merge branch 'nd/maint-sparse-errors' X-Git-Tag: v1.7.8-rc0~90 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/08ec3b5e4d56f62e8585095a7a4bf21721498ef3?hp=-c Merge branch 'nd/maint-sparse-errors' * nd/maint-sparse-errors: Add explanation why we do not allow to sparse checkout to empty working tree sparse checkout: show error messages when worktree shaping fails --- 08ec3b5e4d56f62e8585095a7a4bf21721498ef3 diff --combined t/t1011-read-tree-sparse-checkout.sh index 018c3546b6,efcd8abd2f..5c0053a20b --- a/t/t1011-read-tree-sparse-checkout.sh +++ b/t/t1011-read-tree-sparse-checkout.sh @@@ -234,4 -234,19 +234,20 @@@ test_expect_success 'read-tree --reset test_cmp empty result ' + test_expect_success 'print errors when failed to update worktree' ' + 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 && + cat >expected <<\EOF && + error: The following untracked working tree files would be overwritten by checkout: + sub/added + sub/addedtoo + Please move or remove them before you can switch branches. ++Aborting + EOF + test_cmp expected actual + ' + test_done diff --combined unpack-trees.c index 237aed8c76,0f205903e1..8282f5e5f6 --- a/unpack-trees.c +++ b/unpack-trees.c @@@ -159,7 -159,7 +159,7 @@@ static void display_error_msgs(struct u string_list_clear(rejects, 0); } if (something_displayed) - printf("Aborting\n"); + fprintf(stderr, "Aborting\n"); } /* @@@ -444,7 -444,6 +444,7 @@@ static int traverse_trees_recursive(in newinfo = *info; newinfo.prev = info; + newinfo.pathspec = info->pathspec; newinfo.name = *p; newinfo.pathlen += tree_entry_len(p->path, p->sha1) + 1; newinfo.conflicts |= df_conflicts; @@@ -594,7 -593,7 +594,7 @@@ static int unpack_nondirectories(int n static int unpack_failed(struct unpack_trees_options *o, const char *message) { discard_index(&o->result); - if (!o->gently) { + if (!o->gently && !o->exiting_early) { if (message) return error("%s", message); return -1; @@@ -1041,7 -1040,6 +1041,7 @@@ int unpack_trees(unsigned len, struct t info.fn = unpack_callback; info.data = o; info.show_all_errors = o->show_all_errors; + info.pathspec = o->pathspec; if (o->prefix) { /* @@@ -1091,6 -1089,7 +1091,7 @@@ */ mark_new_skip_worktree(o->el, &o->result, CE_ADDED, CE_SKIP_WORKTREE | CE_NEW_SKIP_WORKTREE); + ret = 0; for (i = 0; i < o->result.cache_nr; i++) { struct cache_entry *ce = o->result.cache[i]; @@@ -1103,19 -1102,30 +1104,30 @@@ * correct CE_NEW_SKIP_WORKTREE */ if (ce->ce_flags & CE_ADDED && - verify_absent(ce, ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o)) - return -1; + verify_absent(ce, ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o)) { + if (!o->show_all_errors) + goto return_failed; + ret = -1; + } if (apply_sparse_checkout(ce, o)) { + if (!o->show_all_errors) + goto return_failed; ret = -1; - goto done; } 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 + * tree. This is usually a mistake in sparse checkout rules. + * Do not allow users to do that. + */ if (o->result.cache_nr && empty_worktree) { - /* dubious---why should this fail??? */ ret = unpack_failed(o, "Sparse checkout leaves no entry on working directory"); goto done; } @@@ -1135,8 -1145,6 +1147,8 @@@ return_failed display_error_msgs(o); mark_all_ce_unused(o->src_index); ret = unpack_failed(o, NULL); + if (o->exiting_early) + ret = 0; goto done; } @@@ -1170,22 -1178,11 +1182,22 @@@ static int verify_uptodate_1(struct cac { struct stat st; - if (o->index_only || (!((ce->ce_flags & CE_VALID) || ce_skip_worktree(ce)) && (o->reset || ce_uptodate(ce)))) + if (o->index_only) + return 0; + + /* + * CE_VALID and CE_SKIP_WORKTREE cheat, we better check again + * if this entry is truly up-to-date because this file may be + * overwritten. + */ + if ((ce->ce_flags & CE_VALID) || ce_skip_worktree(ce)) + ; /* keep checking */ + else if (o->reset || ce_uptodate(ce)) return 0; if (!lstat(ce->name, &st)) { - unsigned changed = ie_match_stat(o->src_index, ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE); + int flags = CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE; + unsigned changed = ie_match_stat(o->src_index, ce, &st, flags); if (!changed) return 0; /*