🌐 AI搜索 & 代理 主页
blob: 5d20a2e8484b22f321a60e01d63cb4c4bd8e88fe [file] [log] [blame]
Brian Gesiak303d1d02014-02-28 06:43:331#include "git-compat-util.h"
Daniel Barkalowe496c002008-02-07 16:40:082#include "cache.h"
Brandon Williamsb2141fc2017-06-14 18:07:363#include "config.h"
Daniel Barkalowe496c002008-02-07 16:40:084#include "branch.h"
5#include "refs.h"
Brandon Williamsec0cb492018-05-16 22:57:486#include "refspec.h"
Daniel Barkalowe496c002008-02-07 16:40:087#include "remote.h"
Phillip Woodb07d9bf2019-04-16 10:18:418#include "sequencer.h"
Daniel Barkalowe496c002008-02-07 16:40:089#include "commit.h"
Michael Rappazzoac6c5612015-10-02 11:55:3110#include "worktree.h"
Daniel Barkalowe496c002008-02-07 16:40:0811
12struct tracking {
Brandon Williams0ad4a5f2018-05-16 22:57:4913 struct refspec_item spec;
Josh Steadmond3115662021-12-21 03:30:2314 struct string_list *srcs;
Daniel Barkalowe496c002008-02-07 16:40:0815 const char *remote;
16 int matches;
17};
18
19static int find_tracked_branch(struct remote *remote, void *priv)
20{
21 struct tracking *tracking = priv;
22
23 if (!remote_find_tracking(remote, &tracking->spec)) {
24 if (++tracking->matches == 1) {
Josh Steadmond3115662021-12-21 03:30:2325 string_list_append(tracking->srcs, tracking->spec.src);
Daniel Barkalowe496c002008-02-07 16:40:0826 tracking->remote = remote->name;
27 } else {
28 free(tracking->spec.src);
Josh Steadmond3115662021-12-21 03:30:2329 string_list_clear(tracking->srcs, 0);
Daniel Barkalowe496c002008-02-07 16:40:0830 }
31 tracking->spec.src = NULL;
32 }
33
34 return 0;
35}
36
Junio C Hamanoa9f2c132009-03-04 06:29:5537static int should_setup_rebase(const char *origin)
Dustin Sallingsc998ae92008-05-10 22:36:2938{
39 switch (autorebase) {
40 case AUTOREBASE_NEVER:
41 return 0;
42 case AUTOREBASE_LOCAL:
Junio C Hamanoa9f2c132009-03-04 06:29:5543 return origin == NULL;
Dustin Sallingsc998ae92008-05-10 22:36:2944 case AUTOREBASE_REMOTE:
Junio C Hamanoa9f2c132009-03-04 06:29:5545 return origin != NULL;
Dustin Sallingsc998ae92008-05-10 22:36:2946 case AUTOREBASE_ALWAYS:
47 return 1;
48 }
49 return 0;
50}
51
Josh Steadmona3f40ec2021-12-21 03:30:2252/**
53 * Install upstream tracking configuration for a branch; specifically, add
54 * `branch.<name>.remote` and `branch.<name>.merge` entries.
55 *
56 * `flag` contains integer flags for options; currently only
57 * BRANCH_CONFIG_VERBOSE is checked.
58 *
59 * `local` is the name of the branch whose configuration we're installing.
60 *
61 * `origin` is the name of the remote owning the upstream branches. NULL means
62 * the upstream branches are local to this repo.
63 *
64 * `remotes` is a list of refs that are upstream of local
65 */
66static int install_branch_config_multiple_remotes(int flag, const char *local,
67 const char *origin, struct string_list *remotes)
Junio C Hamanoa9f2c132009-03-04 06:29:5568{
Jeff Kingcf4fff52014-06-18 19:44:1969 const char *shortname = NULL;
Junio C Hamanoa9f2c132009-03-04 06:29:5570 struct strbuf key = STRBUF_INIT;
Josh Steadmona3f40ec2021-12-21 03:30:2271 struct string_list_item *item;
Junio C Hamanoa9f2c132009-03-04 06:29:5572 int rebasing = should_setup_rebase(origin);
73
Josh Steadmona3f40ec2021-12-21 03:30:2274 if (!remotes->nr)
75 BUG("must provide at least one remote for branch config");
76 if (rebasing && remotes->nr > 1)
77 die(_("cannot inherit upstream tracking configuration of "
78 "multiple refs when rebasing is requested"));
79
80 /*
81 * If the new branch is trying to track itself, something has gone
82 * wrong. Warn the user and don't proceed any further.
83 */
84 if (!origin)
85 for_each_string_list_item(item, remotes)
86 if (skip_prefix(item->string, "refs/heads/", &shortname)
87 && !strcmp(local, shortname)) {
Junio C Hamano0669bdf2022-01-10 19:52:5488 warning(_("not setting branch '%s' as its own upstream"),
Josh Steadmona3f40ec2021-12-21 03:30:2289 local);
90 return 0;
91 }
Matthieu Moy85e22332010-01-18 20:44:1292
Junio C Hamanoa9f2c132009-03-04 06:29:5593 strbuf_addf(&key, "branch.%s.remote", local);
Patrick Steinhardt30598ad2016-02-22 11:23:3594 if (git_config_set_gently(key.buf, origin ? origin : ".") < 0)
Patrick Steinhardt27852b22016-02-22 11:23:2395 goto out_err;
Junio C Hamanoa9f2c132009-03-04 06:29:5596
97 strbuf_reset(&key);
98 strbuf_addf(&key, "branch.%s.merge", local);
Josh Steadmona3f40ec2021-12-21 03:30:2299 /*
100 * We want to overwrite any existing config with all the branches in
101 * "remotes". Override any existing config, then write our branches. If
102 * more than one is provided, use CONFIG_REGEX_NONE to preserve what
103 * we've written so far.
104 */
105 if (git_config_set_gently(key.buf, NULL) < 0)
Patrick Steinhardt27852b22016-02-22 11:23:23106 goto out_err;
Josh Steadmona3f40ec2021-12-21 03:30:22107 for_each_string_list_item(item, remotes)
108 if (git_config_set_multivar_gently(key.buf, item->string, CONFIG_REGEX_NONE, 0) < 0)
109 goto out_err;
Junio C Hamanoa9f2c132009-03-04 06:29:55110
111 if (rebasing) {
112 strbuf_reset(&key);
113 strbuf_addf(&key, "branch.%s.rebase", local);
Patrick Steinhardt30598ad2016-02-22 11:23:35114 if (git_config_set_gently(key.buf, "true") < 0)
Patrick Steinhardt27852b22016-02-22 11:23:23115 goto out_err;
Junio C Hamanoa9f2c132009-03-04 06:29:55116 }
Nguyễn Thái Ngọc Duyd53a35032012-06-07 12:05:10117 strbuf_release(&key);
Junio C Hamanoa9f2c132009-03-04 06:29:55118
Junio C Hamano72f60082009-03-10 08:20:42119 if (flag & BRANCH_CONFIG_VERBOSE) {
Josh Steadmona3f40ec2021-12-21 03:30:22120 struct strbuf tmp_ref_name = STRBUF_INIT;
121 struct string_list friendly_ref_names = STRING_LIST_INIT_DUP;
122
123 for_each_string_list_item(item, remotes) {
124 shortname = item->string;
125 skip_prefix(shortname, "refs/heads/", &shortname);
126 if (origin) {
127 strbuf_addf(&tmp_ref_name, "%s/%s",
128 origin, shortname);
129 string_list_append_nodup(
130 &friendly_ref_names,
131 strbuf_detach(&tmp_ref_name, NULL));
132 } else {
133 string_list_append(
134 &friendly_ref_names, shortname);
135 }
Adam9fe0cf32014-03-10 05:32:01136 }
Josh Steadmona3f40ec2021-12-21 03:30:22137
138 if (remotes->nr == 1) {
139 /*
140 * Rebasing is only allowed in the case of a single
141 * upstream branch.
142 */
143 printf_ln(rebasing ?
144 _("branch '%s' set up to track '%s' by rebasing.") :
145 _("branch '%s' set up to track '%s'."),
146 local, friendly_ref_names.items[0].string);
147 } else {
148 printf_ln(_("branch '%s' set up to track:"), local);
149 for_each_string_list_item(item, &friendly_ref_names)
150 printf_ln(" %s", item->string);
151 }
152
153 string_list_clear(&friendly_ref_names, 0);
Junio C Hamano72f60082009-03-10 08:20:42154 }
Patrick Steinhardt27852b22016-02-22 11:23:23155
156 return 0;
157
158out_err:
159 strbuf_release(&key);
Anders Kaseorg7435e7e2021-12-01 22:15:42160 error(_("unable to write upstream branch configuration"));
Patrick Steinhardt27852b22016-02-22 11:23:23161
Josh Steadmona3f40ec2021-12-21 03:30:22162 advise(_("\nAfter fixing the error cause you may try to fix up\n"
163 "the remote tracking information by invoking:"));
164 if (remotes->nr == 1)
165 advise(" git branch --set-upstream-to=%s%s%s",
166 origin ? origin : "",
167 origin ? "/" : "",
168 remotes->items[0].string);
169 else {
170 advise(" git config --add branch.\"%s\".remote %s",
171 local, origin ? origin : ".");
172 for_each_string_list_item(item, remotes)
173 advise(" git config --add branch.\"%s\".merge %s",
174 local, item->string);
175 }
Patrick Steinhardt27852b22016-02-22 11:23:23176
177 return -1;
Junio C Hamanoa9f2c132009-03-04 06:29:55178}
179
Josh Steadmona3f40ec2021-12-21 03:30:22180int install_branch_config(int flag, const char *local, const char *origin,
181 const char *remote)
182{
183 int ret;
184 struct string_list remotes = STRING_LIST_INIT_DUP;
185
186 string_list_append(&remotes, remote);
187 ret = install_branch_config_multiple_remotes(flag, local, origin, &remotes);
188 string_list_clear(&remotes, 0);
189 return ret;
190}
191
Josh Steadmond3115662021-12-21 03:30:23192static int inherit_tracking(struct tracking *tracking, const char *orig_ref)
193{
194 const char *bare_ref;
195 struct branch *branch;
196 int i;
197
198 bare_ref = orig_ref;
199 skip_prefix(orig_ref, "refs/heads/", &bare_ref);
200
201 branch = branch_get(bare_ref);
202 if (!branch->remote_name) {
203 warning(_("asked to inherit tracking from '%s', but no remote is set"),
204 bare_ref);
205 return -1;
206 }
207
208 if (branch->merge_nr < 1 || !branch->merge_name || !branch->merge_name[0]) {
209 warning(_("asked to inherit tracking from '%s', but no merge configuration is set"),
210 bare_ref);
211 return -1;
212 }
213
214 tracking->remote = xstrdup(branch->remote_name);
215 for (i = 0; i < branch->merge_nr; i++)
216 string_list_append(tracking->srcs, branch->merge_name[i]);
217 return 0;
218}
219
Daniel Barkalowe496c002008-02-07 16:40:08220/*
221 * This is called when new_ref is branched off of orig_ref, and tries
222 * to infer the settings for branch.<new_ref>.{remote,merge} from the
223 * config.
224 */
Patrick Steinhardt27852b22016-02-22 11:23:23225static void setup_tracking(const char *new_ref, const char *orig_ref,
226 enum branch_track track, int quiet)
Daniel Barkalowe496c002008-02-07 16:40:08227{
Daniel Barkalowe496c002008-02-07 16:40:08228 struct tracking tracking;
Josh Steadmond3115662021-12-21 03:30:23229 struct string_list tracking_srcs = STRING_LIST_INIT_DUP;
Jeff Kingf9a482e2012-03-26 23:51:01230 int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
Daniel Barkalowe496c002008-02-07 16:40:08231
Daniel Barkalowe496c002008-02-07 16:40:08232 memset(&tracking, 0, sizeof(tracking));
233 tracking.spec.dst = (char *)orig_ref;
Josh Steadmond3115662021-12-21 03:30:23234 tracking.srcs = &tracking_srcs;
235 if (track != BRANCH_TRACK_INHERIT)
236 for_each_remote(find_tracked_branch, &tracking);
237 else if (inherit_tracking(&tracking, orig_ref))
Patrick Steinhardt27852b22016-02-22 11:23:23238 return;
Daniel Barkalowe496c002008-02-07 16:40:08239
Jay Soffian9ed36cf2008-02-19 16:24:37240 if (!tracking.matches)
241 switch (track) {
242 case BRANCH_TRACK_ALWAYS:
243 case BRANCH_TRACK_EXPLICIT:
Ilari Liusvaara4fc50062010-01-18 20:44:11244 case BRANCH_TRACK_OVERRIDE:
Josh Steadmond3115662021-12-21 03:30:23245 case BRANCH_TRACK_INHERIT:
Jay Soffian9ed36cf2008-02-19 16:24:37246 break;
247 default:
Patrick Steinhardt27852b22016-02-22 11:23:23248 return;
Jay Soffian9ed36cf2008-02-19 16:24:37249 }
250
Daniel Barkalowe496c002008-02-07 16:40:08251 if (tracking.matches > 1)
Anders Kaseorg7435e7e2021-12-01 22:15:42252 die(_("not tracking: ambiguous information for ref %s"),
Patrick Steinhardt27852b22016-02-22 11:23:23253 orig_ref);
Daniel Barkalowe496c002008-02-07 16:40:08254
Josh Steadmond3115662021-12-21 03:30:23255 if (tracking.srcs->nr < 1)
256 string_list_append(tracking.srcs, orig_ref);
257 if (install_branch_config_multiple_remotes(config_flags, new_ref,
258 tracking.remote, tracking.srcs) < 0)
Patrick Steinhardt27852b22016-02-22 11:23:23259 exit(-1);
Daniel Barkalowe496c002008-02-07 16:40:08260
Josh Steadmond3115662021-12-21 03:30:23261 string_list_clear(tracking.srcs, 0);
Daniel Barkalowe496c002008-02-07 16:40:08262}
263
Junio C Hamano6f9a3322011-09-22 03:19:38264int read_branch_desc(struct strbuf *buf, const char *branch_name)
265{
Tanay Abhra540b0f42014-08-07 17:56:42266 char *v = NULL;
Junio C Hamano6f9a3322011-09-22 03:19:38267 struct strbuf name = STRBUF_INIT;
268 strbuf_addf(&name, "branch.%s.description", branch_name);
Tanay Abhra540b0f42014-08-07 17:56:42269 if (git_config_get_string(name.buf, &v)) {
270 strbuf_release(&name);
271 return -1;
272 }
273 strbuf_addstr(buf, v);
274 free(v);
Junio C Hamano6f9a3322011-09-22 03:19:38275 strbuf_release(&name);
276 return 0;
277}
278
Junio C Hamanobc1c9c02017-10-13 04:45:40279/*
280 * Check if 'name' can be a valid name for a branch; die otherwise.
281 * Return 1 if the named branch already exists; return 0 otherwise.
282 * Fill ref with the full refname for the branch.
283 */
284int validate_branchname(const char *name, struct strbuf *ref)
Conrad Irwin55c4a672011-08-20 21:49:48285{
Conrad Irwin55c4a672011-08-20 21:49:48286 if (strbuf_check_branch_ref(ref, name))
Anders Kaseorg7435e7e2021-12-01 22:15:42287 die(_("'%s' is not a valid branch name"), name);
Conrad Irwin55c4a672011-08-20 21:49:48288
Junio C Hamanobc1c9c02017-10-13 04:45:40289 return ref_exists(ref->buf);
290}
Conrad Irwin55c4a672011-08-20 21:49:48291
Junio C Hamanobc1c9c02017-10-13 04:45:40292/*
293 * Check if a branch 'name' can be created as a new branch; die otherwise.
294 * 'force' can be used when it is OK for the named branch already exists.
295 * Return 1 if the named branch already exists; return 0 otherwise.
296 * Fill ref with the full refname for the branch.
297 */
298int validate_new_branchname(const char *name, struct strbuf *ref, int force)
299{
Anders Kaseorg593a2a52021-12-01 22:15:47300 struct worktree **worktrees;
301 const struct worktree *wt;
Junio C Hamanobc1c9c02017-10-13 04:45:40302
303 if (!validate_branchname(name, ref))
Conrad Irwin55c4a672011-08-20 21:49:48304 return 0;
Conrad Irwin55c4a672011-08-20 21:49:48305
Junio C Hamano8280c4c2017-10-13 03:57:02306 if (!force)
Anders Kaseorg7435e7e2021-12-01 22:15:42307 die(_("a branch named '%s' already exists"),
Junio C Hamano8280c4c2017-10-13 03:57:02308 ref->buf + strlen("refs/heads/"));
Conrad Irwin55c4a672011-08-20 21:49:48309
Anders Kaseorg593a2a52021-12-01 22:15:47310 worktrees = get_worktrees();
311 wt = find_shared_symref(worktrees, "HEAD", ref->buf);
312 if (wt && !wt->is_bare)
Bagas Sanjaya68d924e2022-01-11 12:36:27313 die(_("cannot force update the branch '%s' "
Anders Kaseorg593a2a52021-12-01 22:15:47314 "checked out at '%s'"),
315 ref->buf + strlen("refs/heads/"), wt->path);
316 free_worktrees(worktrees);
Junio C Hamano8280c4c2017-10-13 03:57:02317
Conrad Irwin55c4a672011-08-20 21:49:48318 return 1;
319}
320
Johan Herland41c21f22013-04-21 21:52:05321static int check_tracking_branch(struct remote *remote, void *cb_data)
322{
323 char *tracking_branch = cb_data;
Brandon Williams0ad4a5f2018-05-16 22:57:49324 struct refspec_item query;
325 memset(&query, 0, sizeof(struct refspec_item));
Johan Herland41c21f22013-04-21 21:52:05326 query.dst = tracking_branch;
Per Cederqvist1d7358c2013-09-08 20:58:15327 return !remote_find_tracking(remote, &query);
Johan Herland41c21f22013-04-21 21:52:05328}
329
330static int validate_remote_tracking_branch(char *ref)
331{
332 return !for_each_remote(check_tracking_branch, ref);
333}
334
Jeff Kinge2b6aa52013-04-02 19:03:55335static const char upstream_not_branch[] =
Anders Kaseorg7435e7e2021-12-01 22:15:42336N_("cannot set up tracking information; starting point '%s' is not a branch");
Jeff Kinga5e91c72013-04-02 19:04:27337static const char upstream_missing[] =
Jeff Kingcaa20362013-04-02 19:05:12338N_("the requested upstream branch '%s' does not exist");
339static const char upstream_advice[] =
340N_("\n"
341"If you are planning on basing your work on an upstream\n"
342"branch that already exists at the remote, you may need to\n"
343"run \"git fetch\" to retrieve it.\n"
344"\n"
345"If you are planning to push out a new local branch that\n"
346"will track its remote counterpart, you may want to use\n"
347"\"git push -u\" to set the upstream config as you push.");
Jeff Kinge2b6aa52013-04-02 19:03:55348
Nguyễn Thái Ngọc Duy4edce172018-11-10 05:49:00349void create_branch(struct repository *r,
350 const char *name, const char *start_name,
Kaartic Sivaraame2bbd0c2017-11-18 17:26:46351 int force, int clobber_head_ok, int reflog,
Jeff Kingf9a482e2012-03-26 23:51:01352 int quiet, enum branch_track track)
Daniel Barkalowe496c002008-02-07 16:40:08353{
Daniel Barkalowe496c002008-02-07 16:40:08354 struct commit *commit;
brian m. carlson48713bf2017-05-01 02:29:00355 struct object_id oid;
Jeff King3818b252017-03-28 19:46:36356 char *real_ref;
Junio C Hamano8415d5c2009-02-14 07:08:05357 struct strbuf ref = STRBUF_INIT;
Daniel Barkalowe496c002008-02-07 16:40:08358 int forcing = 0;
Ilari Liusvaara4fc50062010-01-18 20:44:11359 int dont_change_ref = 0;
360 int explicit_tracking = 0;
361
362 if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
363 explicit_tracking = 1;
Daniel Barkalowe496c002008-02-07 16:40:08364
Junio C Hamano0faff982017-12-27 19:16:25365 if ((track == BRANCH_TRACK_OVERRIDE || clobber_head_ok)
Junio C Hamanobc1c9c02017-10-13 04:45:40366 ? validate_branchname(name, &ref)
367 : validate_new_branchname(name, &ref, force)) {
Conrad Irwin55c4a672011-08-20 21:49:48368 if (!force)
Ilari Liusvaara4fc50062010-01-18 20:44:11369 dont_change_ref = 1;
Conrad Irwin55c4a672011-08-20 21:49:48370 else
371 forcing = 1;
Daniel Barkalowe496c002008-02-07 16:40:08372 }
373
374 real_ref = NULL;
Denton Liue3d65392019-04-27 12:02:22375 if (get_oid_mb(start_name, &oid)) {
Jeff Kingcaa20362013-04-02 19:05:12376 if (explicit_tracking) {
Ben Boeckeled9bff02021-08-23 10:44:00377 if (advice_enabled(ADVICE_SET_UPSTREAM_FAILURE)) {
Jeff Kingcaa20362013-04-02 19:05:12378 error(_(upstream_missing), start_name);
379 advise(_(upstream_advice));
380 exit(1);
381 }
Jeff King1a15d002013-04-02 19:04:51382 die(_(upstream_missing), start_name);
Jeff Kingcaa20362013-04-02 19:05:12383 }
Anders Kaseorg7435e7e2021-12-01 22:15:42384 die(_("not a valid object name: '%s'"), start_name);
Jeff Kinga5e91c72013-04-02 19:04:27385 }
Daniel Barkalowe496c002008-02-07 16:40:08386
Jonathan Tanf24c30e2020-09-01 22:28:09387 switch (dwim_ref(start_name, strlen(start_name), &oid, &real_ref, 0)) {
Daniel Barkalowe496c002008-02-07 16:40:08388 case 0:
389 /* Not branching from any existing branch */
Ilari Liusvaara4fc50062010-01-18 20:44:11390 if (explicit_tracking)
Jeff King1a15d002013-04-02 19:04:51391 die(_(upstream_not_branch), start_name);
Daniel Barkalowe496c002008-02-07 16:40:08392 break;
393 case 1:
Johan Herland21b5b1e2011-02-16 23:12:20394 /* Unique completion -- good, only if it is a real branch */
Christian Couder59556542013-11-30 20:55:40395 if (!starts_with(real_ref, "refs/heads/") &&
Johan Herland41c21f22013-04-21 21:52:05396 validate_remote_tracking_branch(real_ref)) {
Johan Herland21b5b1e2011-02-16 23:12:20397 if (explicit_tracking)
Jeff King1a15d002013-04-02 19:04:51398 die(_(upstream_not_branch), start_name);
Johan Herland21b5b1e2011-02-16 23:12:20399 else
Andrzej Huntd8958042021-04-25 14:16:12400 FREE_AND_NULL(real_ref);
Johan Herland21b5b1e2011-02-16 23:12:20401 }
Daniel Barkalowe496c002008-02-07 16:40:08402 break;
403 default:
Anders Kaseorg7435e7e2021-12-01 22:15:42404 die(_("ambiguous object name: '%s'"), start_name);
Daniel Barkalowe496c002008-02-07 16:40:08405 break;
406 }
407
Nguyễn Thái Ngọc Duy4edce172018-11-10 05:49:00408 if ((commit = lookup_commit_reference(r, &oid)) == NULL)
Anders Kaseorg7435e7e2021-12-01 22:15:42409 die(_("not a valid branch point: '%s'"), start_name);
brian m. carlson48713bf2017-05-01 02:29:00410 oidcpy(&oid, &commit->object.oid);
Daniel Barkalowe496c002008-02-07 16:40:08411
Ronnie Sahlbergd43f9902014-04-16 23:21:53412 if (reflog)
Cornelius Weig341fb282017-01-27 10:09:47413 log_all_ref_updates = LOG_REFS_NORMAL;
Ronnie Sahlbergd43f9902014-04-16 23:21:53414
415 if (!dont_change_ref) {
416 struct ref_transaction *transaction;
417 struct strbuf err = STRBUF_INIT;
Jeff Kingcddac452017-03-28 19:46:40418 char *msg;
Jeff King3818b252017-03-28 19:46:36419
420 if (forcing)
Jeff Kingcddac452017-03-28 19:46:40421 msg = xstrfmt("branch: Reset to %s", start_name);
Jeff King3818b252017-03-28 19:46:36422 else
Jeff Kingcddac452017-03-28 19:46:40423 msg = xstrfmt("branch: Created from %s", start_name);
Ronnie Sahlbergd43f9902014-04-16 23:21:53424
425 transaction = ref_transaction_begin(&err);
426 if (!transaction ||
Michael Haggerty1d147bd2015-02-17 17:00:15427 ref_transaction_update(transaction, ref.buf,
brian m. carlson14228442021-04-26 01:02:56428 &oid, forcing ? NULL : null_oid(),
Michael Haggerty1d147bd2015-02-17 17:00:15429 0, msg, &err) ||
Ronnie Sahlbergdb7516a2014-04-30 19:22:42430 ref_transaction_commit(transaction, &err))
Ronnie Sahlbergd43f9902014-04-16 23:21:53431 die("%s", err.buf);
432 ref_transaction_free(transaction);
433 strbuf_release(&err);
Jeff Kingcddac452017-03-28 19:46:40434 free(msg);
Ronnie Sahlbergd43f9902014-04-16 23:21:53435 }
436
Daniel Barkalowe496c002008-02-07 16:40:08437 if (real_ref && track)
Felipe Contreras82a06722013-08-30 21:56:46438 setup_tracking(ref.buf + 11, real_ref, track, quiet);
Daniel Barkalowe496c002008-02-07 16:40:08439
Junio C Hamano8415d5c2009-02-14 07:08:05440 strbuf_release(&ref);
Jay Soffian9ed36cf2008-02-19 16:24:37441 free(real_ref);
Daniel Barkalowe496c002008-02-07 16:40:08442}
Daniel Barkalowc369e7b2008-02-07 16:40:16443
Nguyễn Thái Ngọc Duyb6433552019-05-09 10:10:27444void remove_merge_branch_state(struct repository *r)
Daniel Barkalowc369e7b2008-02-07 16:40:16445{
Nguyễn Thái Ngọc Duy4edce172018-11-10 05:49:00446 unlink(git_path_merge_head(r));
447 unlink(git_path_merge_rr(r));
448 unlink(git_path_merge_msg(r));
449 unlink(git_path_merge_mode(r));
Elijah Newren52918282021-03-20 00:03:52450 unlink(git_path_auto_merge(r));
Denton Liua03b5552020-04-07 14:28:07451 save_autostash(git_path_merge_autostash(r));
Nguyễn Thái Ngọc Duyb6433552019-05-09 10:10:27452}
453
Junio C Hamanof496b062019-07-09 22:25:44454void remove_branch_state(struct repository *r, int verbose)
Nguyễn Thái Ngọc Duyb6433552019-05-09 10:10:27455{
Junio C Hamanof496b062019-07-09 22:25:44456 sequencer_post_commit_cleanup(r, verbose);
Nguyễn Thái Ngọc Duy4edce172018-11-10 05:49:00457 unlink(git_path_squash_msg(r));
Nguyễn Thái Ngọc Duyb6433552019-05-09 10:10:27458 remove_merge_branch_state(r);
Daniel Barkalowc369e7b2008-02-07 16:40:16459}
Eric Sunshineed89f842015-07-17 23:00:04460
Nguyễn Thái Ngọc Duy8d9fdd72016-04-22 13:01:33461void die_if_checked_out(const char *branch, int ignore_current_worktree)
David Turner41af6562015-08-10 17:52:44462{
Anders Kaseorgc8dd4912021-12-01 22:15:43463 struct worktree **worktrees = get_worktrees();
Nguyễn Thái Ngọc Duyd3b9ac02016-04-22 13:01:27464 const struct worktree *wt;
David Turner41af6562015-08-10 17:52:44465
Anders Kaseorgc8dd4912021-12-01 22:15:43466 wt = find_shared_symref(worktrees, "HEAD", branch);
467 if (wt && (!ignore_current_worktree || !wt->is_current)) {
468 skip_prefix(branch, "refs/heads/", &branch);
469 die(_("'%s' is already checked out at '%s'"), branch, wt->path);
470 }
471
472 free_worktrees(worktrees);
Eric Sunshineed89f842015-07-17 23:00:04473}
Kazuki Yamaguchi70999e92016-03-27 14:37:14474
Kyle Meyer39ee4c62017-02-21 01:10:35475int replace_each_worktree_head_symref(const char *oldref, const char *newref,
476 const char *logmsg)
Kazuki Yamaguchi70999e92016-03-27 14:37:14477{
478 int ret = 0;
Eric Sunshine03f24652020-06-19 23:35:44479 struct worktree **worktrees = get_worktrees();
Kazuki Yamaguchi70999e92016-03-27 14:37:14480 int i;
481
482 for (i = 0; worktrees[i]; i++) {
Nguyễn Thái Ngọc Duyd026a252017-04-24 10:01:24483 struct ref_store *refs;
484
Kazuki Yamaguchi70999e92016-03-27 14:37:14485 if (worktrees[i]->is_detached)
486 continue;
Nguyễn Thái Ngọc Duy31824d12017-08-24 10:41:24487 if (!worktrees[i]->head_ref)
488 continue;
489 if (strcmp(oldref, worktrees[i]->head_ref))
Kazuki Yamaguchi70999e92016-03-27 14:37:14490 continue;
491
Nguyễn Thái Ngọc Duyd026a252017-04-24 10:01:24492 refs = get_worktree_ref_store(worktrees[i]);
493 if (refs_create_symref(refs, "HEAD", newref, logmsg))
494 ret = error(_("HEAD of working tree %s is not updated"),
495 worktrees[i]->path);
Kazuki Yamaguchi70999e92016-03-27 14:37:14496 }
497
498 free_worktrees(worktrees);
499 return ret;
500}