зеркало из https://github.com/microsoft/git.git
Merge branch 'nd/checkout-dwim-fix'
"git checkout frotz" (without any double-dash) avoids ambiguity by making sure 'frotz' cannot be interpreted as a revision and as a path at the same time. This safety has been updated to check also a unique remote-tracking branch 'frotz' in a remote, when dwimming to create a local branch 'frotz' out of a remote-tracking branch 'frotz' from a remote. * nd/checkout-dwim-fix: checkout: disambiguate dwim tracking branches and local files
This commit is contained in:
Коммит
8d7f9dbf84
|
@ -276,6 +276,10 @@ section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
|
|||
Just like linkgit:git-submodule[1], this will detach the
|
||||
submodules HEAD.
|
||||
|
||||
--no-guess::
|
||||
Do not attempt to create a branch if a remote tracking branch
|
||||
of the same name exists.
|
||||
|
||||
<branch>::
|
||||
Branch to checkout; if it refers to a branch (i.e., a name that,
|
||||
when prepended with "refs/heads/", is a valid ref), then that
|
||||
|
|
|
@ -1080,9 +1080,12 @@ static int parse_branchname_arg(int argc, const char **argv,
|
|||
*/
|
||||
int recover_with_dwim = dwim_new_local_branch_ok;
|
||||
|
||||
if (!has_dash_dash &&
|
||||
(check_filename(opts->prefix, arg) || !no_wildcard(arg)))
|
||||
int could_be_checkout_paths = !has_dash_dash &&
|
||||
check_filename(opts->prefix, arg);
|
||||
|
||||
if (!has_dash_dash && !no_wildcard(arg))
|
||||
recover_with_dwim = 0;
|
||||
|
||||
/*
|
||||
* Accept "git checkout foo" and "git checkout foo --"
|
||||
* as candidates for dwim.
|
||||
|
@ -1095,6 +1098,10 @@ static int parse_branchname_arg(int argc, const char **argv,
|
|||
const char *remote = unique_tracking_name(arg, rev,
|
||||
dwim_remotes_matched);
|
||||
if (remote) {
|
||||
if (could_be_checkout_paths)
|
||||
die(_("'%s' could be both a local file and a tracking branch.\n"
|
||||
"Please use -- (and optionally --no-guess) to disambiguate"),
|
||||
arg);
|
||||
*new_branch = arg;
|
||||
arg = remote;
|
||||
/* DWIMmed to create local branch, case (3).(b) */
|
||||
|
@ -1229,7 +1236,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
|||
struct checkout_opts opts;
|
||||
struct branch_info new_branch_info;
|
||||
char *conflict_style = NULL;
|
||||
int dwim_new_local_branch = 1;
|
||||
int dwim_new_local_branch, no_dwim_new_local_branch = 0;
|
||||
int dwim_remotes_matched = 0;
|
||||
struct option options[] = {
|
||||
OPT__QUIET(&opts.quiet, N_("suppress progress reporting")),
|
||||
|
@ -1259,8 +1266,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
|||
OPT_BOOL('p', "patch", &opts.patch_mode, N_("select hunks interactively")),
|
||||
OPT_BOOL(0, "ignore-skip-worktree-bits", &opts.ignore_skipworktree,
|
||||
N_("do not limit pathspecs to sparse entries only")),
|
||||
OPT_HIDDEN_BOOL(0, "guess", &dwim_new_local_branch,
|
||||
N_("second guess 'git checkout <no-such-branch>'")),
|
||||
OPT_BOOL(0, "no-guess", &no_dwim_new_local_branch,
|
||||
N_("do not second guess 'git checkout <no-such-branch>'")),
|
||||
OPT_BOOL(0, "ignore-other-worktrees", &opts.ignore_other_worktrees,
|
||||
N_("do not check if another worktree is holding the given ref")),
|
||||
{ OPTION_CALLBACK, 0, "recurse-submodules", NULL,
|
||||
|
@ -1283,6 +1290,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
|||
argc = parse_options(argc, argv, prefix, options, checkout_usage,
|
||||
PARSE_OPT_KEEP_DASHDASH);
|
||||
|
||||
dwim_new_local_branch = !no_dwim_new_local_branch;
|
||||
if (opts.show_progress < 0) {
|
||||
if (opts.quiet)
|
||||
opts.show_progress = 0;
|
||||
|
|
|
@ -278,4 +278,35 @@ test_expect_success 'loosely defined local base branch is reported correctly' '
|
|||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'reject when arg could be part of dwim branch' '
|
||||
git remote add foo file://non-existent-place &&
|
||||
git update-ref refs/remotes/foo/dwim-arg HEAD &&
|
||||
echo foo >dwim-arg &&
|
||||
git add dwim-arg &&
|
||||
echo bar >dwim-arg &&
|
||||
test_must_fail git checkout dwim-arg &&
|
||||
test_must_fail git rev-parse refs/heads/dwim-arg -- &&
|
||||
grep bar dwim-arg
|
||||
'
|
||||
|
||||
test_expect_success 'disambiguate dwim branch and checkout path (1)' '
|
||||
git update-ref refs/remotes/foo/dwim-arg1 HEAD &&
|
||||
echo foo >dwim-arg1 &&
|
||||
git add dwim-arg1 &&
|
||||
echo bar >dwim-arg1 &&
|
||||
git checkout -- dwim-arg1 &&
|
||||
test_must_fail git rev-parse refs/heads/dwim-arg1 -- &&
|
||||
grep foo dwim-arg1
|
||||
'
|
||||
|
||||
test_expect_success 'disambiguate dwim branch and checkout path (2)' '
|
||||
git update-ref refs/remotes/foo/dwim-arg2 HEAD &&
|
||||
echo foo >dwim-arg2 &&
|
||||
git add dwim-arg2 &&
|
||||
echo bar >dwim-arg2 &&
|
||||
git checkout dwim-arg2 -- &&
|
||||
git rev-parse refs/heads/dwim-arg2 -- &&
|
||||
grep bar dwim-arg2
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
|
@ -1434,7 +1434,8 @@ test_expect_success 'double dash "git checkout"' '
|
|||
--ignore-other-worktrees Z
|
||||
--recurse-submodules Z
|
||||
--progress Z
|
||||
--no-quiet Z
|
||||
--guess Z
|
||||
--no-guess Z
|
||||
--no-... Z
|
||||
EOF
|
||||
'
|
||||
|
|
Загрузка…
Ссылка в новой задаче