1 #include "git-compat-util.h"
15 static int find_tracked_branch(struct remote *remote, void *priv)
17 struct tracking *tracking = priv;
19 if (!remote_find_tracking(remote, &tracking->spec)) {
20 if (++tracking->matches == 1) {
21 tracking->src = tracking->spec.src;
22 tracking->remote = remote->name;
24 free(tracking->spec.src);
30 tracking->spec.src = NULL;
36 static int should_setup_rebase(const char *origin)
39 case AUTOREBASE_NEVER:
41 case AUTOREBASE_LOCAL:
42 return origin == NULL;
43 case AUTOREBASE_REMOTE:
44 return origin != NULL;
45 case AUTOREBASE_ALWAYS:
51 void install_branch_config(int flag, const char *local, const char *origin, const char *remote)
53 const char *shortname = skip_prefix(remote, "refs/heads/");
54 struct strbuf key = STRBUF_INIT;
55 int rebasing = should_setup_rebase(origin);
58 && !strcmp(local, shortname)
60 warning(_("Not setting branch %s as its own upstream."),
65 strbuf_addf(&key, "branch.%s.remote", local);
66 git_config_set(key.buf, origin ? origin : ".");
69 strbuf_addf(&key, "branch.%s.merge", local);
70 git_config_set(key.buf, remote);
74 strbuf_addf(&key, "branch.%s.rebase", local);
75 git_config_set(key.buf, "true");
79 if (flag & BRANCH_CONFIG_VERBOSE) {
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);
88 _("Branch %s set up to track local branch %s by rebasing.") :
89 _("Branch %s set up to track local branch %s."),
94 _("Branch %s set up to track remote ref %s by rebasing.") :
95 _("Branch %s set up to track remote ref %s."),
99 _("Branch %s set up to track local ref %s by rebasing.") :
100 _("Branch %s set up to track local ref %s."),
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
111 static int setup_tracking(const char *new_ref, const char *orig_ref,
112 enum branch_track track, int quiet)
114 struct tracking tracking;
115 int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
117 memset(&tracking, 0, sizeof(tracking));
118 tracking.spec.dst = (char *)orig_ref;
119 if (for_each_remote(find_tracked_branch, &tracking))
122 if (!tracking.matches)
124 case BRANCH_TRACK_ALWAYS:
125 case BRANCH_TRACK_EXPLICIT:
126 case BRANCH_TRACK_OVERRIDE:
132 if (tracking.matches > 1)
133 return error(_("Not tracking: ambiguous information for ref %s"),
136 install_branch_config(config_flags, new_ref, tracking.remote,
137 tracking.src ? tracking.src : orig_ref);
143 void install_branch_publish(const char *name, const char *remote, const char *remote_ref)
145 struct strbuf key = STRBUF_INIT;
147 if (!remote && !strcmp(name, remote_ref + 11) &&
148 starts_with(remote_ref, "refs/heads")) {
149 warning(_("Not setting branch %s as its own publish branch."), name);
153 strbuf_addf(&key, "branch.%s.pushremote", name);
154 git_config_set(key.buf, remote ? remote : ".");
157 strbuf_addf(&key, "branch.%s.push", name);
158 git_config_set(key.buf, remote_ref);
160 strbuf_release(&key);
163 int setup_publish(const char *name, const char *ref)
165 struct tracking tracking;
166 const char *remote, *remote_ref;
168 memset(&tracking, 0, sizeof(tracking));
169 tracking.spec.dst = (char *)ref;
170 if (for_each_remote(find_tracked_branch, &tracking))
173 if (tracking.matches > 1)
174 return error(_("Not tracking: ambiguous information for ref %s"),
177 remote = tracking.remote;
178 remote_ref = tracking.src ? tracking.src : ref;
180 install_branch_publish(name, remote, remote_ref);
187 struct branch_desc_cb {
188 const char *config_name;
192 static int read_branch_desc_cb(const char *var, const char *value, void *cb)
194 struct branch_desc_cb *desc = cb;
195 if (strcmp(desc->config_name, var))
197 free((char *)desc->value);
198 return git_config_string(&desc->value, var, value);
201 int read_branch_desc(struct strbuf *buf, const char *branch_name)
203 struct branch_desc_cb cb;
204 struct strbuf name = STRBUF_INIT;
205 strbuf_addf(&name, "branch.%s.description", branch_name);
206 cb.config_name = name.buf;
208 if (git_config(read_branch_desc_cb, &cb) < 0) {
209 strbuf_release(&name);
213 strbuf_addstr(buf, cb.value);
214 strbuf_release(&name);
218 int validate_new_branchname(const char *name, struct strbuf *ref,
219 int force, int attr_only)
221 if (strbuf_check_branch_ref(ref, name))
222 die(_("'%s' is not a valid branch name."), name);
224 if (!ref_exists(ref->buf))
226 else if (!force && !attr_only)
227 die(_("A branch named '%s' already exists."), ref->buf + strlen("refs/heads/"));
231 unsigned char sha1[20];
233 head = resolve_ref_unsafe("HEAD", sha1, 0, NULL);
234 if (!is_bare_repository() && head && !strcmp(head, ref->buf))
235 die(_("Cannot force update the current branch."));
240 static int check_tracking_branch(struct remote *remote, void *cb_data)
242 char *tracking_branch = cb_data;
243 struct refspec query;
244 memset(&query, 0, sizeof(struct refspec));
245 query.dst = tracking_branch;
246 return !remote_find_tracking(remote, &query);
249 static int validate_remote_tracking_branch(char *ref)
251 return !for_each_remote(check_tracking_branch, ref);
254 static const char upstream_not_branch[] =
255 N_("Cannot setup tracking information; starting point '%s' is not a branch.");
256 static const char upstream_missing[] =
257 N_("the requested upstream branch '%s' does not exist");
258 static const char upstream_advice[] =
260 "If you are planning on basing your work on an upstream\n"
261 "branch that already exists at the remote, you may need to\n"
262 "run \"git fetch\" to retrieve it.\n"
264 "If you are planning to push out a new local branch that\n"
265 "will track its remote counterpart, you may want to use\n"
266 "\"git push -u\" to set the upstream config as you push.");
268 void create_branch(const char *head,
269 const char *name, const char *start_name,
270 int force, int reflog, int clobber_head,
271 int quiet, enum branch_track track)
273 struct ref_lock *lock = NULL;
274 struct commit *commit;
275 unsigned char sha1[20];
276 char *real_ref, msg[PATH_MAX + 20];
277 struct strbuf ref = STRBUF_INIT;
279 int dont_change_ref = 0;
280 int explicit_tracking = 0;
282 if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
283 explicit_tracking = 1;
285 if (validate_new_branchname(name, &ref, force,
286 track == BRANCH_TRACK_OVERRIDE ||
295 if (get_sha1(start_name, sha1)) {
296 if (explicit_tracking) {
297 if (advice_set_upstream_failure) {
298 error(_(upstream_missing), start_name);
299 advise(_(upstream_advice));
302 die(_(upstream_missing), start_name);
304 die(_("Not a valid object name: '%s'."), start_name);
307 switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) {
309 /* Not branching from any existing branch */
310 if (explicit_tracking)
311 die(_(upstream_not_branch), start_name);
314 /* Unique completion -- good, only if it is a real branch */
315 if (!starts_with(real_ref, "refs/heads/") &&
316 validate_remote_tracking_branch(real_ref)) {
317 if (explicit_tracking)
318 die(_(upstream_not_branch), start_name);
324 die(_("Ambiguous object name: '%s'."), start_name);
328 if ((commit = lookup_commit_reference(sha1)) == NULL)
329 die(_("Not a valid branch point: '%s'."), start_name);
330 hashcpy(sha1, commit->object.sha1);
332 if (!dont_change_ref) {
333 lock = lock_any_ref_for_update(ref.buf, NULL, 0, NULL);
335 die_errno(_("Failed to lock ref for update"));
339 log_all_ref_updates = 1;
342 snprintf(msg, sizeof msg, "branch: Reset to %s",
344 else if (!dont_change_ref)
345 snprintf(msg, sizeof msg, "branch: Created from %s",
348 if (real_ref && track)
349 setup_tracking(ref.buf + 11, real_ref, track, quiet);
351 if (!dont_change_ref)
352 if (write_ref_sha1(lock, sha1, msg) < 0)
353 die_errno(_("Failed to write ref"));
355 strbuf_release(&ref);
359 void remove_branch_state(void)
361 unlink(git_path("CHERRY_PICK_HEAD"));
362 unlink(git_path("REVERT_HEAD"));
363 unlink(git_path("MERGE_HEAD"));
364 unlink(git_path("MERGE_RR"));
365 unlink(git_path("MERGE_MSG"));
366 unlink(git_path("MERGE_MODE"));
367 unlink(git_path("SQUASH_MSG"));