Merge branch 'ta/config-set-1'
[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 struct branch_desc_cb {
144         const char *config_name;
145         const char *value;
146 };
147
148 static int read_branch_desc_cb(const char *var, const char *value, void *cb)
149 {
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);
155 }
156
157 int read_branch_desc(struct strbuf *buf, const char *branch_name)
158 {
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;
169 }
170
171 int validate_new_branchname(const char *name, struct strbuf *ref,
172                             int force, int attr_only)
173 {
174         if (strbuf_check_branch_ref(ref, name))
175                 die(_("'%s' is not a valid branch name."), name);
176
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/"));
181
182         if (!attr_only) {
183                 const char *head;
184                 unsigned char sha1[20];
185
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."));
189         }
190         return 1;
191 }
192
193 static int check_tracking_branch(struct remote *remote, void *cb_data)
194 {
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);
200 }
201
202 static int validate_remote_tracking_branch(char *ref)
203 {
204         return !for_each_remote(check_tracking_branch, ref);
205 }
206
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.");
220
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)
225 {
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;
234
235         if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
236                 explicit_tracking = 1;
237
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;
245         }
246
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);
254                         }
255                         die(_(upstream_missing), start_name);
256                 }
257                 die(_("Not a valid object name: '%s'."), start_name);
258         }
259
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;
274                 }
275                 break;
276         default:
277                 die(_("Ambiguous object name: '%s'."), start_name);
278                 break;
279         }
280
281         if ((commit = lookup_commit_reference(sha1)) == NULL)
282                 die(_("Not a valid branch point: '%s'."), start_name);
283         hashcpy(sha1, commit->object.sha1);
284
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"));
289         }
290
291         if (reflog)
292                 log_all_ref_updates = 1;
293
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);
300
301         if (real_ref && track)
302                 setup_tracking(ref.buf + 11, real_ref, track, quiet);
303
304         if (!dont_change_ref)
305                 if (write_ref_sha1(lock, sha1, msg) < 0)
306                         die_errno(_("Failed to write ref"));
307
308         strbuf_release(&ref);
309         free(real_ref);
310 }
311
312 void remove_branch_state(void)
313 {
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"));
321 }