🌐 AI搜索 & 代理 主页
blob: 534594f7f8006d11ebb9b8d10712b6fc6191a043 [file] [log] [blame]
Brian Gesiak303d1d02014-02-28 06:43:331#include "git-compat-util.h"
Elijah Newren6c6ddf92023-04-11 03:00:392#include "advice.h"
Brandon Williamsb2141fc2017-06-14 18:07:363#include "config.h"
Daniel Barkalowe496c002008-02-07 16:40:084#include "branch.h"
Elijah Newren32a8f512023-03-21 06:26:035#include "environment.h"
Elijah Newrenf394e092023-03-21 06:25:546#include "gettext.h"
Elijah Newren41771fa2023-02-24 00:09:277#include "hex.h"
Elijah Newrendabab1d2023-04-11 07:41:498#include "object-name.h"
Elijah Newrenc3399322023-05-16 06:33:599#include "path.h"
Daniel Barkalowe496c002008-02-07 16:40:0810#include "refs.h"
Brandon Williamsec0cb492018-05-16 22:57:4811#include "refspec.h"
Daniel Barkalowe496c002008-02-07 16:40:0812#include "remote.h"
Elijah Newrend1cbe1e2023-04-22 20:17:2013#include "repository.h"
Phillip Woodb07d9bf2019-04-16 10:18:4114#include "sequencer.h"
Daniel Barkalowe496c002008-02-07 16:40:0815#include "commit.h"
Michael Rappazzoac6c5612015-10-02 11:55:3116#include "worktree.h"
Glen Choo961b1302022-01-29 00:04:4517#include "submodule-config.h"
18#include "run-command.h"
Derrick Stolee31ad6b62022-06-14 19:27:2919#include "strmap.h"
Daniel Barkalowe496c002008-02-07 16:40:0820
21struct tracking {
Brandon Williams0ad4a5f2018-05-16 22:57:4922 struct refspec_item spec;
Josh Steadmond3115662021-12-21 03:30:2323 struct string_list *srcs;
Daniel Barkalowe496c002008-02-07 16:40:0824 const char *remote;
25 int matches;
26};
27
Tao Klerkse4921d82022-04-01 06:05:1328struct find_tracked_branch_cb {
29 struct tracking *tracking;
30 struct string_list ambiguous_remotes;
31};
32
Daniel Barkalowe496c002008-02-07 16:40:0833static int find_tracked_branch(struct remote *remote, void *priv)
34{
Tao Klerkse4921d82022-04-01 06:05:1335 struct find_tracked_branch_cb *ftb = priv;
36 struct tracking *tracking = ftb->tracking;
Daniel Barkalowe496c002008-02-07 16:40:0837
38 if (!remote_find_tracking(remote, &tracking->spec)) {
Tao Klerkse4921d82022-04-01 06:05:1339 switch (++tracking->matches) {
40 case 1:
Rubén Justo861c56f2023-06-11 18:50:3641 string_list_append_nodup(tracking->srcs, tracking->spec.src);
Daniel Barkalowe496c002008-02-07 16:40:0842 tracking->remote = remote->name;
Tao Klerkse4921d82022-04-01 06:05:1343 break;
44 case 2:
45 /* there are at least two remotes; backfill the first one */
46 string_list_append(&ftb->ambiguous_remotes, tracking->remote);
47 /* fall through */
48 default:
49 string_list_append(&ftb->ambiguous_remotes, remote->name);
Daniel Barkalowe496c002008-02-07 16:40:0850 free(tracking->spec.src);
Josh Steadmond3115662021-12-21 03:30:2351 string_list_clear(tracking->srcs, 0);
Tao Klerkse4921d82022-04-01 06:05:1352 break;
Daniel Barkalowe496c002008-02-07 16:40:0853 }
Tao Klerksbdaf1df2022-04-29 09:56:4454 /* remote_find_tracking() searches by src if present */
Daniel Barkalowe496c002008-02-07 16:40:0855 tracking->spec.src = NULL;
56 }
Daniel Barkalowe496c002008-02-07 16:40:0857 return 0;
58}
59
Junio C Hamanoa9f2c132009-03-04 06:29:5560static int should_setup_rebase(const char *origin)
Dustin Sallingsc998ae92008-05-10 22:36:2961{
62 switch (autorebase) {
63 case AUTOREBASE_NEVER:
64 return 0;
65 case AUTOREBASE_LOCAL:
Junio C Hamanoa9f2c132009-03-04 06:29:5566 return origin == NULL;
Dustin Sallingsc998ae92008-05-10 22:36:2967 case AUTOREBASE_REMOTE:
Junio C Hamanoa9f2c132009-03-04 06:29:5568 return origin != NULL;
Dustin Sallingsc998ae92008-05-10 22:36:2969 case AUTOREBASE_ALWAYS:
70 return 1;
71 }
72 return 0;
73}
74
Josh Steadmona3f40ec2021-12-21 03:30:2275/**
76 * Install upstream tracking configuration for a branch; specifically, add
77 * `branch.<name>.remote` and `branch.<name>.merge` entries.
78 *
79 * `flag` contains integer flags for options; currently only
80 * BRANCH_CONFIG_VERBOSE is checked.
81 *
82 * `local` is the name of the branch whose configuration we're installing.
83 *
84 * `origin` is the name of the remote owning the upstream branches. NULL means
85 * the upstream branches are local to this repo.
86 *
87 * `remotes` is a list of refs that are upstream of local
88 */
89static int install_branch_config_multiple_remotes(int flag, const char *local,
90 const char *origin, struct string_list *remotes)
Junio C Hamanoa9f2c132009-03-04 06:29:5591{
Jeff Kingcf4fff52014-06-18 19:44:1992 const char *shortname = NULL;
Junio C Hamanoa9f2c132009-03-04 06:29:5593 struct strbuf key = STRBUF_INIT;
Josh Steadmona3f40ec2021-12-21 03:30:2294 struct string_list_item *item;
Junio C Hamanoa9f2c132009-03-04 06:29:5595 int rebasing = should_setup_rebase(origin);
96
Josh Steadmona3f40ec2021-12-21 03:30:2297 if (!remotes->nr)
98 BUG("must provide at least one remote for branch config");
99 if (rebasing && remotes->nr > 1)
100 die(_("cannot inherit upstream tracking configuration of "
101 "multiple refs when rebasing is requested"));
102
103 /*
104 * If the new branch is trying to track itself, something has gone
105 * wrong. Warn the user and don't proceed any further.
106 */
107 if (!origin)
108 for_each_string_list_item(item, remotes)
109 if (skip_prefix(item->string, "refs/heads/", &shortname)
110 && !strcmp(local, shortname)) {
Junio C Hamano0669bdf2022-01-10 19:52:54111 warning(_("not setting branch '%s' as its own upstream"),
Josh Steadmona3f40ec2021-12-21 03:30:22112 local);
113 return 0;
114 }
Matthieu Moy85e22332010-01-18 20:44:12115
Junio C Hamanoa9f2c132009-03-04 06:29:55116 strbuf_addf(&key, "branch.%s.remote", local);
Patrick Steinhardt30598ad2016-02-22 11:23:35117 if (git_config_set_gently(key.buf, origin ? origin : ".") < 0)
Patrick Steinhardt27852b22016-02-22 11:23:23118 goto out_err;
Junio C Hamanoa9f2c132009-03-04 06:29:55119
120 strbuf_reset(&key);
121 strbuf_addf(&key, "branch.%s.merge", local);
Josh Steadmona3f40ec2021-12-21 03:30:22122 /*
123 * We want to overwrite any existing config with all the branches in
124 * "remotes". Override any existing config, then write our branches. If
125 * more than one is provided, use CONFIG_REGEX_NONE to preserve what
126 * we've written so far.
127 */
128 if (git_config_set_gently(key.buf, NULL) < 0)
Patrick Steinhardt27852b22016-02-22 11:23:23129 goto out_err;
Josh Steadmona3f40ec2021-12-21 03:30:22130 for_each_string_list_item(item, remotes)
131 if (git_config_set_multivar_gently(key.buf, item->string, CONFIG_REGEX_NONE, 0) < 0)
132 goto out_err;
Junio C Hamanoa9f2c132009-03-04 06:29:55133
134 if (rebasing) {
135 strbuf_reset(&key);
136 strbuf_addf(&key, "branch.%s.rebase", local);
Patrick Steinhardt30598ad2016-02-22 11:23:35137 if (git_config_set_gently(key.buf, "true") < 0)
Patrick Steinhardt27852b22016-02-22 11:23:23138 goto out_err;
Junio C Hamanoa9f2c132009-03-04 06:29:55139 }
Nguyễn Thái Ngọc Duyd53a35032012-06-07 12:05:10140 strbuf_release(&key);
Junio C Hamanoa9f2c132009-03-04 06:29:55141
Junio C Hamano72f60082009-03-10 08:20:42142 if (flag & BRANCH_CONFIG_VERBOSE) {
Josh Steadmona3f40ec2021-12-21 03:30:22143 struct strbuf tmp_ref_name = STRBUF_INIT;
144 struct string_list friendly_ref_names = STRING_LIST_INIT_DUP;
145
146 for_each_string_list_item(item, remotes) {
147 shortname = item->string;
148 skip_prefix(shortname, "refs/heads/", &shortname);
149 if (origin) {
150 strbuf_addf(&tmp_ref_name, "%s/%s",
151 origin, shortname);
152 string_list_append_nodup(
153 &friendly_ref_names,
154 strbuf_detach(&tmp_ref_name, NULL));
155 } else {
156 string_list_append(
157 &friendly_ref_names, shortname);
158 }
Adam9fe0cf32014-03-10 05:32:01159 }
Josh Steadmona3f40ec2021-12-21 03:30:22160
161 if (remotes->nr == 1) {
162 /*
163 * Rebasing is only allowed in the case of a single
164 * upstream branch.
165 */
166 printf_ln(rebasing ?
167 _("branch '%s' set up to track '%s' by rebasing.") :
168 _("branch '%s' set up to track '%s'."),
169 local, friendly_ref_names.items[0].string);
170 } else {
171 printf_ln(_("branch '%s' set up to track:"), local);
172 for_each_string_list_item(item, &friendly_ref_names)
173 printf_ln(" %s", item->string);
174 }
175
176 string_list_clear(&friendly_ref_names, 0);
Junio C Hamano72f60082009-03-10 08:20:42177 }
Patrick Steinhardt27852b22016-02-22 11:23:23178
179 return 0;
180
181out_err:
182 strbuf_release(&key);
Anders Kaseorg7435e7e2021-12-01 22:15:42183 error(_("unable to write upstream branch configuration"));
Patrick Steinhardt27852b22016-02-22 11:23:23184
Josh Steadmona3f40ec2021-12-21 03:30:22185 advise(_("\nAfter fixing the error cause you may try to fix up\n"
186 "the remote tracking information by invoking:"));
187 if (remotes->nr == 1)
188 advise(" git branch --set-upstream-to=%s%s%s",
189 origin ? origin : "",
190 origin ? "/" : "",
191 remotes->items[0].string);
192 else {
193 advise(" git config --add branch.\"%s\".remote %s",
194 local, origin ? origin : ".");
195 for_each_string_list_item(item, remotes)
196 advise(" git config --add branch.\"%s\".merge %s",
197 local, item->string);
198 }
Patrick Steinhardt27852b22016-02-22 11:23:23199
200 return -1;
Junio C Hamanoa9f2c132009-03-04 06:29:55201}
202
Josh Steadmona3f40ec2021-12-21 03:30:22203int install_branch_config(int flag, const char *local, const char *origin,
204 const char *remote)
205{
206 int ret;
207 struct string_list remotes = STRING_LIST_INIT_DUP;
208
209 string_list_append(&remotes, remote);
210 ret = install_branch_config_multiple_remotes(flag, local, origin, &remotes);
211 string_list_clear(&remotes, 0);
212 return ret;
213}
214
Josh Steadmond3115662021-12-21 03:30:23215static int inherit_tracking(struct tracking *tracking, const char *orig_ref)
216{
217 const char *bare_ref;
218 struct branch *branch;
219 int i;
220
221 bare_ref = orig_ref;
222 skip_prefix(orig_ref, "refs/heads/", &bare_ref);
223
224 branch = branch_get(bare_ref);
225 if (!branch->remote_name) {
226 warning(_("asked to inherit tracking from '%s', but no remote is set"),
227 bare_ref);
228 return -1;
229 }
230
231 if (branch->merge_nr < 1 || !branch->merge_name || !branch->merge_name[0]) {
232 warning(_("asked to inherit tracking from '%s', but no merge configuration is set"),
233 bare_ref);
234 return -1;
235 }
236
Rubén Justoa88a3d72023-06-11 18:50:16237 tracking->remote = branch->remote_name;
Josh Steadmond3115662021-12-21 03:30:23238 for (i = 0; i < branch->merge_nr; i++)
239 string_list_append(tracking->srcs, branch->merge_name[i]);
240 return 0;
241}
242
Daniel Barkalowe496c002008-02-07 16:40:08243/*
Glen Chooe89f1512022-01-29 00:04:41244 * Used internally to set the branch.<new_ref>.{remote,merge} config
245 * settings so that branch 'new_ref' tracks 'orig_ref'. Unlike
246 * dwim_and_setup_tracking(), this does not do DWIM, i.e. "origin/main"
247 * will not be expanded to "refs/remotes/origin/main", so it is not safe
248 * for 'orig_ref' to be raw user input.
Daniel Barkalowe496c002008-02-07 16:40:08249 */
Patrick Steinhardt27852b22016-02-22 11:23:23250static void setup_tracking(const char *new_ref, const char *orig_ref,
251 enum branch_track track, int quiet)
Daniel Barkalowe496c002008-02-07 16:40:08252{
Daniel Barkalowe496c002008-02-07 16:40:08253 struct tracking tracking;
Josh Steadmond3115662021-12-21 03:30:23254 struct string_list tracking_srcs = STRING_LIST_INIT_DUP;
Jeff Kingf9a482e2012-03-26 23:51:01255 int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
Tao Klerkse4921d82022-04-01 06:05:13256 struct find_tracked_branch_cb ftb_cb = {
257 .tracking = &tracking,
258 .ambiguous_remotes = STRING_LIST_INIT_DUP,
259 };
Daniel Barkalowe496c002008-02-07 16:40:08260
Glen Choo75388bf2022-03-29 20:01:16261 if (!track)
262 BUG("asked to set up tracking, but tracking is disallowed");
263
Daniel Barkalowe496c002008-02-07 16:40:08264 memset(&tracking, 0, sizeof(tracking));
265 tracking.spec.dst = (char *)orig_ref;
Josh Steadmond3115662021-12-21 03:30:23266 tracking.srcs = &tracking_srcs;
267 if (track != BRANCH_TRACK_INHERIT)
Tao Klerkse4921d82022-04-01 06:05:13268 for_each_remote(find_tracked_branch, &ftb_cb);
Josh Steadmond3115662021-12-21 03:30:23269 else if (inherit_tracking(&tracking, orig_ref))
Glen Choo679e3692022-01-29 00:04:46270 goto cleanup;
Daniel Barkalowe496c002008-02-07 16:40:08271
Jay Soffian9ed36cf2008-02-19 16:24:37272 if (!tracking.matches)
273 switch (track) {
Tao Klerksbdaf1df2022-04-29 09:56:44274 /* If ref is not remote, still use local */
Jay Soffian9ed36cf2008-02-19 16:24:37275 case BRANCH_TRACK_ALWAYS:
276 case BRANCH_TRACK_EXPLICIT:
Ilari Liusvaara4fc50062010-01-18 20:44:11277 case BRANCH_TRACK_OVERRIDE:
Tao Klerksbdaf1df2022-04-29 09:56:44278 /* Remote matches not evaluated */
Josh Steadmond3115662021-12-21 03:30:23279 case BRANCH_TRACK_INHERIT:
Jay Soffian9ed36cf2008-02-19 16:24:37280 break;
Tao Klerksbdaf1df2022-04-29 09:56:44281 /* Otherwise, if no remote don't track */
Jay Soffian9ed36cf2008-02-19 16:24:37282 default:
Glen Choo679e3692022-01-29 00:04:46283 goto cleanup;
Jay Soffian9ed36cf2008-02-19 16:24:37284 }
285
Tao Klerksbdaf1df2022-04-29 09:56:44286 /*
287 * This check does not apply to BRANCH_TRACK_INHERIT;
288 * that supports multiple entries in tracking_srcs but
289 * leaves tracking.matches at 0.
290 */
Tao Klerkse4921d82022-04-01 06:05:13291 if (tracking.matches > 1) {
292 int status = die_message(_("not tracking: ambiguous information for ref '%s'"),
293 orig_ref);
294 if (advice_enabled(ADVICE_AMBIGUOUS_FETCH_REFSPEC)) {
295 struct strbuf remotes_advice = STRBUF_INIT;
296 struct string_list_item *item;
297
298 for_each_string_list_item(item, &ftb_cb.ambiguous_remotes)
299 /*
300 * TRANSLATORS: This is a line listing a remote with duplicate
301 * refspecs in the advice message below. For RTL languages you'll
302 * probably want to swap the "%s" and leading " " space around.
303 */
304 strbuf_addf(&remotes_advice, _(" %s\n"), item->string);
305
306 /*
307 * TRANSLATORS: The second argument is a \n-delimited list of
308 * duplicate refspecs, composed above.
309 */
310 advise(_("There are multiple remotes whose fetch refspecs map to the remote\n"
311 "tracking ref '%s':\n"
312 "%s"
313 "\n"
314 "This is typically a configuration error.\n"
315 "\n"
316 "To support setting up tracking branches, ensure that\n"
317 "different remotes' fetch refspecs map into different\n"
318 "tracking namespaces."), orig_ref,
319 remotes_advice.buf);
320 strbuf_release(&remotes_advice);
321 }
322 exit(status);
323 }
Daniel Barkalowe496c002008-02-07 16:40:08324
Tao Klerksbdaf1df2022-04-29 09:56:44325 if (track == BRANCH_TRACK_SIMPLE) {
326 /*
327 * Only track if remote branch name matches.
328 * Reaching into items[0].string is safe because
329 * we know there is at least one and not more than
330 * one entry (because only BRANCH_TRACK_INHERIT can
331 * produce more than one entry).
332 */
333 const char *tracked_branch;
334 if (!skip_prefix(tracking.srcs->items[0].string,
335 "refs/heads/", &tracked_branch) ||
336 strcmp(tracked_branch, new_ref))
Rubén Justo5ace4832023-06-17 06:41:08337 goto cleanup;
Tao Klerksbdaf1df2022-04-29 09:56:44338 }
339
Josh Steadmond3115662021-12-21 03:30:23340 if (tracking.srcs->nr < 1)
341 string_list_append(tracking.srcs, orig_ref);
342 if (install_branch_config_multiple_remotes(config_flags, new_ref,
343 tracking.remote, tracking.srcs) < 0)
Glen Choo5391e942022-03-29 20:01:19344 exit(1);
Daniel Barkalowe496c002008-02-07 16:40:08345
Glen Choo679e3692022-01-29 00:04:46346cleanup:
347 string_list_clear(&tracking_srcs, 0);
Tao Klerkse4921d82022-04-01 06:05:13348 string_list_clear(&ftb_cb.ambiguous_remotes, 0);
Daniel Barkalowe496c002008-02-07 16:40:08349}
350
Junio C Hamano6f9a3322011-09-22 03:19:38351int read_branch_desc(struct strbuf *buf, const char *branch_name)
352{
Tanay Abhra540b0f42014-08-07 17:56:42353 char *v = NULL;
Junio C Hamano6f9a3322011-09-22 03:19:38354 struct strbuf name = STRBUF_INIT;
355 strbuf_addf(&name, "branch.%s.description", branch_name);
Tanay Abhra540b0f42014-08-07 17:56:42356 if (git_config_get_string(name.buf, &v)) {
357 strbuf_release(&name);
358 return -1;
359 }
360 strbuf_addstr(buf, v);
361 free(v);
Junio C Hamano6f9a3322011-09-22 03:19:38362 strbuf_release(&name);
363 return 0;
364}
365
Junio C Hamanobc1c9c02017-10-13 04:45:40366/*
367 * Check if 'name' can be a valid name for a branch; die otherwise.
368 * Return 1 if the named branch already exists; return 0 otherwise.
369 * Fill ref with the full refname for the branch.
370 */
371int validate_branchname(const char *name, struct strbuf *ref)
Conrad Irwin55c4a672011-08-20 21:49:48372{
Conrad Irwin55c4a672011-08-20 21:49:48373 if (strbuf_check_branch_ref(ref, name))
Anders Kaseorg7435e7e2021-12-01 22:15:42374 die(_("'%s' is not a valid branch name"), name);
Conrad Irwin55c4a672011-08-20 21:49:48375
Junio C Hamanobc1c9c02017-10-13 04:45:40376 return ref_exists(ref->buf);
377}
Conrad Irwin55c4a672011-08-20 21:49:48378
Derrick Stolee31ad6b62022-06-14 19:27:29379static int initialized_checked_out_branches;
380static struct strmap current_checked_out_branches = STRMAP_INIT;
381
382static void prepare_checked_out_branches(void)
383{
384 int i = 0;
385 struct worktree **worktrees;
386
387 if (initialized_checked_out_branches)
388 return;
389 initialized_checked_out_branches = 1;
390
391 worktrees = get_worktrees();
392
393 while (worktrees[i]) {
Derrick Stolee4b6e18f2022-06-14 19:27:33394 char *old;
Derrick Stoleed2ba2712022-06-14 19:27:30395 struct wt_status_state state = { 0 };
Derrick Stolee31ad6b62022-06-14 19:27:29396 struct worktree *wt = worktrees[i++];
Derrick Stoleeaa7f2fd2022-07-19 18:33:35397 struct string_list update_refs = STRING_LIST_INIT_DUP;
Derrick Stolee31ad6b62022-06-14 19:27:29398
399 if (wt->is_bare)
400 continue;
401
Derrick Stolee4b6e18f2022-06-14 19:27:33402 if (wt->head_ref) {
403 old = strmap_put(&current_checked_out_branches,
404 wt->head_ref,
405 xstrdup(wt->path));
406 free(old);
407 }
Derrick Stoleed2ba2712022-06-14 19:27:30408
409 if (wt_status_check_rebase(wt, &state) &&
410 (state.rebase_in_progress || state.rebase_interactive_in_progress) &&
411 state.branch) {
412 struct strbuf ref = STRBUF_INIT;
413 strbuf_addf(&ref, "refs/heads/%s", state.branch);
Derrick Stolee4b6e18f2022-06-14 19:27:33414 old = strmap_put(&current_checked_out_branches,
415 ref.buf,
416 xstrdup(wt->path));
417 free(old);
Derrick Stoleed2ba2712022-06-14 19:27:30418 strbuf_release(&ref);
419 }
420 wt_status_state_free_buffers(&state);
421
422 if (wt_status_check_bisect(wt, &state) &&
Rubén Justo990adcc2023-09-09 20:12:47423 state.bisecting_from) {
Derrick Stoleed2ba2712022-06-14 19:27:30424 struct strbuf ref = STRBUF_INIT;
Rubén Justo990adcc2023-09-09 20:12:47425 strbuf_addf(&ref, "refs/heads/%s", state.bisecting_from);
Derrick Stolee4b6e18f2022-06-14 19:27:33426 old = strmap_put(&current_checked_out_branches,
427 ref.buf,
428 xstrdup(wt->path));
429 free(old);
Derrick Stoleed2ba2712022-06-14 19:27:30430 strbuf_release(&ref);
431 }
432 wt_status_state_free_buffers(&state);
Derrick Stoleeaa7f2fd2022-07-19 18:33:35433
434 if (!sequencer_get_update_refs_state(get_worktree_git_dir(wt),
435 &update_refs)) {
436 struct string_list_item *item;
437 for_each_string_list_item(item, &update_refs) {
438 old = strmap_put(&current_checked_out_branches,
439 item->string,
440 xstrdup(wt->path));
441 free(old);
442 }
443 string_list_clear(&update_refs, 1);
444 }
Derrick Stolee31ad6b62022-06-14 19:27:29445 }
446
447 free_worktrees(worktrees);
448}
449
450const char *branch_checked_out(const char *refname)
451{
452 prepare_checked_out_branches();
453 return strmap_get(&current_checked_out_branches, refname);
454}
455
Junio C Hamanobc1c9c02017-10-13 04:45:40456/*
457 * Check if a branch 'name' can be created as a new branch; die otherwise.
458 * 'force' can be used when it is OK for the named branch already exists.
459 * Return 1 if the named branch already exists; return 0 otherwise.
460 * Fill ref with the full refname for the branch.
461 */
462int validate_new_branchname(const char *name, struct strbuf *ref, int force)
463{
Derrick Stoleed2ba2712022-06-14 19:27:30464 const char *path;
Junio C Hamanobc1c9c02017-10-13 04:45:40465 if (!validate_branchname(name, ref))
Conrad Irwin55c4a672011-08-20 21:49:48466 return 0;
Conrad Irwin55c4a672011-08-20 21:49:48467
Junio C Hamano8280c4c2017-10-13 03:57:02468 if (!force)
Anders Kaseorg7435e7e2021-12-01 22:15:42469 die(_("a branch named '%s' already exists"),
Junio C Hamano8280c4c2017-10-13 03:57:02470 ref->buf + strlen("refs/heads/"));
Conrad Irwin55c4a672011-08-20 21:49:48471
Derrick Stoleed2ba2712022-06-14 19:27:30472 if ((path = branch_checked_out(ref->buf)))
Bagas Sanjaya68d924e2022-01-11 12:36:27473 die(_("cannot force update the branch '%s' "
Junio C Hamano4970bed2023-07-21 21:53:12474 "used by worktree at '%s'"),
Derrick Stoleed2ba2712022-06-14 19:27:30475 ref->buf + strlen("refs/heads/"), path);
Junio C Hamano8280c4c2017-10-13 03:57:02476
Conrad Irwin55c4a672011-08-20 21:49:48477 return 1;
478}
479
Johan Herland41c21f22013-04-21 21:52:05480static int check_tracking_branch(struct remote *remote, void *cb_data)
481{
482 char *tracking_branch = cb_data;
Brandon Williams0ad4a5f2018-05-16 22:57:49483 struct refspec_item query;
Rubén Justocaee1d62023-06-11 18:50:27484 int res;
Brandon Williams0ad4a5f2018-05-16 22:57:49485 memset(&query, 0, sizeof(struct refspec_item));
Johan Herland41c21f22013-04-21 21:52:05486 query.dst = tracking_branch;
Rubén Justocaee1d62023-06-11 18:50:27487 res = !remote_find_tracking(remote, &query);
488 free(query.src);
489 return res;
Johan Herland41c21f22013-04-21 21:52:05490}
491
492static int validate_remote_tracking_branch(char *ref)
493{
494 return !for_each_remote(check_tracking_branch, ref);
495}
496
Jeff Kinge2b6aa52013-04-02 19:03:55497static const char upstream_not_branch[] =
Anders Kaseorg7435e7e2021-12-01 22:15:42498N_("cannot set up tracking information; starting point '%s' is not a branch");
Jeff Kinga5e91c72013-04-02 19:04:27499static const char upstream_missing[] =
Jeff Kingcaa20362013-04-02 19:05:12500N_("the requested upstream branch '%s' does not exist");
501static const char upstream_advice[] =
502N_("\n"
503"If you are planning on basing your work on an upstream\n"
504"branch that already exists at the remote, you may need to\n"
505"run \"git fetch\" to retrieve it.\n"
506"\n"
507"If you are planning to push out a new local branch that\n"
508"will track its remote counterpart, you may want to use\n"
509"\"git push -u\" to set the upstream config as you push.");
Jeff Kinge2b6aa52013-04-02 19:03:55510
Glen Chooe89f1512022-01-29 00:04:41511/**
512 * DWIMs a user-provided ref to determine the starting point for a
513 * branch and validates it, where:
514 *
515 * - r is the repository to validate the branch for
516 *
517 * - start_name is the ref that we would like to test. This is
518 * expanded with DWIM and assigned to out_real_ref.
519 *
520 * - track is the tracking mode of the new branch. If tracking is
521 * explicitly requested, start_name must be a branch (because
522 * otherwise start_name cannot be tracked)
523 *
524 * - out_oid is an out parameter containing the object_id of start_name
525 *
526 * - out_real_ref is an out parameter containing the full, 'real' form
527 * of start_name e.g. refs/heads/main instead of main
528 *
529 */
530static void dwim_branch_start(struct repository *r, const char *start_name,
531 enum branch_track track, char **out_real_ref,
532 struct object_id *out_oid)
Daniel Barkalowe496c002008-02-07 16:40:08533{
Daniel Barkalowe496c002008-02-07 16:40:08534 struct commit *commit;
brian m. carlson48713bf2017-05-01 02:29:00535 struct object_id oid;
Jeff King3818b252017-03-28 19:46:36536 char *real_ref;
Ilari Liusvaara4fc50062010-01-18 20:44:11537 int explicit_tracking = 0;
538
539 if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
540 explicit_tracking = 1;
Daniel Barkalowe496c002008-02-07 16:40:08541
Daniel Barkalowe496c002008-02-07 16:40:08542 real_ref = NULL;
Ævar Arnfjörð Bjarmason4a93b892023-03-28 13:58:58543 if (repo_get_oid_mb(r, start_name, &oid)) {
Jeff Kingcaa20362013-04-02 19:05:12544 if (explicit_tracking) {
Glen Choo66966012022-03-31 22:41:18545 int code = die_message(_(upstream_missing), start_name);
546 advise_if_enabled(ADVICE_SET_UPSTREAM_FAILURE,
547 _(upstream_advice));
548 exit(code);
Jeff Kingcaa20362013-04-02 19:05:12549 }
Anders Kaseorg7435e7e2021-12-01 22:15:42550 die(_("not a valid object name: '%s'"), start_name);
Jeff Kinga5e91c72013-04-02 19:04:27551 }
Daniel Barkalowe496c002008-02-07 16:40:08552
Ævar Arnfjörð Bjarmason4a93b892023-03-28 13:58:58553 switch (repo_dwim_ref(r, start_name, strlen(start_name), &oid,
554 &real_ref, 0)) {
Daniel Barkalowe496c002008-02-07 16:40:08555 case 0:
556 /* Not branching from any existing branch */
Ilari Liusvaara4fc50062010-01-18 20:44:11557 if (explicit_tracking)
Jeff King1a15d002013-04-02 19:04:51558 die(_(upstream_not_branch), start_name);
Daniel Barkalowe496c002008-02-07 16:40:08559 break;
560 case 1:
Johan Herland21b5b1e2011-02-16 23:12:20561 /* Unique completion -- good, only if it is a real branch */
Christian Couder59556542013-11-30 20:55:40562 if (!starts_with(real_ref, "refs/heads/") &&
Johan Herland41c21f22013-04-21 21:52:05563 validate_remote_tracking_branch(real_ref)) {
Johan Herland21b5b1e2011-02-16 23:12:20564 if (explicit_tracking)
Jeff King1a15d002013-04-02 19:04:51565 die(_(upstream_not_branch), start_name);
Johan Herland21b5b1e2011-02-16 23:12:20566 else
Andrzej Huntd8958042021-04-25 14:16:12567 FREE_AND_NULL(real_ref);
Johan Herland21b5b1e2011-02-16 23:12:20568 }
Daniel Barkalowe496c002008-02-07 16:40:08569 break;
570 default:
Anders Kaseorg7435e7e2021-12-01 22:15:42571 die(_("ambiguous object name: '%s'"), start_name);
Daniel Barkalowe496c002008-02-07 16:40:08572 break;
573 }
574
Junio C Hamanoafe8a902022-05-02 16:50:37575 if (!(commit = lookup_commit_reference(r, &oid)))
Anders Kaseorg7435e7e2021-12-01 22:15:42576 die(_("not a valid branch point: '%s'"), start_name);
Glen Chooe89f1512022-01-29 00:04:41577 if (out_real_ref) {
578 *out_real_ref = real_ref;
579 real_ref = NULL;
580 }
581 if (out_oid)
582 oidcpy(out_oid, &commit->object.oid);
583
584 FREE_AND_NULL(real_ref);
585}
586
587void create_branch(struct repository *r,
588 const char *name, const char *start_name,
589 int force, int clobber_head_ok, int reflog,
Glen Choo3f3e7602022-01-29 00:04:43590 int quiet, enum branch_track track, int dry_run)
Glen Chooe89f1512022-01-29 00:04:41591{
592 struct object_id oid;
593 char *real_ref;
594 struct strbuf ref = STRBUF_INIT;
595 int forcing = 0;
Glen Choobc0893c2022-01-29 00:04:42596 struct ref_transaction *transaction;
597 struct strbuf err = STRBUF_INIT;
598 char *msg;
Glen Chooe89f1512022-01-29 00:04:41599
Glen Choobc0893c2022-01-29 00:04:42600 if (track == BRANCH_TRACK_OVERRIDE)
601 BUG("'track' cannot be BRANCH_TRACK_OVERRIDE. Did you mean to call dwim_and_setup_tracking()?");
602 if (clobber_head_ok && !force)
603 BUG("'clobber_head_ok' can only be used with 'force'");
604
605 if (clobber_head_ok ?
606 validate_branchname(name, &ref) :
607 validate_new_branchname(name, &ref, force)) {
608 forcing = 1;
Glen Chooe89f1512022-01-29 00:04:41609 }
610
611 dwim_branch_start(r, start_name, track, &real_ref, &oid);
Glen Choo3f3e7602022-01-29 00:04:43612 if (dry_run)
613 goto cleanup;
Daniel Barkalowe496c002008-02-07 16:40:08614
Ronnie Sahlbergd43f9902014-04-16 23:21:53615 if (reflog)
Cornelius Weig341fb282017-01-27 10:09:47616 log_all_ref_updates = LOG_REFS_NORMAL;
Ronnie Sahlbergd43f9902014-04-16 23:21:53617
Glen Choobc0893c2022-01-29 00:04:42618 if (forcing)
619 msg = xstrfmt("branch: Reset to %s", start_name);
620 else
621 msg = xstrfmt("branch: Created from %s", start_name);
622 transaction = ref_transaction_begin(&err);
623 if (!transaction ||
624 ref_transaction_update(transaction, ref.buf,
625 &oid, forcing ? NULL : null_oid(),
626 0, msg, &err) ||
627 ref_transaction_commit(transaction, &err))
628 die("%s", err.buf);
629 ref_transaction_free(transaction);
630 strbuf_release(&err);
631 free(msg);
Ronnie Sahlbergd43f9902014-04-16 23:21:53632
Daniel Barkalowe496c002008-02-07 16:40:08633 if (real_ref && track)
Felipe Contreras82a06722013-08-30 21:56:46634 setup_tracking(ref.buf + 11, real_ref, track, quiet);
Daniel Barkalowe496c002008-02-07 16:40:08635
Glen Choo3f3e7602022-01-29 00:04:43636cleanup:
Junio C Hamano8415d5c2009-02-14 07:08:05637 strbuf_release(&ref);
Jay Soffian9ed36cf2008-02-19 16:24:37638 free(real_ref);
Daniel Barkalowe496c002008-02-07 16:40:08639}
Daniel Barkalowc369e7b2008-02-07 16:40:16640
Glen Chooe89f1512022-01-29 00:04:41641void dwim_and_setup_tracking(struct repository *r, const char *new_ref,
642 const char *orig_ref, enum branch_track track,
643 int quiet)
644{
Rubén Justo1533bda2023-06-11 18:49:43645 char *real_orig_ref = NULL;
Glen Chooe89f1512022-01-29 00:04:41646 dwim_branch_start(r, orig_ref, track, &real_orig_ref, NULL);
647 setup_tracking(new_ref, real_orig_ref, track, quiet);
Rubén Justo1533bda2023-06-11 18:49:43648 free(real_orig_ref);
Glen Chooe89f1512022-01-29 00:04:41649}
650
Glen Choo961b1302022-01-29 00:04:45651/**
652 * Creates a branch in a submodule by calling
653 * create_branches_recursively() in a child process. The child process
654 * is necessary because install_branch_config_multiple_remotes() (which
655 * is called by setup_tracking()) does not support writing configs to
656 * submodules.
657 */
658static int submodule_create_branch(struct repository *r,
659 const struct submodule *submodule,
660 const char *name, const char *start_oid,
661 const char *tracking_name, int force,
662 int reflog, int quiet,
663 enum branch_track track, int dry_run)
664{
665 int ret = 0;
666 struct child_process child = CHILD_PROCESS_INIT;
667 struct strbuf child_err = STRBUF_INIT;
668 struct strbuf out_buf = STRBUF_INIT;
669 char *out_prefix = xstrfmt("submodule '%s': ", submodule->name);
670 child.git_cmd = 1;
671 child.err = -1;
672 child.stdout_to_stderr = 1;
673
Ævar Arnfjörð Bjarmason29fda242022-06-02 09:09:50674 prepare_other_repo_env(&child.env, r->gitdir);
Glen Choo961b1302022-01-29 00:04:45675 /*
676 * submodule_create_branch() is indirectly invoked by "git
677 * branch", but we cannot invoke "git branch" in the child
678 * process. "git branch" accepts a branch name and start point,
679 * where the start point is assumed to provide both the OID
680 * (start_oid) and the branch to use for tracking
681 * (tracking_name). But when recursing through submodules,
682 * start_oid and tracking name need to be specified separately
683 * (see create_branches_recursively()).
684 */
685 strvec_pushl(&child.args, "submodule--helper", "create-branch", NULL);
686 if (dry_run)
687 strvec_push(&child.args, "--dry-run");
688 if (force)
689 strvec_push(&child.args, "--force");
690 if (quiet)
691 strvec_push(&child.args, "--quiet");
692 if (reflog)
693 strvec_push(&child.args, "--create-reflog");
Glen Choo75388bf2022-03-29 20:01:16694
695 switch (track) {
696 case BRANCH_TRACK_NEVER:
697 strvec_push(&child.args, "--no-track");
698 break;
699 case BRANCH_TRACK_ALWAYS:
700 case BRANCH_TRACK_EXPLICIT:
701 strvec_push(&child.args, "--track=direct");
702 break;
703 case BRANCH_TRACK_OVERRIDE:
704 BUG("BRANCH_TRACK_OVERRIDE cannot be used when creating a branch.");
705 break;
706 case BRANCH_TRACK_INHERIT:
707 strvec_push(&child.args, "--track=inherit");
708 break;
709 case BRANCH_TRACK_UNSPECIFIED:
Glen Choo1f888282022-03-31 22:41:17710 /* Default for "git checkout". Do not pass --track. */
Glen Choo75388bf2022-03-29 20:01:16711 case BRANCH_TRACK_REMOTE:
Glen Choo1f888282022-03-31 22:41:17712 /* Default for "git branch". Do not pass --track. */
Tao Klerksbdaf1df2022-04-29 09:56:44713 case BRANCH_TRACK_SIMPLE:
714 /* Config-driven only. Do not pass --track. */
Glen Choo75388bf2022-03-29 20:01:16715 break;
716 }
Glen Choo961b1302022-01-29 00:04:45717
718 strvec_pushl(&child.args, name, start_oid, tracking_name, NULL);
719
720 if ((ret = start_command(&child)))
721 return ret;
722 ret = finish_command(&child);
723 strbuf_read(&child_err, child.err, 0);
724 strbuf_add_lines(&out_buf, out_prefix, child_err.buf, child_err.len);
725
726 if (ret)
727 fprintf(stderr, "%s", out_buf.buf);
728 else
729 printf("%s", out_buf.buf);
730
731 strbuf_release(&child_err);
732 strbuf_release(&out_buf);
733 return ret;
734}
735
736void create_branches_recursively(struct repository *r, const char *name,
737 const char *start_commitish,
738 const char *tracking_name, int force,
739 int reflog, int quiet, enum branch_track track,
740 int dry_run)
741{
742 int i = 0;
743 char *branch_point = NULL;
744 struct object_id super_oid;
745 struct submodule_entry_list submodule_entry_list;
746
747 /* Perform dwim on start_commitish to get super_oid and branch_point. */
748 dwim_branch_start(r, start_commitish, BRANCH_TRACK_NEVER,
749 &branch_point, &super_oid);
750
751 /*
752 * If we were not given an explicit name to track, then assume we are at
753 * the top level and, just like the non-recursive case, the tracking
754 * name is the branch point.
755 */
756 if (!tracking_name)
757 tracking_name = branch_point;
758
759 submodules_of_tree(r, &super_oid, &submodule_entry_list);
760 /*
761 * Before creating any branches, first check that the branch can
762 * be created in every submodule.
763 */
764 for (i = 0; i < submodule_entry_list.entry_nr; i++) {
Junio C Hamanoe6bf70d2022-05-02 17:18:22765 if (!submodule_entry_list.entries[i].repo) {
Glen Choocfbda6b2022-03-29 20:01:17766 int code = die_message(
767 _("submodule '%s': unable to find submodule"),
768 submodule_entry_list.entries[i].submodule->name);
Glen Choo961b1302022-01-29 00:04:45769 if (advice_enabled(ADVICE_SUBMODULES_NOT_UPDATED))
Philippe Blain97cf0c72023-01-16 17:41:48770 advise(_("You may try updating the submodules using 'git checkout --no-recurse-submodules %s && git submodule update --init'"),
Glen Choo961b1302022-01-29 00:04:45771 start_commitish);
Glen Choocfbda6b2022-03-29 20:01:17772 exit(code);
Glen Choo961b1302022-01-29 00:04:45773 }
774
775 if (submodule_create_branch(
776 submodule_entry_list.entries[i].repo,
777 submodule_entry_list.entries[i].submodule, name,
778 oid_to_hex(&submodule_entry_list.entries[i]
779 .name_entry->oid),
780 tracking_name, force, reflog, quiet, track, 1))
781 die(_("submodule '%s': cannot create branch '%s'"),
782 submodule_entry_list.entries[i].submodule->name,
783 name);
784 }
785
Ævar Arnfjörð Bjarmason4a93b892023-03-28 13:58:58786 create_branch(r, name, start_commitish, force, 0, reflog, quiet,
Glen Choo961b1302022-01-29 00:04:45787 BRANCH_TRACK_NEVER, dry_run);
788 if (dry_run)
789 return;
790 /*
791 * NEEDSWORK If tracking was set up in the superproject but not the
792 * submodule, users might expect "git branch --recurse-submodules" to
793 * fail or give a warning, but this is not yet implemented because it is
794 * tedious to determine whether or not tracking was set up in the
795 * superproject.
796 */
Glen Choo75388bf2022-03-29 20:01:16797 if (track)
798 setup_tracking(name, tracking_name, track, quiet);
Glen Choo961b1302022-01-29 00:04:45799
800 for (i = 0; i < submodule_entry_list.entry_nr; i++) {
801 if (submodule_create_branch(
802 submodule_entry_list.entries[i].repo,
803 submodule_entry_list.entries[i].submodule, name,
804 oid_to_hex(&submodule_entry_list.entries[i]
805 .name_entry->oid),
806 tracking_name, force, reflog, quiet, track, 0))
807 die(_("submodule '%s': cannot create branch '%s'"),
808 submodule_entry_list.entries[i].submodule->name,
809 name);
810 repo_clear(submodule_entry_list.entries[i].repo);
811 }
812}
813
Nguyễn Thái Ngọc Duyb6433552019-05-09 10:10:27814void remove_merge_branch_state(struct repository *r)
Daniel Barkalowc369e7b2008-02-07 16:40:16815{
Nguyễn Thái Ngọc Duy4edce172018-11-10 05:49:00816 unlink(git_path_merge_head(r));
817 unlink(git_path_merge_rr(r));
818 unlink(git_path_merge_msg(r));
819 unlink(git_path_merge_mode(r));
Elijah Newren52918282021-03-20 00:03:52820 unlink(git_path_auto_merge(r));
Denton Liua03b5552020-04-07 14:28:07821 save_autostash(git_path_merge_autostash(r));
Nguyễn Thái Ngọc Duyb6433552019-05-09 10:10:27822}
823
Junio C Hamanof496b062019-07-09 22:25:44824void remove_branch_state(struct repository *r, int verbose)
Nguyễn Thái Ngọc Duyb6433552019-05-09 10:10:27825{
Junio C Hamanof496b062019-07-09 22:25:44826 sequencer_post_commit_cleanup(r, verbose);
Nguyễn Thái Ngọc Duy4edce172018-11-10 05:49:00827 unlink(git_path_squash_msg(r));
Nguyễn Thái Ngọc Duyb6433552019-05-09 10:10:27828 remove_merge_branch_state(r);
Daniel Barkalowc369e7b2008-02-07 16:40:16829}
Eric Sunshineed89f842015-07-17 23:00:04830
Nguyễn Thái Ngọc Duy8d9fdd72016-04-22 13:01:33831void die_if_checked_out(const char *branch, int ignore_current_worktree)
David Turner41af6562015-08-10 17:52:44832{
Anders Kaseorgc8dd4912021-12-01 22:15:43833 struct worktree **worktrees = get_worktrees();
David Turner41af6562015-08-10 17:52:44834
Rubén Justofaa4d592023-02-25 14:22:02835 for (int i = 0; worktrees[i]; i++) {
836 if (worktrees[i]->is_current && ignore_current_worktree)
837 continue;
838
839 if (is_shared_symref(worktrees[i], "HEAD", branch)) {
840 skip_prefix(branch, "refs/heads/", &branch);
Rubén Justo2a499262023-08-07 20:42:40841 die(_("'%s' is already used by worktree at '%s'"),
Rubén Justofaa4d592023-02-25 14:22:02842 branch, worktrees[i]->path);
843 }
Anders Kaseorgc8dd4912021-12-01 22:15:43844 }
845
846 free_worktrees(worktrees);
Eric Sunshineed89f842015-07-17 23:00:04847}