1 #include "git-compat-util.h"
16 static int find_tracked_branch(struct remote *remote, void *priv)
18 struct tracking *tracking = priv;
20 if (!remote_find_tracking(remote, &tracking->spec)) {
21 if (++tracking->matches == 1) {
22 tracking->src = tracking->spec.src;
23 tracking->remote = remote->name;
25 free(tracking->spec.src);
31 tracking->spec.src = NULL;
37 static int should_setup_rebase(const char *origin)
40 case AUTOREBASE_NEVER:
42 case AUTOREBASE_LOCAL:
43 return origin == NULL;
44 case AUTOREBASE_REMOTE:
45 return origin != NULL;
46 case AUTOREBASE_ALWAYS:
52 void install_branch_config(int flag, const char *local, const char *origin, const char *remote)
54 const char *shortname = NULL;
55 struct strbuf key = STRBUF_INIT;
56 int rebasing = should_setup_rebase(origin);
58 if (skip_prefix(remote, "refs/heads/", &shortname)
59 && !strcmp(local, shortname)
61 warning(_("Not setting branch %s as its own upstream."),
66 strbuf_addf(&key, "branch.%s.remote", local);
67 git_config_set(key.buf, origin ? origin : ".");
70 strbuf_addf(&key, "branch.%s.merge", local);
71 git_config_set(key.buf, remote);
75 strbuf_addf(&key, "branch.%s.rebase", local);
76 git_config_set(key.buf, "true");
80 if (flag & BRANCH_CONFIG_VERBOSE) {
84 _("Branch %s set up to track remote branch %s from %s by rebasing.") :
85 _("Branch %s set up to track remote branch %s from %s."),
86 local, shortname, origin);
89 _("Branch %s set up to track local branch %s by rebasing.") :
90 _("Branch %s set up to track local branch %s."),
95 _("Branch %s set up to track remote ref %s by rebasing.") :
96 _("Branch %s set up to track remote ref %s."),
100 _("Branch %s set up to track local ref %s by rebasing.") :
101 _("Branch %s set up to track local ref %s."),
108 * This is called when new_ref is branched off of orig_ref, and tries
109 * to infer the settings for branch.<new_ref>.{remote,merge} from the
112 static int setup_tracking(const char *new_ref, const char *orig_ref,
113 enum branch_track track, int quiet)
115 struct tracking tracking;
116 int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
118 memset(&tracking, 0, sizeof(tracking));
119 tracking.spec.dst = (char *)orig_ref;
120 if (for_each_remote(find_tracked_branch, &tracking))
123 if (!tracking.matches)
125 case BRANCH_TRACK_ALWAYS:
126 case BRANCH_TRACK_EXPLICIT:
127 case BRANCH_TRACK_OVERRIDE:
133 if (tracking.matches > 1)
134 return error(_("Not tracking: ambiguous information for ref %s"),
137 install_branch_config(config_flags, new_ref, tracking.remote,
138 tracking.src ? tracking.src : orig_ref);
144 void install_branch_publish(const char *name, const char *remote, const char *remote_ref)
146 struct strbuf key = STRBUF_INIT;
148 if (!remote && !strcmp(name, remote_ref + 11) &&
149 starts_with(remote_ref, "refs/heads")) {
150 warning(_("Not setting branch %s as its own publish branch."), name);
154 strbuf_addf(&key, "branch.%s.pushremote", name);
155 git_config_set(key.buf, remote ? remote : ".");
158 strbuf_addf(&key, "branch.%s.push", name);
159 git_config_set(key.buf, remote_ref);
161 strbuf_release(&key);
164 int setup_publish(const char *name, const char *ref)
166 struct tracking tracking;
167 const char *remote, *remote_ref;
169 memset(&tracking, 0, sizeof(tracking));
170 tracking.spec.dst = (char *)ref;
171 if (for_each_remote(find_tracked_branch, &tracking))
174 if (tracking.matches > 1)
175 return error(_("Not tracking: ambiguous information for ref %s"),
178 remote = tracking.remote;
179 remote_ref = tracking.src ? tracking.src : ref;
181 install_branch_publish(name, remote, remote_ref);
188 int read_branch_desc(struct strbuf *buf, const char *branch_name)
191 struct strbuf name = STRBUF_INIT;
192 strbuf_addf(&name, "branch.%s.description", branch_name);
193 if (git_config_get_string(name.buf, &v)) {
194 strbuf_release(&name);
197 strbuf_addstr(buf, v);
199 strbuf_release(&name);
203 int validate_new_branchname(const char *name, struct strbuf *ref,
204 int force, int attr_only)
206 if (strbuf_check_branch_ref(ref, name))
207 die(_("'%s' is not a valid branch name."), name);
209 if (!ref_exists(ref->buf))
211 else if (!force && !attr_only)
212 die(_("A branch named '%s' already exists."), ref->buf + strlen("refs/heads/"));
216 unsigned char sha1[20];
218 head = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
219 if (!is_bare_repository() && head && !strcmp(head, ref->buf))
220 die(_("Cannot force update the current branch."));
225 static int check_tracking_branch(struct remote *remote, void *cb_data)
227 char *tracking_branch = cb_data;
228 struct refspec query;
229 memset(&query, 0, sizeof(struct refspec));
230 query.dst = tracking_branch;
231 return !remote_find_tracking(remote, &query);
234 static int validate_remote_tracking_branch(char *ref)
236 return !for_each_remote(check_tracking_branch, ref);
239 static const char upstream_not_branch[] =
240 N_("Cannot setup tracking information; starting point '%s' is not a branch.");
241 static const char upstream_missing[] =
242 N_("the requested upstream branch '%s' does not exist");
243 static const char upstream_advice[] =
245 "If you are planning on basing your work on an upstream\n"
246 "branch that already exists at the remote, you may need to\n"
247 "run \"git fetch\" to retrieve it.\n"
249 "If you are planning to push out a new local branch that\n"
250 "will track its remote counterpart, you may want to use\n"
251 "\"git push -u\" to set the upstream config as you push.");
253 void create_branch(const char *head,
254 const char *name, const char *start_name,
255 int force, int reflog, int clobber_head,
256 int quiet, enum branch_track track)
258 struct commit *commit;
259 unsigned char sha1[20];
260 char *real_ref, msg[PATH_MAX + 20];
261 struct strbuf ref = STRBUF_INIT;
263 int dont_change_ref = 0;
264 int explicit_tracking = 0;
266 if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
267 explicit_tracking = 1;
269 if (validate_new_branchname(name, &ref, force,
270 track == BRANCH_TRACK_OVERRIDE ||
279 if (get_sha1(start_name, sha1)) {
280 if (explicit_tracking) {
281 if (advice_set_upstream_failure) {
282 error(_(upstream_missing), start_name);
283 advise(_(upstream_advice));
286 die(_(upstream_missing), start_name);
288 die(_("Not a valid object name: '%s'."), start_name);
291 switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) {
293 /* Not branching from any existing branch */
294 if (explicit_tracking)
295 die(_(upstream_not_branch), start_name);
298 /* Unique completion -- good, only if it is a real branch */
299 if (!starts_with(real_ref, "refs/heads/") &&
300 validate_remote_tracking_branch(real_ref)) {
301 if (explicit_tracking)
302 die(_(upstream_not_branch), start_name);
308 die(_("Ambiguous object name: '%s'."), start_name);
312 if ((commit = lookup_commit_reference(sha1)) == NULL)
313 die(_("Not a valid branch point: '%s'."), start_name);
314 hashcpy(sha1, commit->object.oid.hash);
317 snprintf(msg, sizeof msg, "branch: Reset to %s",
319 else if (!dont_change_ref)
320 snprintf(msg, sizeof msg, "branch: Created from %s",
324 log_all_ref_updates = 1;
326 if (!dont_change_ref) {
327 struct ref_transaction *transaction;
328 struct strbuf err = STRBUF_INIT;
330 transaction = ref_transaction_begin(&err);
332 ref_transaction_update(transaction, ref.buf,
333 sha1, forcing ? NULL : null_sha1,
335 ref_transaction_commit(transaction, &err))
337 ref_transaction_free(transaction);
338 strbuf_release(&err);
341 if (real_ref && track)
342 setup_tracking(ref.buf + 11, real_ref, track, quiet);
344 strbuf_release(&ref);
348 void remove_branch_state(void)
350 unlink(git_path_cherry_pick_head());
351 unlink(git_path_revert_head());
352 unlink(git_path_merge_head());
353 unlink(git_path_merge_rr());
354 unlink(git_path_merge_msg());
355 unlink(git_path_merge_mode());
356 unlink(git_path_squash_msg());
359 void die_if_checked_out(const char *branch)
363 existing = find_shared_symref("HEAD", branch);
365 skip_prefix(branch, "refs/heads/", &branch);
366 die(_("'%s' is already checked out at '%s'"), branch, existing);