From: Junio C Hamano Date: Wed, 10 Sep 2008 09:13:41 +0000 (-0700) Subject: Merge branch 'jc/maint-checkout-fix' into maint X-Git-Tag: v1.6.0.2~12 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/94c27881bd98d5bb70e3d4f8a18e384095c876b9?ds=inline;hp=-c Merge branch 'jc/maint-checkout-fix' into maint * jc/maint-checkout-fix: checkout: do not check out unmerged higher stages randomly --- 94c27881bd98d5bb70e3d4f8a18e384095c876b9 diff --combined builtin-checkout.c index f6f8f086de,8544010994..8e77767b49 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@@ -76,6 -76,15 +76,15 @@@ static int read_tree_some(struct tree * return 0; } + static int skip_same_name(struct cache_entry *ce, int pos) + { + while (++pos < active_nr && + !strcmp(active_cache[pos]->name, ce->name)) + ; /* skip */ + return pos; + } + + static int checkout_paths(struct tree *source_tree, const char **pathspec) { int pos; @@@ -107,6 -116,20 +116,20 @@@ if (report_path_error(ps_matched, pathspec, 0)) return 1; + /* Any unmerged paths? */ + for (pos = 0; pos < active_nr; pos++) { + struct cache_entry *ce = active_cache[pos]; + if (pathspec_match(pathspec, NULL, ce->name, 0)) { + if (!ce_stage(ce)) + continue; + errs = 1; + error("path '%s' is unmerged", ce->name); + pos = skip_same_name(ce, pos) - 1; + } + } + if (errs) + return 1; + /* Now we are committed to check them out */ memset(&state, 0, sizeof(state)); state.force = 1; @@@ -114,7 -137,11 +137,11 @@@ for (pos = 0; pos < active_nr; pos++) { struct cache_entry *ce = active_cache[pos]; if (pathspec_match(pathspec, NULL, ce->name, 0)) { - errs |= checkout_entry(ce, &state, NULL); + if (!ce_stage(ce)) { + errs |= checkout_entry(ce, &state, NULL); + continue; + } + pos = skip_same_name(ce, pos) - 1; } } @@@ -386,11 -413,13 +413,11 @@@ static int switch_branches(struct check } /* - * If the new thing isn't a branch and isn't HEAD and we're - * not starting a new branch, and we want messages, and we - * weren't on a branch, and we're moving to a new commit, - * describe the old commit. + * If we were on a detached HEAD, but we are now moving to + * a new commit, we want to mention the old commit once more + * to remind the user that it might be lost. */ - if (!new->path && strcmp(new->name, "HEAD") && !opts->new_branch && - !opts->quiet && !old.path && new->commit != old.commit) + if (!opts->quiet && !old.path && new->commit != old.commit) describe_detached_head("Previous HEAD position was", old.commit); if (!old.commit) { diff --combined t/t7201-co.sh index 2e2b3bf53d,83a366f1e7..fbec70d3c6 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@@ -3,7 -3,7 +3,7 @@@ # Copyright (c) 2006 Junio C Hamano # -test_description='git-checkout tests. +test_description='git checkout tests. Creates master, forks renamer and side branches from it. Test switching across them. @@@ -337,4 -337,26 +337,26 @@@ test_expect_success test refs/heads/delete-me = "$(git symbolic-ref HEAD)" && test_must_fail git checkout --track -b track' + test_expect_success 'checkout an unmerged path should fail' ' + rm -f .git/index && + O=$(echo original | git hash-object -w --stdin) && + A=$(echo ourside | git hash-object -w --stdin) && + B=$(echo theirside | git hash-object -w --stdin) && + ( + echo "100644 $A 0 fild" && + echo "100644 $O 1 file" && + echo "100644 $A 2 file" && + echo "100644 $B 3 file" && + echo "100644 $A 0 filf" + ) | git update-index --index-info && + echo "none of the above" >sample && + cat sample >fild && + cat sample >file && + cat sample >filf && + test_must_fail git checkout fild file filf && + test_cmp sample fild && + test_cmp sample filf && + test_cmp sample file + ' + test_done