Merge branch 'sn/null-pointer-arith-in-mark-tree-uninteresting'
[git] / branch.c
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"
7 #include "worktree.h"
8
9 struct tracking {
10         struct refspec spec;
11         char *src;
12         const char *remote;
13         int matches;
14 };
15
16 static 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
37 static int should_setup_rebase(const char *origin)
38 {
39         switch (autorebase) {
40         case AUTOREBASE_NEVER:
41                 return 0;
42         case AUTOREBASE_LOCAL:
43                 return origin == NULL;
44         case AUTOREBASE_REMOTE:
45                 return origin != NULL;
46         case AUTOREBASE_ALWAYS:
47                 return 1;
48         }
49         return 0;
50 }
51
52 void install_branch_config(int flag, const char *local, const char *origin, const char *remote)
53 {
54         const char *shortname = NULL;
55         struct strbuf key = STRBUF_INIT;
56         int rebasing = should_setup_rebase(origin);
57
58         if (skip_prefix(remote, "refs/heads/", &shortname)
59             && !strcmp(local, shortname)
60             && !origin) {
61                 warning(_("Not setting branch %s as its own upstream."),
62                         local);
63                 return;
64         }
65
66         strbuf_addf(&key, "branch.%s.remote", local);
67         git_config_set(key.buf, origin ? origin : ".");
68
69         strbuf_reset(&key);
70         strbuf_addf(&key, "branch.%s.merge", local);
71         git_config_set(key.buf, remote);
72
73         if (rebasing) {
74                 strbuf_reset(&key);
75                 strbuf_addf(&key, "branch.%s.rebase", local);
76                 git_config_set(key.buf, "true");
77         }
78         strbuf_release(&key);
79
80         if (flag & BRANCH_CONFIG_VERBOSE) {
81                 if (shortname) {
82                         if (origin)
83                                 printf_ln(rebasing ?
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);
87                         else
88                                 printf_ln(rebasing ?
89                                           _("Branch %s set up to track local branch %s by rebasing.") :
90                                           _("Branch %s set up to track local branch %s."),
91                                           local, shortname);
92                 } else {
93                         if (origin)
94                                 printf_ln(rebasing ?
95                                           _("Branch %s set up to track remote ref %s by rebasing.") :
96                                           _("Branch %s set up to track remote ref %s."),
97                                           local, remote);
98                         else
99                                 printf_ln(rebasing ?
100                                           _("Branch %s set up to track local ref %s by rebasing.") :
101                                           _("Branch %s set up to track local ref %s."),
102                                           local, remote);
103                 }
104         }
105 }
106
107 /*
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
110  * config.
111  */
112 static int setup_tracking(const char *new_ref, const char *orig_ref,
113                           enum branch_track track, int quiet)
114 {
115         struct tracking tracking;
116         int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
117
118         memset(&tracking, 0, sizeof(tracking));
119         tracking.spec.dst = (char *)orig_ref;
120         if (for_each_remote(find_tracked_branch, &tracking))
121                 return 1;
122
123         if (!tracking.matches)
124                 switch (track) {
125                 case BRANCH_TRACK_ALWAYS:
126                 case BRANCH_TRACK_EXPLICIT:
127                 case BRANCH_TRACK_OVERRIDE:
128                         break;
129                 default:
130                         return 1;
131                 }
132
133         if (tracking.matches > 1)
134                 return error(_("Not tracking: ambiguous information for ref %s"),
135                                 orig_ref);
136
137         install_branch_config(config_flags, new_ref, tracking.remote,
138                               tracking.src ? tracking.src : orig_ref);
139
140         free(tracking.src);
141         return 0;
142 }
143
144 int read_branch_desc(struct strbuf *buf, const char *branch_name)
145 {
146         char *v = NULL;
147         struct strbuf name = STRBUF_INIT;
148         strbuf_addf(&name, "branch.%s.description", branch_name);
149         if (git_config_get_string(name.buf, &v)) {
150                 strbuf_release(&name);
151                 return -1;
152         }
153         strbuf_addstr(buf, v);
154         free(v);
155         strbuf_release(&name);
156         return 0;
157 }
158
159 int validate_new_branchname(const char *name, struct strbuf *ref,
160                             int force, int attr_only)
161 {
162         if (strbuf_check_branch_ref(ref, name))
163                 die(_("'%s' is not a valid branch name."), name);
164
165         if (!ref_exists(ref->buf))
166                 return 0;
167         else if (!force && !attr_only)
168                 die(_("A branch named '%s' already exists."), ref->buf + strlen("refs/heads/"));
169
170         if (!attr_only) {
171                 const char *head;
172                 unsigned char sha1[20];
173
174                 head = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
175                 if (!is_bare_repository() && head && !strcmp(head, ref->buf))
176                         die(_("Cannot force update the current branch."));
177         }
178         return 1;
179 }
180
181 static int check_tracking_branch(struct remote *remote, void *cb_data)
182 {
183         char *tracking_branch = cb_data;
184         struct refspec query;
185         memset(&query, 0, sizeof(struct refspec));
186         query.dst = tracking_branch;
187         return !remote_find_tracking(remote, &query);
188 }
189
190 static int validate_remote_tracking_branch(char *ref)
191 {
192         return !for_each_remote(check_tracking_branch, ref);
193 }
194
195 static const char upstream_not_branch[] =
196 N_("Cannot setup tracking information; starting point '%s' is not a branch.");
197 static const char upstream_missing[] =
198 N_("the requested upstream branch '%s' does not exist");
199 static const char upstream_advice[] =
200 N_("\n"
201 "If you are planning on basing your work on an upstream\n"
202 "branch that already exists at the remote, you may need to\n"
203 "run \"git fetch\" to retrieve it.\n"
204 "\n"
205 "If you are planning to push out a new local branch that\n"
206 "will track its remote counterpart, you may want to use\n"
207 "\"git push -u\" to set the upstream config as you push.");
208
209 void create_branch(const char *head,
210                    const char *name, const char *start_name,
211                    int force, int reflog, int clobber_head,
212                    int quiet, enum branch_track track)
213 {
214         struct commit *commit;
215         unsigned char sha1[20];
216         char *real_ref, msg[PATH_MAX + 20];
217         struct strbuf ref = STRBUF_INIT;
218         int forcing = 0;
219         int dont_change_ref = 0;
220         int explicit_tracking = 0;
221
222         if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
223                 explicit_tracking = 1;
224
225         if (validate_new_branchname(name, &ref, force,
226                                     track == BRANCH_TRACK_OVERRIDE ||
227                                     clobber_head)) {
228                 if (!force)
229                         dont_change_ref = 1;
230                 else
231                         forcing = 1;
232         }
233
234         real_ref = NULL;
235         if (get_sha1(start_name, sha1)) {
236                 if (explicit_tracking) {
237                         if (advice_set_upstream_failure) {
238                                 error(_(upstream_missing), start_name);
239                                 advise(_(upstream_advice));
240                                 exit(1);
241                         }
242                         die(_(upstream_missing), start_name);
243                 }
244                 die(_("Not a valid object name: '%s'."), start_name);
245         }
246
247         switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) {
248         case 0:
249                 /* Not branching from any existing branch */
250                 if (explicit_tracking)
251                         die(_(upstream_not_branch), start_name);
252                 break;
253         case 1:
254                 /* Unique completion -- good, only if it is a real branch */
255                 if (!starts_with(real_ref, "refs/heads/") &&
256                     validate_remote_tracking_branch(real_ref)) {
257                         if (explicit_tracking)
258                                 die(_(upstream_not_branch), start_name);
259                         else
260                                 real_ref = NULL;
261                 }
262                 break;
263         default:
264                 die(_("Ambiguous object name: '%s'."), start_name);
265                 break;
266         }
267
268         if ((commit = lookup_commit_reference(sha1)) == NULL)
269                 die(_("Not a valid branch point: '%s'."), start_name);
270         hashcpy(sha1, commit->object.oid.hash);
271
272         if (forcing)
273                 snprintf(msg, sizeof msg, "branch: Reset to %s",
274                          start_name);
275         else if (!dont_change_ref)
276                 snprintf(msg, sizeof msg, "branch: Created from %s",
277                          start_name);
278
279         if (reflog)
280                 log_all_ref_updates = 1;
281
282         if (!dont_change_ref) {
283                 struct ref_transaction *transaction;
284                 struct strbuf err = STRBUF_INIT;
285
286                 transaction = ref_transaction_begin(&err);
287                 if (!transaction ||
288                     ref_transaction_update(transaction, ref.buf,
289                                            sha1, forcing ? NULL : null_sha1,
290                                            0, msg, &err) ||
291                     ref_transaction_commit(transaction, &err))
292                         die("%s", err.buf);
293                 ref_transaction_free(transaction);
294                 strbuf_release(&err);
295         }
296
297         if (real_ref && track)
298                 setup_tracking(ref.buf + 11, real_ref, track, quiet);
299
300         strbuf_release(&ref);
301         free(real_ref);
302 }
303
304 void remove_branch_state(void)
305 {
306         unlink(git_path_cherry_pick_head());
307         unlink(git_path_revert_head());
308         unlink(git_path_merge_head());
309         unlink(git_path_merge_rr());
310         unlink(git_path_merge_msg());
311         unlink(git_path_merge_mode());
312         unlink(git_path_squash_msg());
313 }
314
315 void die_if_checked_out(const char *branch)
316 {
317         char *existing;
318
319         existing = find_shared_symref("HEAD", branch);
320         if (existing) {
321                 skip_prefix(branch, "refs/heads/", &branch);
322                 die(_("'%s' is already checked out at '%s'"), branch, existing);
323         }
324 }