archive.c: replace `git_config()` with `git_config_get_bool()` family
[alt-git.git] / branch.c
blob735767dd4a61678417f1aec2d226f8675e171b63
1 #include "git-compat-util.h"
2 #include "cache.h"
3 #include "branch.h"
4 #include "refs.h"
5 #include "remote.h"
6 #include "commit.h"
8 struct tracking {
9 struct refspec spec;
10 char *src;
11 const char *remote;
12 int matches;
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;
23 } else {
24 free(tracking->spec.src);
25 if (tracking->src) {
26 free(tracking->src);
27 tracking->src = NULL;
30 tracking->spec.src = NULL;
33 return 0;
36 static int should_setup_rebase(const char *origin)
38 switch (autorebase) {
39 case AUTOREBASE_NEVER:
40 return 0;
41 case AUTOREBASE_LOCAL:
42 return origin == NULL;
43 case AUTOREBASE_REMOTE:
44 return origin != NULL;
45 case AUTOREBASE_ALWAYS:
46 return 1;
48 return 0;
51 void install_branch_config(int flag, const char *local, const char *origin, const char *remote)
53 const char *shortname = NULL;
54 struct strbuf key = STRBUF_INIT;
55 int rebasing = should_setup_rebase(origin);
57 if (skip_prefix(remote, "refs/heads/", &shortname)
58 && !strcmp(local, shortname)
59 && !origin) {
60 warning(_("Not setting branch %s as its own upstream."),
61 local);
62 return;
65 strbuf_addf(&key, "branch.%s.remote", local);
66 git_config_set(key.buf, origin ? origin : ".");
68 strbuf_reset(&key);
69 strbuf_addf(&key, "branch.%s.merge", local);
70 git_config_set(key.buf, remote);
72 if (rebasing) {
73 strbuf_reset(&key);
74 strbuf_addf(&key, "branch.%s.rebase", local);
75 git_config_set(key.buf, "true");
77 strbuf_release(&key);
79 if (flag & BRANCH_CONFIG_VERBOSE) {
80 if (shortname) {
81 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);
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.
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))
120 return 1;
122 if (!tracking.matches)
123 switch (track) {
124 case BRANCH_TRACK_ALWAYS:
125 case BRANCH_TRACK_EXPLICIT:
126 case BRANCH_TRACK_OVERRIDE:
127 break;
128 default:
129 return 1;
132 if (tracking.matches > 1)
133 return error(_("Not tracking: ambiguous information for ref %s"),
134 orig_ref);
136 install_branch_config(config_flags, new_ref, tracking.remote,
137 tracking.src ? tracking.src : orig_ref);
139 free(tracking.src);
140 return 0;
143 struct branch_desc_cb {
144 const char *config_name;
145 const char *value;
148 static int read_branch_desc_cb(const char *var, const char *value, void *cb)
150 struct branch_desc_cb *desc = cb;
151 if (strcmp(desc->config_name, var))
152 return 0;
153 free((char *)desc->value);
154 return git_config_string(&desc->value, var, value);
157 int read_branch_desc(struct strbuf *buf, const char *branch_name)
159 struct branch_desc_cb cb;
160 struct strbuf name = STRBUF_INIT;
161 strbuf_addf(&name, "branch.%s.description", branch_name);
162 cb.config_name = name.buf;
163 cb.value = NULL;
164 git_config(read_branch_desc_cb, &cb);
165 if (cb.value)
166 strbuf_addstr(buf, cb.value);
167 strbuf_release(&name);
168 return 0;
171 int validate_new_branchname(const char *name, struct strbuf *ref,
172 int force, int attr_only)
174 if (strbuf_check_branch_ref(ref, name))
175 die(_("'%s' is not a valid branch name."), name);
177 if (!ref_exists(ref->buf))
178 return 0;
179 else if (!force && !attr_only)
180 die(_("A branch named '%s' already exists."), ref->buf + strlen("refs/heads/"));
182 if (!attr_only) {
183 const char *head;
184 unsigned char sha1[20];
186 head = resolve_ref_unsafe("HEAD", sha1, 0, NULL);
187 if (!is_bare_repository() && head && !strcmp(head, ref->buf))
188 die(_("Cannot force update the current branch."));
190 return 1;
193 static int check_tracking_branch(struct remote *remote, void *cb_data)
195 char *tracking_branch = cb_data;
196 struct refspec query;
197 memset(&query, 0, sizeof(struct refspec));
198 query.dst = tracking_branch;
199 return !remote_find_tracking(remote, &query);
202 static int validate_remote_tracking_branch(char *ref)
204 return !for_each_remote(check_tracking_branch, ref);
207 static const char upstream_not_branch[] =
208 N_("Cannot setup tracking information; starting point '%s' is not a branch.");
209 static const char upstream_missing[] =
210 N_("the requested upstream branch '%s' does not exist");
211 static const char upstream_advice[] =
212 N_("\n"
213 "If you are planning on basing your work on an upstream\n"
214 "branch that already exists at the remote, you may need to\n"
215 "run \"git fetch\" to retrieve it.\n"
216 "\n"
217 "If you are planning to push out a new local branch that\n"
218 "will track its remote counterpart, you may want to use\n"
219 "\"git push -u\" to set the upstream config as you push.");
221 void create_branch(const char *head,
222 const char *name, const char *start_name,
223 int force, int reflog, int clobber_head,
224 int quiet, enum branch_track track)
226 struct ref_lock *lock = NULL;
227 struct commit *commit;
228 unsigned char sha1[20];
229 char *real_ref, msg[PATH_MAX + 20];
230 struct strbuf ref = STRBUF_INIT;
231 int forcing = 0;
232 int dont_change_ref = 0;
233 int explicit_tracking = 0;
235 if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
236 explicit_tracking = 1;
238 if (validate_new_branchname(name, &ref, force,
239 track == BRANCH_TRACK_OVERRIDE ||
240 clobber_head)) {
241 if (!force)
242 dont_change_ref = 1;
243 else
244 forcing = 1;
247 real_ref = NULL;
248 if (get_sha1(start_name, sha1)) {
249 if (explicit_tracking) {
250 if (advice_set_upstream_failure) {
251 error(_(upstream_missing), start_name);
252 advise(_(upstream_advice));
253 exit(1);
255 die(_(upstream_missing), start_name);
257 die(_("Not a valid object name: '%s'."), start_name);
260 switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) {
261 case 0:
262 /* Not branching from any existing branch */
263 if (explicit_tracking)
264 die(_(upstream_not_branch), start_name);
265 break;
266 case 1:
267 /* Unique completion -- good, only if it is a real branch */
268 if (!starts_with(real_ref, "refs/heads/") &&
269 validate_remote_tracking_branch(real_ref)) {
270 if (explicit_tracking)
271 die(_(upstream_not_branch), start_name);
272 else
273 real_ref = NULL;
275 break;
276 default:
277 die(_("Ambiguous object name: '%s'."), start_name);
278 break;
281 if ((commit = lookup_commit_reference(sha1)) == NULL)
282 die(_("Not a valid branch point: '%s'."), start_name);
283 hashcpy(sha1, commit->object.sha1);
285 if (!dont_change_ref) {
286 lock = lock_any_ref_for_update(ref.buf, NULL, 0, NULL);
287 if (!lock)
288 die_errno(_("Failed to lock ref for update"));
291 if (reflog)
292 log_all_ref_updates = 1;
294 if (forcing)
295 snprintf(msg, sizeof msg, "branch: Reset to %s",
296 start_name);
297 else if (!dont_change_ref)
298 snprintf(msg, sizeof msg, "branch: Created from %s",
299 start_name);
301 if (real_ref && track)
302 setup_tracking(ref.buf + 11, real_ref, track, quiet);
304 if (!dont_change_ref)
305 if (write_ref_sha1(lock, sha1, msg) < 0)
306 die_errno(_("Failed to write ref"));
308 strbuf_release(&ref);
309 free(real_ref);
312 void remove_branch_state(void)
314 unlink(git_path("CHERRY_PICK_HEAD"));
315 unlink(git_path("REVERT_HEAD"));
316 unlink(git_path("MERGE_HEAD"));
317 unlink(git_path("MERGE_RR"));
318 unlink(git_path("MERGE_MSG"));
319 unlink(git_path("MERGE_MODE"));
320 unlink(git_path("SQUASH_MSG"));