mirror of
https://github.com/git/git.git
synced 2026-02-27 10:25:07 +00:00
Merge branch 'jc/checkout-switch-restore' into jch
"git switch <name>", in an attempt to create a local branch <name> after a remote tracking branch of the same name gave an advise message to disambiguate using "git checkout", which has been updated to use "git switch". * jc/checkout-switch-restore: checkout: tell "parse_remote_branch" which command is calling it checkout: pass program-readable token to unified "main"
This commit is contained in:
@@ -43,22 +43,6 @@
|
||||
#include "parallel-checkout.h"
|
||||
#include "add-interactive.h"
|
||||
|
||||
static const char * const checkout_usage[] = {
|
||||
N_("git checkout [<options>] <branch>"),
|
||||
N_("git checkout [<options>] [<branch>] -- <file>..."),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char * const switch_branch_usage[] = {
|
||||
N_("git switch [<options>] [<branch>]"),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char * const restore_usage[] = {
|
||||
N_("git restore [<options>] [--source=<branch>] <file>..."),
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct checkout_opts {
|
||||
int patch_mode;
|
||||
int patch_context;
|
||||
@@ -1293,9 +1277,17 @@ static void setup_new_branch_info_and_source_tree(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum checkout_command {
|
||||
CHECKOUT_CHECKOUT = 1,
|
||||
CHECKOUT_SWITCH = 2,
|
||||
CHECKOUT_RESTORE = 3,
|
||||
};
|
||||
|
||||
static char *parse_remote_branch(const char *arg,
|
||||
struct object_id *rev,
|
||||
int could_be_checkout_paths)
|
||||
int could_be_checkout_paths,
|
||||
enum checkout_command which_command)
|
||||
{
|
||||
int num_matches = 0;
|
||||
char *remote = unique_tracking_name(arg, rev, &num_matches);
|
||||
@@ -1308,14 +1300,30 @@ static char *parse_remote_branch(const char *arg,
|
||||
|
||||
if (!remote && num_matches > 1) {
|
||||
if (advice_enabled(ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME)) {
|
||||
const char *cmdname;
|
||||
|
||||
switch (which_command) {
|
||||
case CHECKOUT_CHECKOUT:
|
||||
cmdname = "checkout";
|
||||
break;
|
||||
case CHECKOUT_SWITCH:
|
||||
cmdname = "switch";
|
||||
break;
|
||||
default:
|
||||
BUG("command <%d> should not reach parse_remote_branch",
|
||||
which_command);
|
||||
break;
|
||||
}
|
||||
|
||||
advise(_("If you meant to check out a remote tracking branch on, e.g. 'origin',\n"
|
||||
"you can do so by fully qualifying the name with the --track option:\n"
|
||||
"\n"
|
||||
" git checkout --track origin/<name>\n"
|
||||
" git %s --track origin/<name>\n"
|
||||
"\n"
|
||||
"If you'd like to always have checkouts of an ambiguous <name> prefer\n"
|
||||
"one remote, e.g. the 'origin' remote, consider setting\n"
|
||||
"checkout.defaultRemote=origin in your config."));
|
||||
"checkout.defaultRemote=origin in your config."),
|
||||
cmdname);
|
||||
}
|
||||
|
||||
die(_("'%s' matched multiple (%d) remote tracking branches"),
|
||||
@@ -1327,6 +1335,7 @@ static char *parse_remote_branch(const char *arg,
|
||||
|
||||
static int parse_branchname_arg(int argc, const char **argv,
|
||||
int dwim_new_local_branch_ok,
|
||||
enum checkout_command which_command,
|
||||
struct branch_info *new_branch_info,
|
||||
struct checkout_opts *opts,
|
||||
struct object_id *rev)
|
||||
@@ -1436,7 +1445,8 @@ static int parse_branchname_arg(int argc, const char **argv,
|
||||
|
||||
if (recover_with_dwim) {
|
||||
remote = parse_remote_branch(arg, rev,
|
||||
could_be_checkout_paths);
|
||||
could_be_checkout_paths,
|
||||
which_command);
|
||||
if (remote) {
|
||||
*new_branch = arg;
|
||||
arg = remote;
|
||||
@@ -1767,12 +1777,44 @@ static char cb_option = 'b';
|
||||
|
||||
static int checkout_main(int argc, const char **argv, const char *prefix,
|
||||
struct checkout_opts *opts, struct option *options,
|
||||
const char * const usagestr[])
|
||||
enum checkout_command which_command)
|
||||
{
|
||||
int parseopt_flags = 0;
|
||||
struct branch_info new_branch_info = { 0 };
|
||||
int ret;
|
||||
|
||||
static const char * const checkout_usage[] = {
|
||||
N_("git checkout [<options>] <branch>"),
|
||||
N_("git checkout [<options>] [<branch>] -- <file>..."),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char * const switch_branch_usage[] = {
|
||||
N_("git switch [<options>] [<branch>]"),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char * const restore_usage[] = {
|
||||
N_("git restore [<options>] [--source=<branch>] <file>..."),
|
||||
NULL,
|
||||
};
|
||||
|
||||
const char * const *usagestr;
|
||||
|
||||
switch (which_command) {
|
||||
case CHECKOUT_CHECKOUT:
|
||||
usagestr = checkout_usage;
|
||||
break;
|
||||
case CHECKOUT_SWITCH:
|
||||
usagestr = switch_branch_usage;
|
||||
break;
|
||||
case CHECKOUT_RESTORE:
|
||||
usagestr = restore_usage;
|
||||
break;
|
||||
default:
|
||||
BUG("no such checkout variant %d", which_command);
|
||||
}
|
||||
|
||||
opts->overwrite_ignore = 1;
|
||||
opts->prefix = prefix;
|
||||
opts->show_progress = -1;
|
||||
@@ -1893,7 +1935,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
|
||||
opts->dwim_new_local_branch &&
|
||||
opts->track == BRANCH_TRACK_UNSPECIFIED &&
|
||||
!opts->new_branch;
|
||||
int n = parse_branchname_arg(argc, argv, dwim_ok,
|
||||
int n = parse_branchname_arg(argc, argv, dwim_ok, which_command,
|
||||
&new_branch_info, opts, &rev);
|
||||
argv += n;
|
||||
argc -= n;
|
||||
@@ -2032,7 +2074,7 @@ int cmd_checkout(int argc,
|
||||
options = add_checkout_path_options(&opts, options);
|
||||
|
||||
return checkout_main(argc, argv, prefix, &opts, options,
|
||||
checkout_usage);
|
||||
CHECKOUT_CHECKOUT);
|
||||
}
|
||||
|
||||
int cmd_switch(int argc,
|
||||
@@ -2071,7 +2113,7 @@ int cmd_switch(int argc,
|
||||
cb_option = 'c';
|
||||
|
||||
return checkout_main(argc, argv, prefix, &opts, options,
|
||||
switch_branch_usage);
|
||||
CHECKOUT_SWITCH);
|
||||
}
|
||||
|
||||
int cmd_restore(int argc,
|
||||
@@ -2107,5 +2149,5 @@ int cmd_restore(int argc,
|
||||
options = add_checkout_path_options(&opts, options);
|
||||
|
||||
return checkout_main(argc, argv, prefix, &opts, options,
|
||||
restore_usage);
|
||||
CHECKOUT_RESTORE);
|
||||
}
|
||||
|
||||
@@ -47,4 +47,22 @@ test_expect_success 'checkout --track -b overrides autoSetupMerge=inherit' '
|
||||
test_cmp_config refs/heads/main branch.b4.merge
|
||||
'
|
||||
|
||||
test_expect_success 'ambiguous tracking info' '
|
||||
# Set up a few remote repositories
|
||||
git init --bare --initial-branch=trunk src1 &&
|
||||
git init --bare --initial-branch=trunk src2 &&
|
||||
git push src1 one:refs/heads/trunk &&
|
||||
git push src2 two:refs/heads/trunk &&
|
||||
|
||||
git remote add -f src1 "file://$PWD/src1" &&
|
||||
git remote add -f src2 "file://$PWD/src2" &&
|
||||
|
||||
# DWIM
|
||||
test_must_fail git checkout trunk 2>hint.checkout &&
|
||||
test_grep "hint: *git checkout --track" hint.checkout &&
|
||||
|
||||
test_must_fail git switch trunk 2>hint.switch &&
|
||||
test_grep "hint: *git switch --track" hint.switch
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
Reference in New Issue
Block a user