From: Junio C Hamano Date: Fri, 1 Apr 2011 23:16:23 +0000 (-0700) Subject: Merge "checkout ambiguous ref bugfix" into maint X-Git-Tag: v1.7.4.3~12 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/d12d8ec9d728b0ce148f5a5caa68c858ef180d30?ds=inline;hp=-c Merge "checkout ambiguous ref bugfix" into maint * commit '0cb6ad3': checkout: fix bug with ambiguous refs --- d12d8ec9d728b0ce148f5a5caa68c858ef180d30 diff --combined builtin/checkout.c index cd7f56e6c4,953abdd0fa..e98576f22e --- a/builtin/checkout.c +++ b/builtin/checkout.c @@@ -161,7 -161,7 +161,7 @@@ static int checkout_merged(int pos, str * merge.renormalize set, too */ status = ll_merge(&result_buf, path, &ancestor, "base", - &ours, "ours", &theirs, "theirs", 0); + &ours, "ours", &theirs, "theirs", NULL); free(ancestor.ptr); free(ours.ptr); free(theirs.ptr); @@@ -404,7 -404,7 +404,7 @@@ static int merge_working_tree(struct ch topts.dir->exclude_per_dir = ".gitignore"; tree = parse_tree_indirect(old->commit ? old->commit->object.sha1 : - (unsigned char *)EMPTY_TREE_SHA1_BIN); + EMPTY_TREE_SHA1_BIN); init_tree_desc(&trees[0], tree->buffer, tree->size); tree = parse_tree_indirect(new->commit->object.sha1); init_tree_desc(&trees[1], tree->buffer, tree->size); @@@ -678,7 -678,7 +678,7 @@@ static const char *unique_tracking_name int cmd_checkout(int argc, const char **argv, const char *prefix) { struct checkout_opts opts; - unsigned char rev[20]; + unsigned char rev[20], branch_rev[20]; const char *arg; struct branch_info new; struct tree *source_tree = NULL; @@@ -686,7 -686,7 +686,7 @@@ int patch_mode = 0; int dwim_new_local_branch = 1; struct option options[] = { - OPT__QUIET(&opts.quiet), + OPT__QUIET(&opts.quiet, "suppress progress reporting"), OPT_STRING('b', NULL, &opts.new_branch, "branch", "create and checkout a new branch"), OPT_STRING('B', NULL, &opts.new_branch_force, "branch", @@@ -699,7 -699,7 +699,7 @@@ 2), OPT_SET_INT('3', "theirs", &opts.writeout_stage, "checkout their version for unmerged files", 3), - OPT_BOOLEAN('f', "force", &opts.force, "force checkout (throw away local modifications)"), + OPT__FORCE(&opts.force, "force checkout (throw away local modifications)"), OPT_BOOLEAN('m', "merge", &opts.merge, "perform a 3-way merge with the new branch"), OPT_STRING(0, "conflict", &conflict_style, "style", "conflict style (merge or diff3)"), @@@ -784,9 -784,9 +784,9 @@@ * between A and B, A...B names that merge base. * * With no paths, if is _not_ a commit, no -t nor -b - * was given, and there is a tracking branch whose name is + * was given, and there is a remote-tracking branch whose name is * in one and only one remote, then this is a short-hand - * to fork local from that remote tracking branch. + * to fork local from that remote-tracking branch. * * Otherwise shall not be ambiguous. * - If it's *only* a reference, treat it like case (1). @@@ -832,18 -832,21 +832,21 @@@ argc--; new.name = arg; - if ((new.commit = lookup_commit_reference_gently(rev, 1))) { - setup_branch_path(&new); + setup_branch_path(&new); - if ((check_ref_format(new.path) == CHECK_REF_FORMAT_OK) && - resolve_ref(new.path, rev, 1, NULL)) - ; - else - new.path = NULL; + if (check_ref_format(new.path) == CHECK_REF_FORMAT_OK && + resolve_ref(new.path, branch_rev, 1, NULL)) + hashcpy(rev, branch_rev); + else + new.path = NULL; /* not an existing branch */ + + if (!(new.commit = lookup_commit_reference_gently(rev, 1))) { + /* not a commit */ + source_tree = parse_tree_indirect(rev); + } else { parse_commit(new.commit); source_tree = new.commit->tree; - } else - source_tree = parse_tree_indirect(rev); + } if (!source_tree) /* case (1): want a tree */ die("reference is not a tree: %s", arg); diff --combined t/t2019-checkout-ambiguous-ref.sh index 0000000000,0000000000..943541d40d new file mode 100755 --- /dev/null +++ b/t/t2019-checkout-ambiguous-ref.sh @@@ -1,0 -1,0 +1,59 @@@ ++#!/bin/sh ++ ++test_description='checkout handling of ambiguous (branch/tag) refs' ++. ./test-lib.sh ++ ++test_expect_success 'setup ambiguous refs' ' ++ test_commit branch file && ++ git branch ambiguity && ++ git branch vagueness && ++ test_commit tag file && ++ git tag ambiguity && ++ git tag vagueness HEAD:file && ++ test_commit other file ++' ++ ++test_expect_success 'checkout ambiguous ref succeeds' ' ++ git checkout ambiguity >stdout 2>stderr ++' ++ ++test_expect_success 'checkout produces ambiguity warning' ' ++ grep "warning.*ambiguous" stderr ++' ++ ++test_expect_success 'checkout chooses branch over tag' ' ++ echo refs/heads/ambiguity >expect && ++ git symbolic-ref HEAD >actual && ++ test_cmp expect actual && ++ echo branch >expect && ++ test_cmp expect file ++' ++ ++test_expect_success 'checkout reports switch to branch' ' ++ grep "Switched to branch" stderr && ++ ! grep "^HEAD is now at" stderr ++' ++ ++test_expect_success 'checkout vague ref succeeds' ' ++ git checkout vagueness >stdout 2>stderr && ++ test_set_prereq VAGUENESS_SUCCESS ++' ++ ++test_expect_success VAGUENESS_SUCCESS 'checkout produces ambiguity warning' ' ++ grep "warning.*ambiguous" stderr ++' ++ ++test_expect_success VAGUENESS_SUCCESS 'checkout chooses branch over tag' ' ++ echo refs/heads/vagueness >expect && ++ git symbolic-ref HEAD >actual && ++ test_cmp expect actual && ++ echo branch >expect && ++ test_cmp expect file ++' ++ ++test_expect_success VAGUENESS_SUCCESS 'checkout reports switch to branch' ' ++ grep "Switched to branch" stderr && ++ ! grep "^HEAD is now at" stderr ++' ++ ++test_done