|
23 | 23 | #include "resolve-undo.h" |
24 | 24 | #include "submodule-config.h" |
25 | 25 | #include "submodule.h" |
| 26 | +#include "advice.h" |
26 | 27 |
|
27 | 28 | static const char * const checkout_usage[] = { |
28 | 29 | N_("git checkout [<options>] <branch>"), |
@@ -879,7 +880,8 @@ static int parse_branchname_arg(int argc, const char **argv, |
879 | 880 | int dwim_new_local_branch_ok, |
880 | 881 | struct branch_info *new_branch_info, |
881 | 882 | struct checkout_opts *opts, |
882 | | - struct object_id *rev) |
| 883 | + struct object_id *rev, |
| 884 | + int *dwim_remotes_matched) |
883 | 885 | { |
884 | 886 | struct tree **source_tree = &opts->source_tree; |
885 | 887 | const char **new_branch = &opts->new_branch; |
@@ -911,8 +913,10 @@ static int parse_branchname_arg(int argc, const char **argv, |
911 | 913 | * (b) If <something> is _not_ a commit, either "--" is present |
912 | 914 | * or <something> is not a path, no -t or -b was given, and |
913 | 915 | * and there is a tracking branch whose name is <something> |
914 | | - * in one and only one remote, then this is a short-hand to |
915 | | - * fork local <something> from that remote-tracking branch. |
| 916 | + * in one and only one remote (or if the branch exists on the |
| 917 | + * remote named in checkout.defaultRemote), then this is a |
| 918 | + * short-hand to fork local <something> from that |
| 919 | + * remote-tracking branch. |
916 | 920 | * |
917 | 921 | * (c) Otherwise, if "--" is present, treat it like case (1). |
918 | 922 | * |
@@ -973,7 +977,8 @@ static int parse_branchname_arg(int argc, const char **argv, |
973 | 977 | recover_with_dwim = 0; |
974 | 978 |
|
975 | 979 | if (recover_with_dwim) { |
976 | | - const char *remote = unique_tracking_name(arg, rev); |
| 980 | + const char *remote = unique_tracking_name(arg, rev, |
| 981 | + dwim_remotes_matched); |
977 | 982 | if (remote) { |
978 | 983 | *new_branch = arg; |
979 | 984 | arg = remote; |
@@ -1110,6 +1115,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) |
1110 | 1115 | struct branch_info new_branch_info; |
1111 | 1116 | char *conflict_style = NULL; |
1112 | 1117 | int dwim_new_local_branch = 1; |
| 1118 | + int dwim_remotes_matched = 0; |
1113 | 1119 | struct option options[] = { |
1114 | 1120 | OPT__QUIET(&opts.quiet, N_("suppress progress reporting")), |
1115 | 1121 | OPT_STRING('b', NULL, &opts.new_branch, N_("branch"), |
@@ -1222,7 +1228,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) |
1222 | 1228 | opts.track == BRANCH_TRACK_UNSPECIFIED && |
1223 | 1229 | !opts.new_branch; |
1224 | 1230 | int n = parse_branchname_arg(argc, argv, dwim_ok, |
1225 | | - &new_branch_info, &opts, &rev); |
| 1231 | + &new_branch_info, &opts, &rev, |
| 1232 | + &dwim_remotes_matched); |
1226 | 1233 | argv += n; |
1227 | 1234 | argc -= n; |
1228 | 1235 | } |
@@ -1264,8 +1271,26 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) |
1264 | 1271 | } |
1265 | 1272 |
|
1266 | 1273 | UNLEAK(opts); |
1267 | | - if (opts.patch_mode || opts.pathspec.nr) |
1268 | | - return checkout_paths(&opts, new_branch_info.name); |
1269 | | - else |
| 1274 | + if (opts.patch_mode || opts.pathspec.nr) { |
| 1275 | + int ret = checkout_paths(&opts, new_branch_info.name); |
| 1276 | + if (ret && dwim_remotes_matched > 1 && |
| 1277 | + advice_checkout_ambiguous_remote_branch_name) |
| 1278 | + advise(_("'%s' matched more than one remote tracking branch.\n" |
| 1279 | + "We found %d remotes with a reference that matched. So we fell back\n" |
| 1280 | + "on trying to resolve the argument as a path, but failed there too!\n" |
| 1281 | + "\n" |
| 1282 | + "If you meant to check out a remote tracking branch on, e.g. 'origin',\n" |
| 1283 | + "you can do so by fully qualifying the name with the --track option:\n" |
| 1284 | + "\n" |
| 1285 | + " git checkout --track origin/<name>\n" |
| 1286 | + "\n" |
| 1287 | + "If you'd like to always have checkouts of an ambiguous <name> prefer\n" |
| 1288 | + "one remote, e.g. the 'origin' remote, consider setting\n" |
| 1289 | + "checkout.defaultRemote=origin in your config."), |
| 1290 | + argv[0], |
| 1291 | + dwim_remotes_matched); |
| 1292 | + return ret; |
| 1293 | + } else { |
1270 | 1294 | return checkout_branch(&opts, &new_branch_info); |
| 1295 | + } |
1271 | 1296 | } |
0 commit comments