utf8: add function to align a string into given strbuf
[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
8 struct tracking {
9         struct refspec spec;
10         char *src;
11         const char *remote;
12         int matches;
13 };
14
15 static 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
36 static int should_setup_rebase(const char *origin)
37 {
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;
47         }
48         return 0;
49 }
50
51 void install_branch_config(int flag, const char *local, const char *origin, const char *remote)
52 {
53         const char *shortname = NULL;
54         struct strbuf key = STRBUF_INIT;
55         int rebasing = should_setup_rebase(origin);
56
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;
63         }
64
65         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         }
77         strbuf_release(&key);
78
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);
102                 }
103         }
104 }
105
106 /*
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  */
111 static int setup_tracking(const char *new_ref, const char *orig_ref,
112                           enum branch_track track, int quiet)
113 {
114         struct tracking tracking;
115         int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
116
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;
121
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;
130                 }
131
132         if (tracking.matches > 1)
133                 return error(_("Not tracking: ambiguous information for ref %s"),
134                                 orig_ref);
135
136         install_branch_config(config_flags, new_ref, tracking.remote,
137                               tracking.src ? tracking.src : orig_ref);
138
139         free(tracking.src);
140         return 0;
141 }
142
143 int read_branch_desc(struct strbuf *buf, const char *branch_name)
144 {
145         char *v = NULL;
146         struct strbuf name = STRBUF_INIT;
147         strbuf_addf(&name, "branch.%s.description", branch_name);
148         if (git_config_get_string(name.buf, &v)) {
149                 strbuf_release(&name);
150                 return -1;
151         }
152         strbuf_addstr(buf, v);
153         free(v);
154         strbuf_release(&name);
155         return 0;
156 }
157
158 int validate_new_branchname(const char *name, struct strbuf *ref,
159                             int force, int attr_only)
160 {
161         if (strbuf_check_branch_ref(ref, name))
162                 die(_("'%s' is not a valid branch name."), name);
163
164         if (!ref_exists(ref->buf))
165                 return 0;
166         else if (!force && !attr_only)
167                 die(_("A branch named '%s' already exists."), ref->buf + strlen("refs/heads/"));
168
169         if (!attr_only) {
170                 const char *head;
171                 unsigned char sha1[20];
172
173                 head = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
174                 if (!is_bare_repository() && head && !strcmp(head, ref->buf))
175                         die(_("Cannot force update the current branch."));
176         }
177         return 1;
178 }
179
180 static 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;
186         return !remote_find_tracking(remote, &query);
187 }
188
189 static int validate_remote_tracking_branch(char *ref)
190 {
191         return !for_each_remote(check_tracking_branch, ref);
192 }
193
194 static const char upstream_not_branch[] =
195 N_("Cannot setup tracking information; starting point '%s' is not a branch.");
196 static const char upstream_missing[] =
197 N_("the requested upstream branch '%s' does not exist");
198 static const char upstream_advice[] =
199 N_("\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.");
207
208 void create_branch(const char *head,
209                    const char *name, const char *start_name,
210                    int force, int reflog, int clobber_head,
211                    int quiet, enum branch_track track)
212 {
213         struct commit *commit;
214         unsigned char sha1[20];
215         char *real_ref, msg[PATH_MAX + 20];
216         struct strbuf ref = STRBUF_INIT;
217         int forcing = 0;
218         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;
223
224         if (validate_new_branchname(name, &ref, force,
225                                     track == BRANCH_TRACK_OVERRIDE ||
226                                     clobber_head)) {
227                 if (!force)
228                         dont_change_ref = 1;
229                 else
230                         forcing = 1;
231         }
232
233         real_ref = NULL;
234         if (get_sha1(start_name, sha1)) {
235                 if (explicit_tracking) {
236                         if (advice_set_upstream_failure) {
237                                 error(_(upstream_missing), start_name);
238                                 advise(_(upstream_advice));
239                                 exit(1);
240                         }
241                         die(_(upstream_missing), start_name);
242                 }
243                 die(_("Not a valid object name: '%s'."), start_name);
244         }
245
246         switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) {
247         case 0:
248                 /* Not branching from any existing branch */
249                 if (explicit_tracking)
250                         die(_(upstream_not_branch), start_name);
251                 break;
252         case 1:
253                 /* Unique completion -- good, only if it is a real branch */
254                 if (!starts_with(real_ref, "refs/heads/") &&
255                     validate_remote_tracking_branch(real_ref)) {
256                         if (explicit_tracking)
257                                 die(_(upstream_not_branch), start_name);
258                         else
259                                 real_ref = NULL;
260                 }
261                 break;
262         default:
263                 die(_("Ambiguous object name: '%s'."), start_name);
264                 break;
265         }
266
267         if ((commit = lookup_commit_reference(sha1)) == NULL)
268                 die(_("Not a valid branch point: '%s'."), start_name);
269         hashcpy(sha1, commit->object.sha1);
270
271         if (forcing)
272                 snprintf(msg, sizeof msg, "branch: Reset to %s",
273                          start_name);
274         else if (!dont_change_ref)
275                 snprintf(msg, sizeof msg, "branch: Created from %s",
276                          start_name);
277
278         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,
288                                            sha1, forcing ? NULL : null_sha1,
289                                            0, msg, &err) ||
290                     ref_transaction_commit(transaction, &err))
291                         die("%s", err.buf);
292                 ref_transaction_free(transaction);
293                 strbuf_release(&err);
294         }
295
296         if (real_ref && track)
297                 setup_tracking(ref.buf + 11, real_ref, track, quiet);
298
299         strbuf_release(&ref);
300         free(real_ref);
301 }
302
303 void remove_branch_state(void)
304 {
305         unlink(git_path_cherry_pick_head());
306         unlink(git_path_revert_head());
307         unlink(git_path_merge_head());
308         unlink(git_path_merge_rr());
309         unlink(git_path_merge_msg());
310         unlink(git_path_merge_mode());
311         unlink(git_path_squash_msg());
312 }