blob: 0d459b3cfe507b3906760fbea7f35e6191366057 [file] [log] [blame]
Brian Gesiak303d1d02014-02-28 15:43:33 +09001#include "git-compat-util.h"
Daniel Barkalowe496c002008-02-07 11:40:08 -05002#include "cache.h"
3#include "branch.h"
4#include "refs.h"
5#include "remote.h"
6#include "commit.h"
Michael Rappazzoac6c5612015-10-02 07:55:31 -04007#include "worktree.h"
Daniel Barkalowe496c002008-02-07 11:40:08 -05008
9struct tracking {
10 struct refspec spec;
11 char *src;
12 const char *remote;
13 int matches;
14};
15
16static int find_tracked_branch(struct remote *remote, void *priv)
17{
18 struct tracking *tracking = priv;
19
20 if (!remote_find_tracking(remote, &tracking->spec)) {
21 if (++tracking->matches == 1) {
22 tracking->src = tracking->spec.src;
23 tracking->remote = remote->name;
24 } else {
25 free(tracking->spec.src);
26 if (tracking->src) {
27 free(tracking->src);
28 tracking->src = NULL;
29 }
30 }
31 tracking->spec.src = NULL;
32 }
33
34 return 0;
35}
36
Junio C Hamanoa9f2c132009-03-03 22:29:55 -080037static int should_setup_rebase(const char *origin)
Dustin Sallingsc998ae92008-05-10 15:36:29 -070038{
39 switch (autorebase) {
40 case AUTOREBASE_NEVER:
41 return 0;
42 case AUTOREBASE_LOCAL:
Junio C Hamanoa9f2c132009-03-03 22:29:55 -080043 return origin == NULL;
Dustin Sallingsc998ae92008-05-10 15:36:29 -070044 case AUTOREBASE_REMOTE:
Junio C Hamanoa9f2c132009-03-03 22:29:55 -080045 return origin != NULL;
Dustin Sallingsc998ae92008-05-10 15:36:29 -070046 case AUTOREBASE_ALWAYS:
47 return 1;
48 }
49 return 0;
50}
51
Patrick Steinhardt27852b22016-02-22 12:23:23 +010052static const char tracking_advice[] =
53N_("\n"
54"After fixing the error cause you may try to fix up\n"
55"the remote tracking information by invoking\n"
56"\"git branch --set-upstream-to=%s%s%s\".");
57
58int install_branch_config(int flag, const char *local, const char *origin, const char *remote)
Junio C Hamanoa9f2c132009-03-03 22:29:55 -080059{
Jeff Kingcf4fff52014-06-18 15:44:19 -040060 const char *shortname = NULL;
Junio C Hamanoa9f2c132009-03-03 22:29:55 -080061 struct strbuf key = STRBUF_INIT;
62 int rebasing = should_setup_rebase(origin);
63
Jeff Kingcf4fff52014-06-18 15:44:19 -040064 if (skip_prefix(remote, "refs/heads/", &shortname)
Matthieu Moy85e22332010-01-18 22:44:12 +020065 && !strcmp(local, shortname)
66 && !origin) {
Jiang Xinbc554df2013-04-16 11:37:50 +080067 warning(_("Not setting branch %s as its own upstream."),
Matthieu Moy85e22332010-01-18 22:44:12 +020068 local);
Patrick Steinhardt27852b22016-02-22 12:23:23 +010069 return 0;
Matthieu Moy85e22332010-01-18 22:44:12 +020070 }
71
Junio C Hamanoa9f2c132009-03-03 22:29:55 -080072 strbuf_addf(&key, "branch.%s.remote", local);
Patrick Steinhardt30598ad2016-02-22 12:23:35 +010073 if (git_config_set_gently(key.buf, origin ? origin : ".") < 0)
Patrick Steinhardt27852b22016-02-22 12:23:23 +010074 goto out_err;
Junio C Hamanoa9f2c132009-03-03 22:29:55 -080075
76 strbuf_reset(&key);
77 strbuf_addf(&key, "branch.%s.merge", local);
Patrick Steinhardt30598ad2016-02-22 12:23:35 +010078 if (git_config_set_gently(key.buf, remote) < 0)
Patrick Steinhardt27852b22016-02-22 12:23:23 +010079 goto out_err;
Junio C Hamanoa9f2c132009-03-03 22:29:55 -080080
81 if (rebasing) {
82 strbuf_reset(&key);
83 strbuf_addf(&key, "branch.%s.rebase", local);
Patrick Steinhardt30598ad2016-02-22 12:23:35 +010084 if (git_config_set_gently(key.buf, "true") < 0)
Patrick Steinhardt27852b22016-02-22 12:23:23 +010085 goto out_err;
Junio C Hamanoa9f2c132009-03-03 22:29:55 -080086 }
Nguyễn Thái Ngọc Duyd53a35032012-06-07 19:05:10 +070087 strbuf_release(&key);
Junio C Hamanoa9f2c132009-03-03 22:29:55 -080088
Junio C Hamano72f60082009-03-10 01:20:42 -070089 if (flag & BRANCH_CONFIG_VERBOSE) {
Junio C Hamano1d9aaed2014-03-31 16:31:19 -070090 if (shortname) {
Adam9fe0cf32014-03-10 01:32:01 -040091 if (origin)
92 printf_ln(rebasing ?
93 _("Branch %s set up to track remote branch %s from %s by rebasing.") :
94 _("Branch %s set up to track remote branch %s from %s."),
95 local, shortname, origin);
96 else
97 printf_ln(rebasing ?
98 _("Branch %s set up to track local branch %s by rebasing.") :
99 _("Branch %s set up to track local branch %s."),
100 local, shortname);
101 } else {
102 if (origin)
103 printf_ln(rebasing ?
104 _("Branch %s set up to track remote ref %s by rebasing.") :
105 _("Branch %s set up to track remote ref %s."),
106 local, remote);
107 else
108 printf_ln(rebasing ?
109 _("Branch %s set up to track local ref %s by rebasing.") :
110 _("Branch %s set up to track local ref %s."),
111 local, remote);
112 }
Junio C Hamano72f60082009-03-10 01:20:42 -0700113 }
Patrick Steinhardt27852b22016-02-22 12:23:23 +0100114
115 return 0;
116
117out_err:
118 strbuf_release(&key);
119 error(_("Unable to write upstream branch configuration"));
120
121 advise(_(tracking_advice),
122 origin ? origin : "",
123 origin ? "/" : "",
124 shortname ? shortname : remote);
125
126 return -1;
Junio C Hamanoa9f2c132009-03-03 22:29:55 -0800127}
128
Daniel Barkalowe496c002008-02-07 11:40:08 -0500129/*
130 * This is called when new_ref is branched off of orig_ref, and tries
131 * to infer the settings for branch.<new_ref>.{remote,merge} from the
132 * config.
133 */
Patrick Steinhardt27852b22016-02-22 12:23:23 +0100134static void setup_tracking(const char *new_ref, const char *orig_ref,
135 enum branch_track track, int quiet)
Daniel Barkalowe496c002008-02-07 11:40:08 -0500136{
Daniel Barkalowe496c002008-02-07 11:40:08 -0500137 struct tracking tracking;
Jeff Kingf9a482e2012-03-26 19:51:01 -0400138 int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
Daniel Barkalowe496c002008-02-07 11:40:08 -0500139
Daniel Barkalowe496c002008-02-07 11:40:08 -0500140 memset(&tracking, 0, sizeof(tracking));
141 tracking.spec.dst = (char *)orig_ref;
Jay Soffian9ed36cf2008-02-19 11:24:37 -0500142 if (for_each_remote(find_tracked_branch, &tracking))
Patrick Steinhardt27852b22016-02-22 12:23:23 +0100143 return;
Daniel Barkalowe496c002008-02-07 11:40:08 -0500144
Jay Soffian9ed36cf2008-02-19 11:24:37 -0500145 if (!tracking.matches)
146 switch (track) {
147 case BRANCH_TRACK_ALWAYS:
148 case BRANCH_TRACK_EXPLICIT:
Ilari Liusvaara4fc50062010-01-18 22:44:11 +0200149 case BRANCH_TRACK_OVERRIDE:
Jay Soffian9ed36cf2008-02-19 11:24:37 -0500150 break;
151 default:
Patrick Steinhardt27852b22016-02-22 12:23:23 +0100152 return;
Jay Soffian9ed36cf2008-02-19 11:24:37 -0500153 }
154
Daniel Barkalowe496c002008-02-07 11:40:08 -0500155 if (tracking.matches > 1)
Patrick Steinhardt27852b22016-02-22 12:23:23 +0100156 die(_("Not tracking: ambiguous information for ref %s"),
157 orig_ref);
Daniel Barkalowe496c002008-02-07 11:40:08 -0500158
Patrick Steinhardt27852b22016-02-22 12:23:23 +0100159 if (install_branch_config(config_flags, new_ref, tracking.remote,
160 tracking.src ? tracking.src : orig_ref) < 0)
161 exit(-1);
Daniel Barkalowe496c002008-02-07 11:40:08 -0500162
Junio C Hamanoa9f2c132009-03-03 22:29:55 -0800163 free(tracking.src);
Daniel Barkalowe496c002008-02-07 11:40:08 -0500164}
165
Junio C Hamano6f9a3322011-09-21 20:19:38 -0700166int read_branch_desc(struct strbuf *buf, const char *branch_name)
167{
Tanay Abhra540b0f42014-08-07 23:26:42 +0530168 char *v = NULL;
Junio C Hamano6f9a3322011-09-21 20:19:38 -0700169 struct strbuf name = STRBUF_INIT;
170 strbuf_addf(&name, "branch.%s.description", branch_name);
Tanay Abhra540b0f42014-08-07 23:26:42 +0530171 if (git_config_get_string(name.buf, &v)) {
172 strbuf_release(&name);
173 return -1;
174 }
175 strbuf_addstr(buf, v);
176 free(v);
Junio C Hamano6f9a3322011-09-21 20:19:38 -0700177 strbuf_release(&name);
178 return 0;
179}
180
Junio C Hamanofa799372011-09-16 16:28:38 -0700181int validate_new_branchname(const char *name, struct strbuf *ref,
182 int force, int attr_only)
Conrad Irwin55c4a672011-08-20 14:49:48 -0700183{
Conrad Irwin55c4a672011-08-20 14:49:48 -0700184 if (strbuf_check_branch_ref(ref, name))
Jiang Xinbc554df2013-04-16 11:37:50 +0800185 die(_("'%s' is not a valid branch name."), name);
Conrad Irwin55c4a672011-08-20 14:49:48 -0700186
187 if (!ref_exists(ref->buf))
188 return 0;
Junio C Hamanofa799372011-09-16 16:28:38 -0700189 else if (!force && !attr_only)
Jiang Xinbc554df2013-04-16 11:37:50 +0800190 die(_("A branch named '%s' already exists."), ref->buf + strlen("refs/heads/"));
Conrad Irwin55c4a672011-08-20 14:49:48 -0700191
Junio C Hamanofa799372011-09-16 16:28:38 -0700192 if (!attr_only) {
193 const char *head;
194 unsigned char sha1[20];
Conrad Irwin55c4a672011-08-20 14:49:48 -0700195
Ronnie Sahlberg7695d112014-07-15 12:59:36 -0700196 head = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
Junio C Hamanofa799372011-09-16 16:28:38 -0700197 if (!is_bare_repository() && head && !strcmp(head, ref->buf))
Jiang Xinbc554df2013-04-16 11:37:50 +0800198 die(_("Cannot force update the current branch."));
Junio C Hamanofa799372011-09-16 16:28:38 -0700199 }
Conrad Irwin55c4a672011-08-20 14:49:48 -0700200 return 1;
201}
202
Johan Herland41c21f22013-04-21 23:52:05 +0200203static int check_tracking_branch(struct remote *remote, void *cb_data)
204{
205 char *tracking_branch = cb_data;
206 struct refspec query;
207 memset(&query, 0, sizeof(struct refspec));
208 query.dst = tracking_branch;
Per Cederqvist1d7358c2013-09-08 22:58:15 +0200209 return !remote_find_tracking(remote, &query);
Johan Herland41c21f22013-04-21 23:52:05 +0200210}
211
212static int validate_remote_tracking_branch(char *ref)
213{
214 return !for_each_remote(check_tracking_branch, ref);
215}
216
Jeff Kinge2b6aa52013-04-02 15:03:55 -0400217static const char upstream_not_branch[] =
Jeff King1a15d002013-04-02 15:04:51 -0400218N_("Cannot setup tracking information; starting point '%s' is not a branch.");
Jeff Kinga5e91c72013-04-02 15:04:27 -0400219static const char upstream_missing[] =
Jeff Kingcaa20362013-04-02 15:05:12 -0400220N_("the requested upstream branch '%s' does not exist");
221static const char upstream_advice[] =
222N_("\n"
223"If you are planning on basing your work on an upstream\n"
224"branch that already exists at the remote, you may need to\n"
225"run \"git fetch\" to retrieve it.\n"
226"\n"
227"If you are planning to push out a new local branch that\n"
228"will track its remote counterpart, you may want to use\n"
229"\"git push -u\" to set the upstream config as you push.");
Jeff Kinge2b6aa52013-04-02 15:03:55 -0400230
Jeff King4bd488e2016-11-04 12:30:12 -0400231void create_branch(const char *name, const char *start_name,
Jonathan Nieder39bd6f72011-11-26 02:54:55 -0600232 int force, int reflog, int clobber_head,
Jeff Kingf9a482e2012-03-26 19:51:01 -0400233 int quiet, enum branch_track track)
Daniel Barkalowe496c002008-02-07 11:40:08 -0500234{
Daniel Barkalowe496c002008-02-07 11:40:08 -0500235 struct commit *commit;
236 unsigned char sha1[20];
Junio C Hamano8415d5c2009-02-13 23:08:05 -0800237 char *real_ref, msg[PATH_MAX + 20];
238 struct strbuf ref = STRBUF_INIT;
Daniel Barkalowe496c002008-02-07 11:40:08 -0500239 int forcing = 0;
Ilari Liusvaara4fc50062010-01-18 22:44:11 +0200240 int dont_change_ref = 0;
241 int explicit_tracking = 0;
242
243 if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
244 explicit_tracking = 1;
Daniel Barkalowe496c002008-02-07 11:40:08 -0500245
Junio C Hamanofa799372011-09-16 16:28:38 -0700246 if (validate_new_branchname(name, &ref, force,
Jonathan Nieder39bd6f72011-11-26 02:54:55 -0600247 track == BRANCH_TRACK_OVERRIDE ||
248 clobber_head)) {
Conrad Irwin55c4a672011-08-20 14:49:48 -0700249 if (!force)
Ilari Liusvaara4fc50062010-01-18 22:44:11 +0200250 dont_change_ref = 1;
Conrad Irwin55c4a672011-08-20 14:49:48 -0700251 else
252 forcing = 1;
Daniel Barkalowe496c002008-02-07 11:40:08 -0500253 }
254
255 real_ref = NULL;
Jeff Kinga5e91c72013-04-02 15:04:27 -0400256 if (get_sha1(start_name, sha1)) {
Jeff Kingcaa20362013-04-02 15:05:12 -0400257 if (explicit_tracking) {
258 if (advice_set_upstream_failure) {
259 error(_(upstream_missing), start_name);
260 advise(_(upstream_advice));
261 exit(1);
262 }
Jeff King1a15d002013-04-02 15:04:51 -0400263 die(_(upstream_missing), start_name);
Jeff Kingcaa20362013-04-02 15:05:12 -0400264 }
Jiang Xinbc554df2013-04-16 11:37:50 +0800265 die(_("Not a valid object name: '%s'."), start_name);
Jeff Kinga5e91c72013-04-02 15:04:27 -0400266 }
Daniel Barkalowe496c002008-02-07 11:40:08 -0500267
268 switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) {
269 case 0:
270 /* Not branching from any existing branch */
Ilari Liusvaara4fc50062010-01-18 22:44:11 +0200271 if (explicit_tracking)
Jeff King1a15d002013-04-02 15:04:51 -0400272 die(_(upstream_not_branch), start_name);
Daniel Barkalowe496c002008-02-07 11:40:08 -0500273 break;
274 case 1:
Johan Herland21b5b1e2011-02-17 00:12:20 +0100275 /* Unique completion -- good, only if it is a real branch */
Christian Couder59556542013-11-30 21:55:40 +0100276 if (!starts_with(real_ref, "refs/heads/") &&
Johan Herland41c21f22013-04-21 23:52:05 +0200277 validate_remote_tracking_branch(real_ref)) {
Johan Herland21b5b1e2011-02-17 00:12:20 +0100278 if (explicit_tracking)
Jeff King1a15d002013-04-02 15:04:51 -0400279 die(_(upstream_not_branch), start_name);
Johan Herland21b5b1e2011-02-17 00:12:20 +0100280 else
281 real_ref = NULL;
282 }
Daniel Barkalowe496c002008-02-07 11:40:08 -0500283 break;
284 default:
Jiang Xinbc554df2013-04-16 11:37:50 +0800285 die(_("Ambiguous object name: '%s'."), start_name);
Daniel Barkalowe496c002008-02-07 11:40:08 -0500286 break;
287 }
288
289 if ((commit = lookup_commit_reference(sha1)) == NULL)
Jiang Xinbc554df2013-04-16 11:37:50 +0800290 die(_("Not a valid branch point: '%s'."), start_name);
brian m. carlsoned1c9972015-11-10 02:22:29 +0000291 hashcpy(sha1, commit->object.oid.hash);
Daniel Barkalowe496c002008-02-07 11:40:08 -0500292
Daniel Barkalowe496c002008-02-07 11:40:08 -0500293 if (forcing)
Junio C Hamanoda288e22010-04-09 20:42:10 -0700294 snprintf(msg, sizeof msg, "branch: Reset to %s",
Daniel Barkalowe496c002008-02-07 11:40:08 -0500295 start_name);
Ilari Liusvaara4fc50062010-01-18 22:44:11 +0200296 else if (!dont_change_ref)
Daniel Barkalowe496c002008-02-07 11:40:08 -0500297 snprintf(msg, sizeof msg, "branch: Created from %s",
298 start_name);
299
Ronnie Sahlbergd43f9902014-04-16 16:21:53 -0700300 if (reflog)
301 log_all_ref_updates = 1;
302
303 if (!dont_change_ref) {
304 struct ref_transaction *transaction;
305 struct strbuf err = STRBUF_INIT;
306
307 transaction = ref_transaction_begin(&err);
308 if (!transaction ||
Michael Haggerty1d147bd2015-02-17 18:00:15 +0100309 ref_transaction_update(transaction, ref.buf,
310 sha1, forcing ? NULL : null_sha1,
311 0, msg, &err) ||
Ronnie Sahlbergdb7516a2014-04-30 12:22:42 -0700312 ref_transaction_commit(transaction, &err))
Ronnie Sahlbergd43f9902014-04-16 16:21:53 -0700313 die("%s", err.buf);
314 ref_transaction_free(transaction);
315 strbuf_release(&err);
316 }
317
Daniel Barkalowe496c002008-02-07 11:40:08 -0500318 if (real_ref && track)
Felipe Contreras82a06722013-08-30 16:56:46 -0500319 setup_tracking(ref.buf + 11, real_ref, track, quiet);
Daniel Barkalowe496c002008-02-07 11:40:08 -0500320
Junio C Hamano8415d5c2009-02-13 23:08:05 -0800321 strbuf_release(&ref);
Jay Soffian9ed36cf2008-02-19 11:24:37 -0500322 free(real_ref);
Daniel Barkalowe496c002008-02-07 11:40:08 -0500323}
Daniel Barkalowc369e7b2008-02-07 11:40:16 -0500324
325void remove_branch_state(void)
326{
Jeff Kingf9327292015-08-10 05:38:57 -0400327 unlink(git_path_cherry_pick_head());
328 unlink(git_path_revert_head());
329 unlink(git_path_merge_head());
330 unlink(git_path_merge_rr());
331 unlink(git_path_merge_msg());
332 unlink(git_path_merge_mode());
333 unlink(git_path_squash_msg());
Daniel Barkalowc369e7b2008-02-07 11:40:16 -0500334}
Eric Sunshineed89f842015-07-17 19:00:04 -0400335
Nguyễn Thái Ngọc Duy8d9fdd72016-04-22 20:01:33 +0700336void die_if_checked_out(const char *branch, int ignore_current_worktree)
David Turner41af6562015-08-10 13:52:44 -0400337{
Nguyễn Thái Ngọc Duyd3b9ac02016-04-22 20:01:27 +0700338 const struct worktree *wt;
David Turner41af6562015-08-10 13:52:44 -0400339
Nguyễn Thái Ngọc Duyd3b9ac02016-04-22 20:01:27 +0700340 wt = find_shared_symref("HEAD", branch);
Nguyễn Thái Ngọc Duy8d9fdd72016-04-22 20:01:33 +0700341 if (!wt || (ignore_current_worktree && wt->is_current))
Nguyễn Thái Ngọc Duyd3b9ac02016-04-22 20:01:27 +0700342 return;
343 skip_prefix(branch, "refs/heads/", &branch);
344 die(_("'%s' is already checked out at '%s'"),
345 branch, wt->path);
Eric Sunshineed89f842015-07-17 19:00:04 -0400346}
Kazuki Yamaguchi70999e92016-03-27 23:37:14 +0900347
348int replace_each_worktree_head_symref(const char *oldref, const char *newref)
349{
350 int ret = 0;
351 struct worktree **worktrees = get_worktrees();
352 int i;
353
354 for (i = 0; worktrees[i]; i++) {
355 if (worktrees[i]->is_detached)
356 continue;
357 if (strcmp(oldref, worktrees[i]->head_ref))
358 continue;
359
Nguyễn Thái Ngọc Duy69dfe3b2016-04-22 20:01:26 +0700360 if (set_worktree_head_symref(get_worktree_git_dir(worktrees[i]),
361 newref)) {
Kazuki Yamaguchi70999e92016-03-27 23:37:14 +0900362 ret = -1;
363 error(_("HEAD of working tree %s is not updated"),
364 worktrees[i]->path);
365 }
366 }
367
368 free_worktrees(worktrees);
369 return ret;
370}