switch: implicit dwim, use --no-guess to disable it

This is already the default in git-checkout. The real change in here is
just minor cleanup. The main excuse is to explain why dwim is kept default.

Contrary to detach mode that is easy to get into and confusing to get
back out. Automatically creating a tracking branch often does not kick
in as often (you would need a branch of the same name on a remote). And
since the branch creation is reported clearly, the user should be able
to undo/delete it if it's unwanted.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy 2019-03-29 17:39:13 +07:00 коммит произвёл Junio C Hamano
Родитель 163e3b2975
Коммит ccb111b342
2 изменённых файлов: 31 добавлений и 23 удалений

Просмотреть файл

@ -31,22 +31,13 @@ branch.
`<branch>`. `<branch>`.
+ +
If `<branch>` is not found but there does exist a tracking branch in If `<branch>` is not found but there does exist a tracking branch in
exactly one remote (call it `<remote>`) with a matching name, treat as exactly one remote (call it `<remote>`) with a matching name and
equivalent to `--no-guess` is not specified, treat as equivalent to
+ +
------------ ------------
$ git checkout -b <branch> --track <remote>/<branch> $ git checkout -b <branch> --track <remote>/<branch>
------------ ------------
+ +
If the branch exists in multiple remotes and one of them is named by
the `checkout.defaultRemote` configuration variable, we'll use that
one for the purposes of disambiguation, even if the `<branch>` isn't
unique across all remotes. Set it to
e.g. `checkout.defaultRemote=origin` to always checkout remote
branches from there if `<branch>` is ambiguous but exists on the
'origin' remote. See also `checkout.defaultRemote` in
linkgit:git-config[1].
+
You could omit `<branch>`, in which case the command degenerates to You could omit `<branch>`, in which case the command degenerates to
"check out the current branch", which is a glorified no-op with "check out the current branch", which is a glorified no-op with
rather expensive side-effects to show only the tracking information, rather expensive side-effects to show only the tracking information,
@ -183,6 +174,27 @@ explicitly give a name with `-b` in such a case.
Do not set up "upstream" configuration, even if the Do not set up "upstream" configuration, even if the
`branch.autoSetupMerge` configuration variable is true. `branch.autoSetupMerge` configuration variable is true.
--guess::
--no-guess::
If `<branch>` is not found but there does exist a tracking
branch in exactly one remote (call it `<remote>`) with a
matching name, treat as equivalent to
+
------------
$ git checkout -b <branch> --track <remote>/<branch>
------------
+
If the branch exists in multiple remotes and one of them is named by
the `checkout.defaultRemote` configuration variable, we'll use that
one for the purposes of disambiguation, even if the `<branch>` isn't
unique across all remotes. Set it to
e.g. `checkout.defaultRemote=origin` to always checkout remote
branches from there if `<branch>` is ambiguous but exists on the
'origin' remote. See also `checkout.defaultRemote` in
linkgit:git-config[1].
+
Use `--no-guess` to disable this.
-l:: -l::
Create the new branch's reflog; see linkgit:git-branch[1] for Create the new branch's reflog; see linkgit:git-branch[1] for
details. details.
@ -287,10 +299,6 @@ Note that this option uses the no overlay mode by default (see also
Just like linkgit:git-submodule[1], this will detach `HEAD` of the Just like linkgit:git-submodule[1], this will detach `HEAD` of the
submodule. submodule.
--no-guess::
Do not attempt to create a branch if a remote tracking branch
of the same name exists.
--overlay:: --overlay::
--no-overlay:: --no-overlay::
In the default overlay mode, `git checkout` never In the default overlay mode, `git checkout` never

Просмотреть файл

@ -53,7 +53,7 @@ struct checkout_opts {
int show_progress; int show_progress;
int count_checkout_paths; int count_checkout_paths;
int overlay_mode; int overlay_mode;
int no_dwim_new_local_branch; int dwim_new_local_branch;
int discard_changes; int discard_changes;
int accept_pathspec; int accept_pathspec;
int switch_branch_doing_nothing_is_ok; int switch_branch_doing_nothing_is_ok;
@ -1430,8 +1430,6 @@ static struct option *add_common_switch_branch_options(
OPT_BOOL_F(0, "overwrite-ignore", &opts->overwrite_ignore, OPT_BOOL_F(0, "overwrite-ignore", &opts->overwrite_ignore,
N_("update ignored files (default)"), N_("update ignored files (default)"),
PARSE_OPT_NOCOMPLETE), PARSE_OPT_NOCOMPLETE),
OPT_BOOL(0, "no-guess", &opts->no_dwim_new_local_branch,
N_("second guess 'git checkout <no-such-branch>'")),
OPT_BOOL(0, "ignore-other-worktrees", &opts->ignore_other_worktrees, OPT_BOOL(0, "ignore-other-worktrees", &opts->ignore_other_worktrees,
N_("do not check if another worktree is holding the given ref")), N_("do not check if another worktree is holding the given ref")),
OPT_END() OPT_END()
@ -1468,7 +1466,6 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
{ {
struct branch_info new_branch_info; struct branch_info new_branch_info;
int dwim_remotes_matched = 0; int dwim_remotes_matched = 0;
int dwim_new_local_branch;
memset(&new_branch_info, 0, sizeof(new_branch_info)); memset(&new_branch_info, 0, sizeof(new_branch_info));
opts->overwrite_ignore = 1; opts->overwrite_ignore = 1;
@ -1483,7 +1480,6 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
argc = parse_options(argc, argv, prefix, options, usagestr, argc = parse_options(argc, argv, prefix, options, usagestr,
PARSE_OPT_KEEP_DASHDASH); PARSE_OPT_KEEP_DASHDASH);
dwim_new_local_branch = !opts->no_dwim_new_local_branch;
if (opts->show_progress < 0) { if (opts->show_progress < 0) {
if (opts->quiet) if (opts->quiet)
opts->show_progress = 0; opts->show_progress = 0;
@ -1545,7 +1541,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
struct object_id rev; struct object_id rev;
int dwim_ok = int dwim_ok =
!opts->patch_mode && !opts->patch_mode &&
dwim_new_local_branch && opts->dwim_new_local_branch &&
opts->track == BRANCH_TRACK_UNSPECIFIED && opts->track == BRANCH_TRACK_UNSPECIFIED &&
!opts->new_branch; !opts->new_branch;
int n = parse_branchname_arg(argc, argv, dwim_ok, int n = parse_branchname_arg(argc, argv, dwim_ok,
@ -1626,12 +1622,14 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
OPT_STRING('B', NULL, &opts.new_branch_force, N_("branch"), OPT_STRING('B', NULL, &opts.new_branch_force, N_("branch"),
N_("create/reset and checkout a branch")), N_("create/reset and checkout a branch")),
OPT_BOOL('l', NULL, &opts.new_branch_log, N_("create reflog for new branch")), OPT_BOOL('l', NULL, &opts.new_branch_log, N_("create reflog for new branch")),
OPT_BOOL(0, "guess", &opts.dwim_new_local_branch,
N_("second guess 'git checkout <no-such-branch>' (default)")),
OPT_END() OPT_END()
}; };
int ret; int ret;
memset(&opts, 0, sizeof(opts)); memset(&opts, 0, sizeof(opts));
opts.no_dwim_new_local_branch = 0; opts.dwim_new_local_branch = 1;
opts.switch_branch_doing_nothing_is_ok = 1; opts.switch_branch_doing_nothing_is_ok = 1;
opts.accept_pathspec = 1; opts.accept_pathspec = 1;
opts.implicit_detach = 1; opts.implicit_detach = 1;
@ -1656,6 +1654,8 @@ int cmd_switch(int argc, const char **argv, const char *prefix)
N_("create and switch to a new branch")), N_("create and switch to a new branch")),
OPT_STRING('C', "force-create", &opts.new_branch_force, N_("branch"), OPT_STRING('C', "force-create", &opts.new_branch_force, N_("branch"),
N_("create/reset and switch to a branch")), N_("create/reset and switch to a branch")),
OPT_BOOL(0, "guess", &opts.dwim_new_local_branch,
N_("second guess 'git switch <no-such-branch>'")),
OPT_BOOL(0, "discard-changes", &opts.discard_changes, OPT_BOOL(0, "discard-changes", &opts.discard_changes,
N_("throw away local modifications")), N_("throw away local modifications")),
OPT_END() OPT_END()
@ -1663,7 +1663,7 @@ int cmd_switch(int argc, const char **argv, const char *prefix)
int ret; int ret;
memset(&opts, 0, sizeof(opts)); memset(&opts, 0, sizeof(opts));
opts.no_dwim_new_local_branch = 0; opts.dwim_new_local_branch = 1;
opts.accept_pathspec = 0; opts.accept_pathspec = 0;
opts.switch_branch_doing_nothing_is_ok = 0; opts.switch_branch_doing_nothing_is_ok = 0;
opts.implicit_detach = 0; opts.implicit_detach = 0;