🌐 AI搜索 & 代理 主页
blob: 4bab55a9a85e187e2a3906312f1e771f4a214f45 [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"
3#include "branch.h"
4#include "refs.h"
5#include "remote.h"
6#include "commit.h"
7
8struct tracking {
9 struct refspec spec;
10 char *src;
11 const char *remote;
12 int matches;
13};
14
15static int find_tracked_branch(struct remote *remote, void *priv)
16{
17 struct tracking *tracking = priv;
18
19 if (!remote_find_tracking(remote, &tracking->spec)) {
20 if (++tracking->matches == 1) {
21 tracking->src = tracking->spec.src;
22 tracking->remote = remote->name;
23 } else {
24 free(tracking->spec.src);
25 if (tracking->src) {
26 free(tracking->src);
27 tracking->src = NULL;
28 }
29 }
30 tracking->spec.src = NULL;
31 }
32
33 return 0;
34}
35
Junio C Hamanoa9f2c132009-03-04 06:29:5536static int should_setup_rebase(const char *origin)
Dustin Sallingsc998ae92008-05-10 22:36:2937{
38 switch (autorebase) {
39 case AUTOREBASE_NEVER:
40 return 0;
41 case AUTOREBASE_LOCAL:
Junio C Hamanoa9f2c132009-03-04 06:29:5542 return origin == NULL;
Dustin Sallingsc998ae92008-05-10 22:36:2943 case AUTOREBASE_REMOTE:
Junio C Hamanoa9f2c132009-03-04 06:29:5544 return origin != NULL;
Dustin Sallingsc998ae92008-05-10 22:36:2945 case AUTOREBASE_ALWAYS:
46 return 1;
47 }
48 return 0;
49}
50
Junio C Hamanoa9f2c132009-03-04 06:29:5551void install_branch_config(int flag, const char *local, const char *origin, const char *remote)
52{
Jeff Kingcf4fff52014-06-18 19:44:1953 const char *shortname = NULL;
Junio C Hamanoa9f2c132009-03-04 06:29:5554 struct strbuf key = STRBUF_INIT;
55 int rebasing = should_setup_rebase(origin);
56
Jeff Kingcf4fff52014-06-18 19:44:1957 if (skip_prefix(remote, "refs/heads/", &shortname)
Matthieu Moy85e22332010-01-18 20:44:1258 && !strcmp(local, shortname)
59 && !origin) {
Jiang Xinbc554df2013-04-16 03:37:5060 warning(_("Not setting branch %s as its own upstream."),
Matthieu Moy85e22332010-01-18 20:44:1261 local);
62 return;
63 }
64
Junio C Hamanoa9f2c132009-03-04 06:29:5565 strbuf_addf(&key, "branch.%s.remote", local);
66 git_config_set(key.buf, origin ? origin : ".");
67
68 strbuf_reset(&key);
69 strbuf_addf(&key, "branch.%s.merge", local);
70 git_config_set(key.buf, remote);
71
72 if (rebasing) {
73 strbuf_reset(&key);
74 strbuf_addf(&key, "branch.%s.rebase", local);
75 git_config_set(key.buf, "true");
76 }
Nguyễn Thái Ngọc Duyd53a35032012-06-07 12:05:1077 strbuf_release(&key);
Junio C Hamanoa9f2c132009-03-04 06:29:5578
Junio C Hamano72f60082009-03-10 08:20:4279 if (flag & BRANCH_CONFIG_VERBOSE) {
Junio C Hamano1d9aaed2014-03-31 23:31:1980 if (shortname) {
Adam9fe0cf32014-03-10 05:32:0181 if (origin)
82 printf_ln(rebasing ?
83 _("Branch %s set up to track remote branch %s from %s by rebasing.") :
84 _("Branch %s set up to track remote branch %s from %s."),
85 local, shortname, origin);
86 else
87 printf_ln(rebasing ?
88 _("Branch %s set up to track local branch %s by rebasing.") :
89 _("Branch %s set up to track local branch %s."),
90 local, shortname);
91 } else {
92 if (origin)
93 printf_ln(rebasing ?
94 _("Branch %s set up to track remote ref %s by rebasing.") :
95 _("Branch %s set up to track remote ref %s."),
96 local, remote);
97 else
98 printf_ln(rebasing ?
99 _("Branch %s set up to track local ref %s by rebasing.") :
100 _("Branch %s set up to track local ref %s."),
101 local, remote);
102 }
Junio C Hamano72f60082009-03-10 08:20:42103 }
Junio C Hamanoa9f2c132009-03-04 06:29:55104}
105
Daniel Barkalowe496c002008-02-07 16:40:08106/*
107 * This is called when new_ref is branched off of orig_ref, and tries
108 * to infer the settings for branch.<new_ref>.{remote,merge} from the
109 * config.
110 */
Jay Soffian9ed36cf2008-02-19 16:24:37111static int setup_tracking(const char *new_ref, const char *orig_ref,
Jeff Kingf9a482e2012-03-26 23:51:01112 enum branch_track track, int quiet)
Daniel Barkalowe496c002008-02-07 16:40:08113{
Daniel Barkalowe496c002008-02-07 16:40:08114 struct tracking tracking;
Jeff Kingf9a482e2012-03-26 23:51:01115 int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
Daniel Barkalowe496c002008-02-07 16:40:08116
Daniel Barkalowe496c002008-02-07 16:40:08117 memset(&tracking, 0, sizeof(tracking));
118 tracking.spec.dst = (char *)orig_ref;
Jay Soffian9ed36cf2008-02-19 16:24:37119 if (for_each_remote(find_tracked_branch, &tracking))
Daniel Barkalowe496c002008-02-07 16:40:08120 return 1;
121
Jay Soffian9ed36cf2008-02-19 16:24:37122 if (!tracking.matches)
123 switch (track) {
124 case BRANCH_TRACK_ALWAYS:
125 case BRANCH_TRACK_EXPLICIT:
Ilari Liusvaara4fc50062010-01-18 20:44:11126 case BRANCH_TRACK_OVERRIDE:
Jay Soffian9ed36cf2008-02-19 16:24:37127 break;
128 default:
129 return 1;
130 }
131
Daniel Barkalowe496c002008-02-07 16:40:08132 if (tracking.matches > 1)
Jiang Xinbc554df2013-04-16 03:37:50133 return error(_("Not tracking: ambiguous information for ref %s"),
Daniel Barkalowe496c002008-02-07 16:40:08134 orig_ref);
135
Jeff Kingf9a482e2012-03-26 23:51:01136 install_branch_config(config_flags, new_ref, tracking.remote,
Junio C Hamanoa9f2c132009-03-04 06:29:55137 tracking.src ? tracking.src : orig_ref);
Daniel Barkalowe496c002008-02-07 16:40:08138
Junio C Hamanoa9f2c132009-03-04 06:29:55139 free(tracking.src);
Daniel Barkalowe496c002008-02-07 16:40:08140 return 0;
141}
142
Junio C Hamano6f9a3322011-09-22 03:19:38143int read_branch_desc(struct strbuf *buf, const char *branch_name)
144{
Tanay Abhra540b0f42014-08-07 17:56:42145 char *v = NULL;
Junio C Hamano6f9a3322011-09-22 03:19:38146 struct strbuf name = STRBUF_INIT;
147 strbuf_addf(&name, "branch.%s.description", branch_name);
Tanay Abhra540b0f42014-08-07 17:56:42148 if (git_config_get_string(name.buf, &v)) {
149 strbuf_release(&name);
150 return -1;
151 }
152 strbuf_addstr(buf, v);
153 free(v);
Junio C Hamano6f9a3322011-09-22 03:19:38154 strbuf_release(&name);
155 return 0;
156}
157
Junio C Hamanofa799372011-09-16 23:28:38158int validate_new_branchname(const char *name, struct strbuf *ref,
159 int force, int attr_only)
Conrad Irwin55c4a672011-08-20 21:49:48160{
Conrad Irwin55c4a672011-08-20 21:49:48161 if (strbuf_check_branch_ref(ref, name))
Jiang Xinbc554df2013-04-16 03:37:50162 die(_("'%s' is not a valid branch name."), name);
Conrad Irwin55c4a672011-08-20 21:49:48163
164 if (!ref_exists(ref->buf))
165 return 0;
Junio C Hamanofa799372011-09-16 23:28:38166 else if (!force && !attr_only)
Jiang Xinbc554df2013-04-16 03:37:50167 die(_("A branch named '%s' already exists."), ref->buf + strlen("refs/heads/"));
Conrad Irwin55c4a672011-08-20 21:49:48168
Junio C Hamanofa799372011-09-16 23:28:38169 if (!attr_only) {
170 const char *head;
171 unsigned char sha1[20];
Conrad Irwin55c4a672011-08-20 21:49:48172
Ronnie Sahlberg7695d112014-07-15 19:59:36173 head = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
Junio C Hamanofa799372011-09-16 23:28:38174 if (!is_bare_repository() && head && !strcmp(head, ref->buf))
Jiang Xinbc554df2013-04-16 03:37:50175 die(_("Cannot force update the current branch."));
Junio C Hamanofa799372011-09-16 23:28:38176 }
Conrad Irwin55c4a672011-08-20 21:49:48177 return 1;
178}
179
Johan Herland41c21f22013-04-21 21:52:05180static int check_tracking_branch(struct remote *remote, void *cb_data)
181{
182 char *tracking_branch = cb_data;
183 struct refspec query;
184 memset(&query, 0, sizeof(struct refspec));
185 query.dst = tracking_branch;
Per Cederqvist1d7358c2013-09-08 20:58:15186 return !remote_find_tracking(remote, &query);
Johan Herland41c21f22013-04-21 21:52:05187}
188
189static int validate_remote_tracking_branch(char *ref)
190{
191 return !for_each_remote(check_tracking_branch, ref);
192}
193
Jeff Kinge2b6aa52013-04-02 19:03:55194static const char upstream_not_branch[] =
Jeff King1a15d002013-04-02 19:04:51195N_("Cannot setup tracking information; starting point '%s' is not a branch.");
Jeff Kinga5e91c72013-04-02 19:04:27196static const char upstream_missing[] =
Jeff Kingcaa20362013-04-02 19:05:12197N_("the requested upstream branch '%s' does not exist");
198static const char upstream_advice[] =
199N_("\n"
200"If you are planning on basing your work on an upstream\n"
201"branch that already exists at the remote, you may need to\n"
202"run \"git fetch\" to retrieve it.\n"
203"\n"
204"If you are planning to push out a new local branch that\n"
205"will track its remote counterpart, you may want to use\n"
206"\"git push -u\" to set the upstream config as you push.");
Jeff Kinge2b6aa52013-04-02 19:03:55207
Daniel Barkalowe496c002008-02-07 16:40:08208void create_branch(const char *head,
209 const char *name, const char *start_name,
Jonathan Nieder39bd6f72011-11-26 08:54:55210 int force, int reflog, int clobber_head,
Jeff Kingf9a482e2012-03-26 23:51:01211 int quiet, enum branch_track track)
Daniel Barkalowe496c002008-02-07 16:40:08212{
Daniel Barkalowe496c002008-02-07 16:40:08213 struct commit *commit;
214 unsigned char sha1[20];
Junio C Hamano8415d5c2009-02-14 07:08:05215 char *real_ref, msg[PATH_MAX + 20];
216 struct strbuf ref = STRBUF_INIT;
Daniel Barkalowe496c002008-02-07 16:40:08217 int forcing = 0;
Ilari Liusvaara4fc50062010-01-18 20:44:11218 int dont_change_ref = 0;
219 int explicit_tracking = 0;
220
221 if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
222 explicit_tracking = 1;
Daniel Barkalowe496c002008-02-07 16:40:08223
Junio C Hamanofa799372011-09-16 23:28:38224 if (validate_new_branchname(name, &ref, force,
Jonathan Nieder39bd6f72011-11-26 08:54:55225 track == BRANCH_TRACK_OVERRIDE ||
226 clobber_head)) {
Conrad Irwin55c4a672011-08-20 21:49:48227 if (!force)
Ilari Liusvaara4fc50062010-01-18 20:44:11228 dont_change_ref = 1;
Conrad Irwin55c4a672011-08-20 21:49:48229 else
230 forcing = 1;
Daniel Barkalowe496c002008-02-07 16:40:08231 }
232
233 real_ref = NULL;
Jeff Kinga5e91c72013-04-02 19:04:27234 if (get_sha1(start_name, sha1)) {
Jeff Kingcaa20362013-04-02 19:05:12235 if (explicit_tracking) {
236 if (advice_set_upstream_failure) {
237 error(_(upstream_missing), start_name);
238 advise(_(upstream_advice));
239 exit(1);
240 }
Jeff King1a15d002013-04-02 19:04:51241 die(_(upstream_missing), start_name);
Jeff Kingcaa20362013-04-02 19:05:12242 }
Jiang Xinbc554df2013-04-16 03:37:50243 die(_("Not a valid object name: '%s'."), start_name);
Jeff Kinga5e91c72013-04-02 19:04:27244 }
Daniel Barkalowe496c002008-02-07 16:40:08245
246 switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) {
247 case 0:
248 /* Not branching from any existing branch */
Ilari Liusvaara4fc50062010-01-18 20:44:11249 if (explicit_tracking)
Jeff King1a15d002013-04-02 19:04:51250 die(_(upstream_not_branch), start_name);
Daniel Barkalowe496c002008-02-07 16:40:08251 break;
252 case 1:
Johan Herland21b5b1e2011-02-16 23:12:20253 /* Unique completion -- good, only if it is a real branch */
Christian Couder59556542013-11-30 20:55:40254 if (!starts_with(real_ref, "refs/heads/") &&
Johan Herland41c21f22013-04-21 21:52:05255 validate_remote_tracking_branch(real_ref)) {
Johan Herland21b5b1e2011-02-16 23:12:20256 if (explicit_tracking)
Jeff King1a15d002013-04-02 19:04:51257 die(_(upstream_not_branch), start_name);
Johan Herland21b5b1e2011-02-16 23:12:20258 else
259 real_ref = NULL;
260 }
Daniel Barkalowe496c002008-02-07 16:40:08261 break;
262 default:
Jiang Xinbc554df2013-04-16 03:37:50263 die(_("Ambiguous object name: '%s'."), start_name);
Daniel Barkalowe496c002008-02-07 16:40:08264 break;
265 }
266
267 if ((commit = lookup_commit_reference(sha1)) == NULL)
Jiang Xinbc554df2013-04-16 03:37:50268 die(_("Not a valid branch point: '%s'."), start_name);
Daniel Barkalowe496c002008-02-07 16:40:08269 hashcpy(sha1, commit->object.sha1);
270
Daniel Barkalowe496c002008-02-07 16:40:08271 if (forcing)
Junio C Hamanoda288e22010-04-10 03:42:10272 snprintf(msg, sizeof msg, "branch: Reset to %s",
Daniel Barkalowe496c002008-02-07 16:40:08273 start_name);
Ilari Liusvaara4fc50062010-01-18 20:44:11274 else if (!dont_change_ref)
Daniel Barkalowe496c002008-02-07 16:40:08275 snprintf(msg, sizeof msg, "branch: Created from %s",
276 start_name);
277
Ronnie Sahlbergd43f9902014-04-16 23:21:53278 if (reflog)
279 log_all_ref_updates = 1;
280
281 if (!dont_change_ref) {
282 struct ref_transaction *transaction;
283 struct strbuf err = STRBUF_INIT;
284
285 transaction = ref_transaction_begin(&err);
286 if (!transaction ||
287 ref_transaction_update(transaction, ref.buf, sha1,
Ronnie Sahlbergdb7516a2014-04-30 19:22:42288 null_sha1, 0, !forcing, msg, &err) ||
289 ref_transaction_commit(transaction, &err))
Ronnie Sahlbergd43f9902014-04-16 23:21:53290 die("%s", err.buf);
291 ref_transaction_free(transaction);
292 strbuf_release(&err);
293 }
294
Daniel Barkalowe496c002008-02-07 16:40:08295 if (real_ref && track)
Felipe Contreras82a06722013-08-30 21:56:46296 setup_tracking(ref.buf + 11, real_ref, track, quiet);
Daniel Barkalowe496c002008-02-07 16:40:08297
Junio C Hamano8415d5c2009-02-14 07:08:05298 strbuf_release(&ref);
Jay Soffian9ed36cf2008-02-19 16:24:37299 free(real_ref);
Daniel Barkalowe496c002008-02-07 16:40:08300}
Daniel Barkalowc369e7b2008-02-07 16:40:16301
302void remove_branch_state(void)
303{
Jay Soffiand7e5c0c2011-02-20 04:12:27304 unlink(git_path("CHERRY_PICK_HEAD"));
Jonathan Nieder82433cd2011-11-22 11:17:36305 unlink(git_path("REVERT_HEAD"));
Daniel Barkalowc369e7b2008-02-07 16:40:16306 unlink(git_path("MERGE_HEAD"));
Johannes Schindelin0af0ac72008-07-12 14:56:19307 unlink(git_path("MERGE_RR"));
Daniel Barkalowc369e7b2008-02-07 16:40:16308 unlink(git_path("MERGE_MSG"));
Miklos Vajnacf10f9f2008-10-03 12:04:47309 unlink(git_path("MERGE_MODE"));
Daniel Barkalowc369e7b2008-02-07 16:40:16310 unlink(git_path("SQUASH_MSG"));
Daniel Barkalowc369e7b2008-02-07 16:40:16311}