|
30 | 30 | #include "repo-settings.h" |
31 | 31 | #include "resolve-undo.h" |
32 | 32 | #include "revision.h" |
| 33 | +#include "run-command.h" |
33 | 34 | #include "setup.h" |
| 35 | +#include "strvec.h" |
34 | 36 | #include "submodule.h" |
35 | 37 | #include "symlinks.h" |
36 | 38 | #include "trace2.h" |
@@ -61,6 +63,7 @@ struct checkout_opts { |
61 | 63 | int count_checkout_paths; |
62 | 64 | int overlay_mode; |
63 | 65 | int dwim_new_local_branch; |
| 66 | + int fetch; |
64 | 67 | int discard_changes; |
65 | 68 | int accept_ref; |
66 | 69 | int accept_pathspec; |
@@ -112,6 +115,34 @@ struct branch_info { |
112 | 115 | char *checkout; |
113 | 116 | }; |
114 | 117 |
|
| 118 | +static void fetch_remote_for_start_point(const char *arg) |
| 119 | +{ |
| 120 | + const char *slash; |
| 121 | + char *remote_name; |
| 122 | + struct remote *remote; |
| 123 | + struct child_process cmd = CHILD_PROCESS_INIT; |
| 124 | + |
| 125 | + if (!arg || !*arg) |
| 126 | + return; |
| 127 | + |
| 128 | + slash = strchr(arg, '/'); |
| 129 | + if (slash == arg) |
| 130 | + return; |
| 131 | + remote_name = slash ? xstrndup(arg, slash - arg) : xstrdup(arg); |
| 132 | + |
| 133 | + remote = remote_get(remote_name); |
| 134 | + if (!remote || !remote_is_configured(remote, 1)) { |
| 135 | + free(remote_name); |
| 136 | + return; |
| 137 | + } |
| 138 | + |
| 139 | + strvec_pushl(&cmd.args, "fetch", remote_name, NULL); |
| 140 | + cmd.git_cmd = 1; |
| 141 | + free(remote_name); |
| 142 | + if (run_command(&cmd)) |
| 143 | + die(_("failed to fetch start-point '%s'"), arg); |
| 144 | +} |
| 145 | + |
115 | 146 | static void branch_info_release(struct branch_info *info) |
116 | 147 | { |
117 | 148 | free(info->name); |
@@ -1237,6 +1268,10 @@ static int git_checkout_config(const char *var, const char *value, |
1237 | 1268 | opts->dwim_new_local_branch = git_config_bool(var, value); |
1238 | 1269 | return 0; |
1239 | 1270 | } |
| 1271 | + if (!strcmp(var, "checkout.fetch")) { |
| 1272 | + opts->fetch = git_config_bool(var, value); |
| 1273 | + return 0; |
| 1274 | + } |
1240 | 1275 |
|
1241 | 1276 | if (starts_with(var, "submodule.")) |
1242 | 1277 | return git_default_submodule_config(var, value, NULL); |
@@ -1942,8 +1977,13 @@ static int checkout_main(int argc, const char **argv, const char *prefix, |
1942 | 1977 | opts->dwim_new_local_branch && |
1943 | 1978 | opts->track == BRANCH_TRACK_UNSPECIFIED && |
1944 | 1979 | !opts->new_branch; |
1945 | | - int n = parse_branchname_arg(argc, argv, dwim_ok, which_command, |
1946 | | - &new_branch_info, opts, &rev); |
| 1980 | + int n; |
| 1981 | + |
| 1982 | + if (opts->fetch) |
| 1983 | + fetch_remote_for_start_point(argv[0]); |
| 1984 | + |
| 1985 | + n = parse_branchname_arg(argc, argv, dwim_ok, which_command, |
| 1986 | + &new_branch_info, opts, &rev); |
1947 | 1987 | argv += n; |
1948 | 1988 | argc -= n; |
1949 | 1989 | } else if (!opts->accept_ref && opts->from_treeish) { |
@@ -2052,6 +2092,8 @@ int cmd_checkout(int argc, |
2052 | 2092 | OPT_BOOL(0, "overlay", &opts.overlay_mode, N_("use overlay mode (default)")), |
2053 | 2093 | OPT_BOOL(0, "auto-advance", &opts.auto_advance, |
2054 | 2094 | N_("auto advance to the next file when selecting hunks interactively")), |
| 2095 | + OPT_BOOL(0, "fetch", &opts.fetch, |
| 2096 | + N_("fetch from the remote first if <start-point> is a remote-tracking branch")), |
2055 | 2097 | OPT_END() |
2056 | 2098 | }; |
2057 | 2099 |
|
@@ -2102,6 +2144,8 @@ int cmd_switch(int argc, |
2102 | 2144 | N_("second guess 'git switch <no-such-branch>'")), |
2103 | 2145 | OPT_BOOL(0, "discard-changes", &opts.discard_changes, |
2104 | 2146 | N_("throw away local modifications")), |
| 2147 | + OPT_BOOL(0, "fetch", &opts.fetch, |
| 2148 | + N_("fetch from the remote first if <start-point> is a remote-tracking branch")), |
2105 | 2149 | OPT_END() |
2106 | 2150 | }; |
2107 | 2151 |
|
|
0 commit comments