🌐 AI搜索 & 代理 主页
blob: e4a738fc7beba95b10fa40d32b428411d6cdae15 [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{
Kristoffer Haugsbakk8fbd9032024-03-05 20:29:43373 if (strbuf_check_branch_ref(ref, name)) {
374 int code = die_message(_("'%s' is not a valid branch name"), name);
375 advise_if_enabled(ADVICE_REF_SYNTAX,
376 _("See `man git check-ref-format`"));
377 exit(code);
378 }
Conrad Irwin55c4a672011-08-20 21:49:48379
Junio C Hamanobc1c9c02017-10-13 04:45:40380 return ref_exists(ref->buf);
381}
Conrad Irwin55c4a672011-08-20 21:49:48382
Derrick Stolee31ad6b62022-06-14 19:27:29383static int initialized_checked_out_branches;
384static struct strmap current_checked_out_branches = STRMAP_INIT;
385
386static void prepare_checked_out_branches(void)
387{
388 int i = 0;
389 struct worktree **worktrees;
390
391 if (initialized_checked_out_branches)
392 return;
393 initialized_checked_out_branches = 1;
394
395 worktrees = get_worktrees();
396
397 while (worktrees[i]) {
Derrick Stolee4b6e18f2022-06-14 19:27:33398 char *old;
Derrick Stoleed2ba2712022-06-14 19:27:30399 struct wt_status_state state = { 0 };
Derrick Stolee31ad6b62022-06-14 19:27:29400 struct worktree *wt = worktrees[i++];
Derrick Stoleeaa7f2fd2022-07-19 18:33:35401 struct string_list update_refs = STRING_LIST_INIT_DUP;
Derrick Stolee31ad6b62022-06-14 19:27:29402
403 if (wt->is_bare)
404 continue;
405
Derrick Stolee4b6e18f2022-06-14 19:27:33406 if (wt->head_ref) {
407 old = strmap_put(&current_checked_out_branches,
408 wt->head_ref,
409 xstrdup(wt->path));
410 free(old);
411 }
Derrick Stoleed2ba2712022-06-14 19:27:30412
413 if (wt_status_check_rebase(wt, &state) &&
414 (state.rebase_in_progress || state.rebase_interactive_in_progress) &&
415 state.branch) {
416 struct strbuf ref = STRBUF_INIT;
417 strbuf_addf(&ref, "refs/heads/%s", state.branch);
Derrick Stolee4b6e18f2022-06-14 19:27:33418 old = strmap_put(&current_checked_out_branches,
419 ref.buf,
420 xstrdup(wt->path));
421 free(old);
Derrick Stoleed2ba2712022-06-14 19:27:30422 strbuf_release(&ref);
423 }
424 wt_status_state_free_buffers(&state);
425
426 if (wt_status_check_bisect(wt, &state) &&
Rubén Justo990adcc2023-09-09 20:12:47427 state.bisecting_from) {
Derrick Stoleed2ba2712022-06-14 19:27:30428 struct strbuf ref = STRBUF_INIT;
Rubén Justo990adcc2023-09-09 20:12:47429 strbuf_addf(&ref, "refs/heads/%s", state.bisecting_from);
Derrick Stolee4b6e18f2022-06-14 19:27:33430 old = strmap_put(&current_checked_out_branches,
431 ref.buf,
432 xstrdup(wt->path));
433 free(old);
Derrick Stoleed2ba2712022-06-14 19:27:30434 strbuf_release(&ref);
435 }
436 wt_status_state_free_buffers(&state);
Derrick Stoleeaa7f2fd2022-07-19 18:33:35437
438 if (!sequencer_get_update_refs_state(get_worktree_git_dir(wt),
439 &update_refs)) {
440 struct string_list_item *item;
441 for_each_string_list_item(item, &update_refs) {
442 old = strmap_put(&current_checked_out_branches,
443 item->string,
444 xstrdup(wt->path));
445 free(old);
446 }
447 string_list_clear(&update_refs, 1);
448 }
Derrick Stolee31ad6b62022-06-14 19:27:29449 }
450
451 free_worktrees(worktrees);
452}
453
454const char *branch_checked_out(const char *refname)
455{
456 prepare_checked_out_branches();
457 return strmap_get(&current_checked_out_branches, refname);
458}
459
Junio C Hamanobc1c9c02017-10-13 04:45:40460/*
461 * Check if a branch 'name' can be created as a new branch; die otherwise.
462 * 'force' can be used when it is OK for the named branch already exists.
463 * Return 1 if the named branch already exists; return 0 otherwise.
464 * Fill ref with the full refname for the branch.
465 */
466int validate_new_branchname(const char *name, struct strbuf *ref, int force)
467{
Derrick Stoleed2ba2712022-06-14 19:27:30468 const char *path;
Junio C Hamanobc1c9c02017-10-13 04:45:40469 if (!validate_branchname(name, ref))
Conrad Irwin55c4a672011-08-20 21:49:48470 return 0;
Conrad Irwin55c4a672011-08-20 21:49:48471
Junio C Hamano8280c4c2017-10-13 03:57:02472 if (!force)
Anders Kaseorg7435e7e2021-12-01 22:15:42473 die(_("a branch named '%s' already exists"),
Junio C Hamano8280c4c2017-10-13 03:57:02474 ref->buf + strlen("refs/heads/"));
Conrad Irwin55c4a672011-08-20 21:49:48475
Derrick Stoleed2ba2712022-06-14 19:27:30476 if ((path = branch_checked_out(ref->buf)))
Bagas Sanjaya68d924e2022-01-11 12:36:27477 die(_("cannot force update the branch '%s' "
Junio C Hamano4970bed2023-07-21 21:53:12478 "used by worktree at '%s'"),
Derrick Stoleed2ba2712022-06-14 19:27:30479 ref->buf + strlen("refs/heads/"), path);
Junio C Hamano8280c4c2017-10-13 03:57:02480
Conrad Irwin55c4a672011-08-20 21:49:48481 return 1;
482}
483
Johan Herland41c21f22013-04-21 21:52:05484static int check_tracking_branch(struct remote *remote, void *cb_data)
485{
486 char *tracking_branch = cb_data;
Brandon Williams0ad4a5f2018-05-16 22:57:49487 struct refspec_item query;
Rubén Justocaee1d62023-06-11 18:50:27488 int res;
Brandon Williams0ad4a5f2018-05-16 22:57:49489 memset(&query, 0, sizeof(struct refspec_item));
Johan Herland41c21f22013-04-21 21:52:05490 query.dst = tracking_branch;
Rubén Justocaee1d62023-06-11 18:50:27491 res = !remote_find_tracking(remote, &query);
492 free(query.src);
493 return res;
Johan Herland41c21f22013-04-21 21:52:05494}
495
496static int validate_remote_tracking_branch(char *ref)
497{
498 return !for_each_remote(check_tracking_branch, ref);
499}
500
Jeff Kinge2b6aa52013-04-02 19:03:55501static const char upstream_not_branch[] =
Anders Kaseorg7435e7e2021-12-01 22:15:42502N_("cannot set up tracking information; starting point '%s' is not a branch");
Jeff Kinga5e91c72013-04-02 19:04:27503static const char upstream_missing[] =
Jeff Kingcaa20362013-04-02 19:05:12504N_("the requested upstream branch '%s' does not exist");
505static const char upstream_advice[] =
506N_("\n"
507"If you are planning on basing your work on an upstream\n"
508"branch that already exists at the remote, you may need to\n"
509"run \"git fetch\" to retrieve it.\n"
510"\n"
511"If you are planning to push out a new local branch that\n"
512"will track its remote counterpart, you may want to use\n"
513"\"git push -u\" to set the upstream config as you push.");
Jeff Kinge2b6aa52013-04-02 19:03:55514
Glen Chooe89f1512022-01-29 00:04:41515/**
516 * DWIMs a user-provided ref to determine the starting point for a
517 * branch and validates it, where:
518 *
519 * - r is the repository to validate the branch for
520 *
521 * - start_name is the ref that we would like to test. This is
522 * expanded with DWIM and assigned to out_real_ref.
523 *
524 * - track is the tracking mode of the new branch. If tracking is
525 * explicitly requested, start_name must be a branch (because
526 * otherwise start_name cannot be tracked)
527 *
528 * - out_oid is an out parameter containing the object_id of start_name
529 *
530 * - out_real_ref is an out parameter containing the full, 'real' form
531 * of start_name e.g. refs/heads/main instead of main
532 *
533 */
534static void dwim_branch_start(struct repository *r, const char *start_name,
535 enum branch_track track, char **out_real_ref,
536 struct object_id *out_oid)
Daniel Barkalowe496c002008-02-07 16:40:08537{
Daniel Barkalowe496c002008-02-07 16:40:08538 struct commit *commit;
brian m. carlson48713bf2017-05-01 02:29:00539 struct object_id oid;
Jeff King3818b252017-03-28 19:46:36540 char *real_ref;
Ilari Liusvaara4fc50062010-01-18 20:44:11541 int explicit_tracking = 0;
542
543 if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
544 explicit_tracking = 1;
Daniel Barkalowe496c002008-02-07 16:40:08545
Daniel Barkalowe496c002008-02-07 16:40:08546 real_ref = NULL;
Ævar Arnfjörð Bjarmason4a93b892023-03-28 13:58:58547 if (repo_get_oid_mb(r, start_name, &oid)) {
Jeff Kingcaa20362013-04-02 19:05:12548 if (explicit_tracking) {
Glen Choo66966012022-03-31 22:41:18549 int code = die_message(_(upstream_missing), start_name);
550 advise_if_enabled(ADVICE_SET_UPSTREAM_FAILURE,
551 _(upstream_advice));
552 exit(code);
Jeff Kingcaa20362013-04-02 19:05:12553 }
Anders Kaseorg7435e7e2021-12-01 22:15:42554 die(_("not a valid object name: '%s'"), start_name);
Jeff Kinga5e91c72013-04-02 19:04:27555 }
Daniel Barkalowe496c002008-02-07 16:40:08556
Ævar Arnfjörð Bjarmason4a93b892023-03-28 13:58:58557 switch (repo_dwim_ref(r, start_name, strlen(start_name), &oid,
558 &real_ref, 0)) {
Daniel Barkalowe496c002008-02-07 16:40:08559 case 0:
560 /* Not branching from any existing branch */
Ilari Liusvaara4fc50062010-01-18 20:44:11561 if (explicit_tracking)
Jeff King1a15d002013-04-02 19:04:51562 die(_(upstream_not_branch), start_name);
Daniel Barkalowe496c002008-02-07 16:40:08563 break;
564 case 1:
Johan Herland21b5b1e2011-02-16 23:12:20565 /* Unique completion -- good, only if it is a real branch */
Christian Couder59556542013-11-30 20:55:40566 if (!starts_with(real_ref, "refs/heads/") &&
Johan Herland41c21f22013-04-21 21:52:05567 validate_remote_tracking_branch(real_ref)) {
Johan Herland21b5b1e2011-02-16 23:12:20568 if (explicit_tracking)
Jeff King1a15d002013-04-02 19:04:51569 die(_(upstream_not_branch), start_name);
Johan Herland21b5b1e2011-02-16 23:12:20570 else
Andrzej Huntd8958042021-04-25 14:16:12571 FREE_AND_NULL(real_ref);
Johan Herland21b5b1e2011-02-16 23:12:20572 }
Daniel Barkalowe496c002008-02-07 16:40:08573 break;
574 default:
Anders Kaseorg7435e7e2021-12-01 22:15:42575 die(_("ambiguous object name: '%s'"), start_name);
Daniel Barkalowe496c002008-02-07 16:40:08576 break;
577 }
578
Junio C Hamanoafe8a902022-05-02 16:50:37579 if (!(commit = lookup_commit_reference(r, &oid)))
Anders Kaseorg7435e7e2021-12-01 22:15:42580 die(_("not a valid branch point: '%s'"), start_name);
Glen Chooe89f1512022-01-29 00:04:41581 if (out_real_ref) {
582 *out_real_ref = real_ref;
583 real_ref = NULL;
584 }
585 if (out_oid)
586 oidcpy(out_oid, &commit->object.oid);
587
588 FREE_AND_NULL(real_ref);
589}
590
591void create_branch(struct repository *r,
592 const char *name, const char *start_name,
593 int force, int clobber_head_ok, int reflog,
Glen Choo3f3e7602022-01-29 00:04:43594 int quiet, enum branch_track track, int dry_run)
Glen Chooe89f1512022-01-29 00:04:41595{
596 struct object_id oid;
597 char *real_ref;
598 struct strbuf ref = STRBUF_INIT;
599 int forcing = 0;
Glen Choobc0893c2022-01-29 00:04:42600 struct ref_transaction *transaction;
601 struct strbuf err = STRBUF_INIT;
602 char *msg;
Glen Chooe89f1512022-01-29 00:04:41603
Glen Choobc0893c2022-01-29 00:04:42604 if (track == BRANCH_TRACK_OVERRIDE)
605 BUG("'track' cannot be BRANCH_TRACK_OVERRIDE. Did you mean to call dwim_and_setup_tracking()?");
606 if (clobber_head_ok && !force)
607 BUG("'clobber_head_ok' can only be used with 'force'");
608
609 if (clobber_head_ok ?
610 validate_branchname(name, &ref) :
611 validate_new_branchname(name, &ref, force)) {
612 forcing = 1;
Glen Chooe89f1512022-01-29 00:04:41613 }
614
615 dwim_branch_start(r, start_name, track, &real_ref, &oid);
Glen Choo3f3e7602022-01-29 00:04:43616 if (dry_run)
617 goto cleanup;
Daniel Barkalowe496c002008-02-07 16:40:08618
Ronnie Sahlbergd43f9902014-04-16 23:21:53619 if (reflog)
Cornelius Weig341fb282017-01-27 10:09:47620 log_all_ref_updates = LOG_REFS_NORMAL;
Ronnie Sahlbergd43f9902014-04-16 23:21:53621
Glen Choobc0893c2022-01-29 00:04:42622 if (forcing)
623 msg = xstrfmt("branch: Reset to %s", start_name);
624 else
625 msg = xstrfmt("branch: Created from %s", start_name);
626 transaction = ref_transaction_begin(&err);
627 if (!transaction ||
628 ref_transaction_update(transaction, ref.buf,
629 &oid, forcing ? NULL : null_oid(),
630 0, msg, &err) ||
631 ref_transaction_commit(transaction, &err))
632 die("%s", err.buf);
633 ref_transaction_free(transaction);
634 strbuf_release(&err);
635 free(msg);
Ronnie Sahlbergd43f9902014-04-16 23:21:53636
Daniel Barkalowe496c002008-02-07 16:40:08637 if (real_ref && track)
Felipe Contreras82a06722013-08-30 21:56:46638 setup_tracking(ref.buf + 11, real_ref, track, quiet);
Daniel Barkalowe496c002008-02-07 16:40:08639
Glen Choo3f3e7602022-01-29 00:04:43640cleanup:
Junio C Hamano8415d5c2009-02-14 07:08:05641 strbuf_release(&ref);
Jay Soffian9ed36cf2008-02-19 16:24:37642 free(real_ref);
Daniel Barkalowe496c002008-02-07 16:40:08643}
Daniel Barkalowc369e7b2008-02-07 16:40:16644
Glen Chooe89f1512022-01-29 00:04:41645void dwim_and_setup_tracking(struct repository *r, const char *new_ref,
646 const char *orig_ref, enum branch_track track,
647 int quiet)
648{
Rubén Justo1533bda2023-06-11 18:49:43649 char *real_orig_ref = NULL;
Glen Chooe89f1512022-01-29 00:04:41650 dwim_branch_start(r, orig_ref, track, &real_orig_ref, NULL);
651 setup_tracking(new_ref, real_orig_ref, track, quiet);
Rubén Justo1533bda2023-06-11 18:49:43652 free(real_orig_ref);
Glen Chooe89f1512022-01-29 00:04:41653}
654
Glen Choo961b1302022-01-29 00:04:45655/**
656 * Creates a branch in a submodule by calling
657 * create_branches_recursively() in a child process. The child process
658 * is necessary because install_branch_config_multiple_remotes() (which
659 * is called by setup_tracking()) does not support writing configs to
660 * submodules.
661 */
662static int submodule_create_branch(struct repository *r,
663 const struct submodule *submodule,
664 const char *name, const char *start_oid,
665 const char *tracking_name, int force,
666 int reflog, int quiet,
667 enum branch_track track, int dry_run)
668{
669 int ret = 0;
670 struct child_process child = CHILD_PROCESS_INIT;
671 struct strbuf child_err = STRBUF_INIT;
672 struct strbuf out_buf = STRBUF_INIT;
673 char *out_prefix = xstrfmt("submodule '%s': ", submodule->name);
674 child.git_cmd = 1;
675 child.err = -1;
676 child.stdout_to_stderr = 1;
677
Ævar Arnfjörð Bjarmason29fda242022-06-02 09:09:50678 prepare_other_repo_env(&child.env, r->gitdir);
Glen Choo961b1302022-01-29 00:04:45679 /*
680 * submodule_create_branch() is indirectly invoked by "git
681 * branch", but we cannot invoke "git branch" in the child
682 * process. "git branch" accepts a branch name and start point,
683 * where the start point is assumed to provide both the OID
684 * (start_oid) and the branch to use for tracking
685 * (tracking_name). But when recursing through submodules,
686 * start_oid and tracking name need to be specified separately
687 * (see create_branches_recursively()).
688 */
689 strvec_pushl(&child.args, "submodule--helper", "create-branch", NULL);
690 if (dry_run)
691 strvec_push(&child.args, "--dry-run");
692 if (force)
693 strvec_push(&child.args, "--force");
694 if (quiet)
695 strvec_push(&child.args, "--quiet");
696 if (reflog)
697 strvec_push(&child.args, "--create-reflog");
Glen Choo75388bf2022-03-29 20:01:16698
699 switch (track) {
700 case BRANCH_TRACK_NEVER:
701 strvec_push(&child.args, "--no-track");
702 break;
703 case BRANCH_TRACK_ALWAYS:
704 case BRANCH_TRACK_EXPLICIT:
705 strvec_push(&child.args, "--track=direct");
706 break;
707 case BRANCH_TRACK_OVERRIDE:
708 BUG("BRANCH_TRACK_OVERRIDE cannot be used when creating a branch.");
709 break;
710 case BRANCH_TRACK_INHERIT:
711 strvec_push(&child.args, "--track=inherit");
712 break;
713 case BRANCH_TRACK_UNSPECIFIED:
Glen Choo1f888282022-03-31 22:41:17714 /* Default for "git checkout". Do not pass --track. */
Glen Choo75388bf2022-03-29 20:01:16715 case BRANCH_TRACK_REMOTE:
Glen Choo1f888282022-03-31 22:41:17716 /* Default for "git branch". Do not pass --track. */
Tao Klerksbdaf1df2022-04-29 09:56:44717 case BRANCH_TRACK_SIMPLE:
718 /* Config-driven only. Do not pass --track. */
Glen Choo75388bf2022-03-29 20:01:16719 break;
720 }
Glen Choo961b1302022-01-29 00:04:45721
722 strvec_pushl(&child.args, name, start_oid, tracking_name, NULL);
723
724 if ((ret = start_command(&child)))
725 return ret;
726 ret = finish_command(&child);
727 strbuf_read(&child_err, child.err, 0);
728 strbuf_add_lines(&out_buf, out_prefix, child_err.buf, child_err.len);
729
730 if (ret)
731 fprintf(stderr, "%s", out_buf.buf);
732 else
733 printf("%s", out_buf.buf);
734
735 strbuf_release(&child_err);
736 strbuf_release(&out_buf);
737 return ret;
738}
739
740void create_branches_recursively(struct repository *r, const char *name,
Pi Fisher84a7c332024-04-07 21:21:08741 const char *start_committish,
Glen Choo961b1302022-01-29 00:04:45742 const char *tracking_name, int force,
743 int reflog, int quiet, enum branch_track track,
744 int dry_run)
745{
746 int i = 0;
747 char *branch_point = NULL;
748 struct object_id super_oid;
749 struct submodule_entry_list submodule_entry_list;
750
Pi Fisher84a7c332024-04-07 21:21:08751 /* Perform dwim on start_committish to get super_oid and branch_point. */
752 dwim_branch_start(r, start_committish, BRANCH_TRACK_NEVER,
Glen Choo961b1302022-01-29 00:04:45753 &branch_point, &super_oid);
754
755 /*
756 * If we were not given an explicit name to track, then assume we are at
757 * the top level and, just like the non-recursive case, the tracking
758 * name is the branch point.
759 */
760 if (!tracking_name)
761 tracking_name = branch_point;
762
763 submodules_of_tree(r, &super_oid, &submodule_entry_list);
764 /*
765 * Before creating any branches, first check that the branch can
766 * be created in every submodule.
767 */
768 for (i = 0; i < submodule_entry_list.entry_nr; i++) {
Junio C Hamanoe6bf70d2022-05-02 17:18:22769 if (!submodule_entry_list.entries[i].repo) {
Glen Choocfbda6b2022-03-29 20:01:17770 int code = die_message(
771 _("submodule '%s': unable to find submodule"),
772 submodule_entry_list.entries[i].submodule->name);
Glen Choo961b1302022-01-29 00:04:45773 if (advice_enabled(ADVICE_SUBMODULES_NOT_UPDATED))
Philippe Blain97cf0c72023-01-16 17:41:48774 advise(_("You may try updating the submodules using 'git checkout --no-recurse-submodules %s && git submodule update --init'"),
Pi Fisher84a7c332024-04-07 21:21:08775 start_committish);
Glen Choocfbda6b2022-03-29 20:01:17776 exit(code);
Glen Choo961b1302022-01-29 00:04:45777 }
778
779 if (submodule_create_branch(
780 submodule_entry_list.entries[i].repo,
781 submodule_entry_list.entries[i].submodule, name,
782 oid_to_hex(&submodule_entry_list.entries[i]
783 .name_entry->oid),
784 tracking_name, force, reflog, quiet, track, 1))
785 die(_("submodule '%s': cannot create branch '%s'"),
786 submodule_entry_list.entries[i].submodule->name,
787 name);
788 }
789
Pi Fisher84a7c332024-04-07 21:21:08790 create_branch(r, name, start_committish, force, 0, reflog, quiet,
Glen Choo961b1302022-01-29 00:04:45791 BRANCH_TRACK_NEVER, dry_run);
792 if (dry_run)
793 return;
794 /*
795 * NEEDSWORK If tracking was set up in the superproject but not the
796 * submodule, users might expect "git branch --recurse-submodules" to
797 * fail or give a warning, but this is not yet implemented because it is
798 * tedious to determine whether or not tracking was set up in the
799 * superproject.
800 */
Glen Choo75388bf2022-03-29 20:01:16801 if (track)
802 setup_tracking(name, tracking_name, track, quiet);
Glen Choo961b1302022-01-29 00:04:45803
804 for (i = 0; i < submodule_entry_list.entry_nr; i++) {
805 if (submodule_create_branch(
806 submodule_entry_list.entries[i].repo,
807 submodule_entry_list.entries[i].submodule, name,
808 oid_to_hex(&submodule_entry_list.entries[i]
809 .name_entry->oid),
810 tracking_name, force, reflog, quiet, track, 0))
811 die(_("submodule '%s': cannot create branch '%s'"),
812 submodule_entry_list.entries[i].submodule->name,
813 name);
814 repo_clear(submodule_entry_list.entries[i].repo);
815 }
816}
817
Nguyễn Thái Ngọc Duyb6433552019-05-09 10:10:27818void remove_merge_branch_state(struct repository *r)
Daniel Barkalowc369e7b2008-02-07 16:40:16819{
Nguyễn Thái Ngọc Duy4edce172018-11-10 05:49:00820 unlink(git_path_merge_head(r));
821 unlink(git_path_merge_rr(r));
822 unlink(git_path_merge_msg(r));
823 unlink(git_path_merge_mode(r));
Patrick Steinhardtfd7c6ff2024-01-19 10:40:09824 refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",
825 NULL, REF_NO_DEREF);
Patrick Steinhardt3f921c72024-01-19 10:40:19826 save_autostash_ref(r, "MERGE_AUTOSTASH");
Nguyễn Thái Ngọc Duyb6433552019-05-09 10:10:27827}
828
Junio C Hamanof496b062019-07-09 22:25:44829void remove_branch_state(struct repository *r, int verbose)
Nguyễn Thái Ngọc Duyb6433552019-05-09 10:10:27830{
Junio C Hamanof496b062019-07-09 22:25:44831 sequencer_post_commit_cleanup(r, verbose);
Nguyễn Thái Ngọc Duy4edce172018-11-10 05:49:00832 unlink(git_path_squash_msg(r));
Nguyễn Thái Ngọc Duyb6433552019-05-09 10:10:27833 remove_merge_branch_state(r);
Daniel Barkalowc369e7b2008-02-07 16:40:16834}
Eric Sunshineed89f842015-07-17 23:00:04835
Nguyễn Thái Ngọc Duy8d9fdd72016-04-22 13:01:33836void die_if_checked_out(const char *branch, int ignore_current_worktree)
David Turner41af6562015-08-10 17:52:44837{
Anders Kaseorgc8dd4912021-12-01 22:15:43838 struct worktree **worktrees = get_worktrees();
David Turner41af6562015-08-10 17:52:44839
Rubén Justofaa4d592023-02-25 14:22:02840 for (int i = 0; worktrees[i]; i++) {
841 if (worktrees[i]->is_current && ignore_current_worktree)
842 continue;
843
844 if (is_shared_symref(worktrees[i], "HEAD", branch)) {
845 skip_prefix(branch, "refs/heads/", &branch);
Rubén Justo2a499262023-08-07 20:42:40846 die(_("'%s' is already used by worktree at '%s'"),
Rubén Justofaa4d592023-02-25 14:22:02847 branch, worktrees[i]->path);
848 }
Anders Kaseorgc8dd4912021-12-01 22:15:43849 }
850
851 free_worktrees(worktrees);
Eric Sunshineed89f842015-07-17 23:00:04852}