environment: store worktree in the_repository
[git] / branch.c
1 #include "git-compat-util.h"
2 #include "cache.h"
3 #include "config.h"
4 #include "branch.h"
5 #include "refs.h"
6 #include "remote.h"
7 #include "commit.h"
8 #include "worktree.h"
9
10 struct tracking {
11         struct refspec spec;
12         char *src;
13         const char *remote;
14         int matches;
15 };
16
17 static int find_tracked_branch(struct remote *remote, void *priv)
18 {
19         struct tracking *tracking = priv;
20
21         if (!remote_find_tracking(remote, &tracking->spec)) {
22                 if (++tracking->matches == 1) {
23                         tracking->src = tracking->spec.src;
24                         tracking->remote = remote->name;
25                 } else {
26                         free(tracking->spec.src);
27                         if (tracking->src) {
28                                 free(tracking->src);
29                                 tracking->src = NULL;
30                         }
31                 }
32                 tracking->spec.src = NULL;
33         }
34
35         return 0;
36 }
37
38 static int should_setup_rebase(const char *origin)
39 {
40         switch (autorebase) {
41         case AUTOREBASE_NEVER:
42                 return 0;
43         case AUTOREBASE_LOCAL:
44                 return origin == NULL;
45         case AUTOREBASE_REMOTE:
46                 return origin != NULL;
47         case AUTOREBASE_ALWAYS:
48                 return 1;
49         }
50         return 0;
51 }
52
53 static const char tracking_advice[] =
54 N_("\n"
55 "After fixing the error cause you may try to fix up\n"
56 "the remote tracking information by invoking\n"
57 "\"git branch --set-upstream-to=%s%s%s\".");
58
59 int install_branch_config(int flag, const char *local, const char *origin, const char *remote)
60 {
61         const char *shortname = NULL;
62         struct strbuf key = STRBUF_INIT;
63         int rebasing = should_setup_rebase(origin);
64
65         if (skip_prefix(remote, "refs/heads/", &shortname)
66             && !strcmp(local, shortname)
67             && !origin) {
68                 warning(_("Not setting branch %s as its own upstream."),
69                         local);
70                 return 0;
71         }
72
73         strbuf_addf(&key, "branch.%s.remote", local);
74         if (git_config_set_gently(key.buf, origin ? origin : ".") < 0)
75                 goto out_err;
76
77         strbuf_reset(&key);
78         strbuf_addf(&key, "branch.%s.merge", local);
79         if (git_config_set_gently(key.buf, remote) < 0)
80                 goto out_err;
81
82         if (rebasing) {
83                 strbuf_reset(&key);
84                 strbuf_addf(&key, "branch.%s.rebase", local);
85                 if (git_config_set_gently(key.buf, "true") < 0)
86                         goto out_err;
87         }
88         strbuf_release(&key);
89
90         if (flag & BRANCH_CONFIG_VERBOSE) {
91                 if (shortname) {
92                         if (origin)
93                                 printf_ln(rebasing ?
94                                           _("Branch %s set up to track remote branch %s from %s by rebasing.") :
95                                           _("Branch %s set up to track remote branch %s from %s."),
96                                           local, shortname, origin);
97                         else
98                                 printf_ln(rebasing ?
99                                           _("Branch %s set up to track local branch %s by rebasing.") :
100                                           _("Branch %s set up to track local branch %s."),
101                                           local, shortname);
102                 } else {
103                         if (origin)
104                                 printf_ln(rebasing ?
105                                           _("Branch %s set up to track remote ref %s by rebasing.") :
106                                           _("Branch %s set up to track remote ref %s."),
107                                           local, remote);
108                         else
109                                 printf_ln(rebasing ?
110                                           _("Branch %s set up to track local ref %s by rebasing.") :
111                                           _("Branch %s set up to track local ref %s."),
112                                           local, remote);
113                 }
114         }
115
116         return 0;
117
118 out_err:
119         strbuf_release(&key);
120         error(_("Unable to write upstream branch configuration"));
121
122         advise(_(tracking_advice),
123                origin ? origin : "",
124                origin ? "/" : "",
125                shortname ? shortname : remote);
126
127         return -1;
128 }
129
130 /*
131  * This is called when new_ref is branched off of orig_ref, and tries
132  * to infer the settings for branch.<new_ref>.{remote,merge} from the
133  * config.
134  */
135 static void setup_tracking(const char *new_ref, const char *orig_ref,
136                            enum branch_track track, int quiet)
137 {
138         struct tracking tracking;
139         int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
140
141         memset(&tracking, 0, sizeof(tracking));
142         tracking.spec.dst = (char *)orig_ref;
143         if (for_each_remote(find_tracked_branch, &tracking))
144                 return;
145
146         if (!tracking.matches)
147                 switch (track) {
148                 case BRANCH_TRACK_ALWAYS:
149                 case BRANCH_TRACK_EXPLICIT:
150                 case BRANCH_TRACK_OVERRIDE:
151                         break;
152                 default:
153                         return;
154                 }
155
156         if (tracking.matches > 1)
157                 die(_("Not tracking: ambiguous information for ref %s"),
158                     orig_ref);
159
160         if (install_branch_config(config_flags, new_ref, tracking.remote,
161                               tracking.src ? tracking.src : orig_ref) < 0)
162                 exit(-1);
163
164         free(tracking.src);
165 }
166
167 int read_branch_desc(struct strbuf *buf, const char *branch_name)
168 {
169         char *v = NULL;
170         struct strbuf name = STRBUF_INIT;
171         strbuf_addf(&name, "branch.%s.description", branch_name);
172         if (git_config_get_string(name.buf, &v)) {
173                 strbuf_release(&name);
174                 return -1;
175         }
176         strbuf_addstr(buf, v);
177         free(v);
178         strbuf_release(&name);
179         return 0;
180 }
181
182 int validate_new_branchname(const char *name, struct strbuf *ref,
183                             int force, int attr_only)
184 {
185         if (strbuf_check_branch_ref(ref, name))
186                 die(_("'%s' is not a valid branch name."), name);
187
188         if (!ref_exists(ref->buf))
189                 return 0;
190         else if (!force && !attr_only)
191                 die(_("A branch named '%s' already exists."), ref->buf + strlen("refs/heads/"));
192
193         if (!attr_only) {
194                 const char *head;
195                 struct object_id oid;
196
197                 head = resolve_ref_unsafe("HEAD", 0, oid.hash, NULL);
198                 if (!is_bare_repository() && head && !strcmp(head, ref->buf))
199                         die(_("Cannot force update the current branch."));
200         }
201         return 1;
202 }
203
204 static int check_tracking_branch(struct remote *remote, void *cb_data)
205 {
206         char *tracking_branch = cb_data;
207         struct refspec query;
208         memset(&query, 0, sizeof(struct refspec));
209         query.dst = tracking_branch;
210         return !remote_find_tracking(remote, &query);
211 }
212
213 static int validate_remote_tracking_branch(char *ref)
214 {
215         return !for_each_remote(check_tracking_branch, ref);
216 }
217
218 static const char upstream_not_branch[] =
219 N_("Cannot setup tracking information; starting point '%s' is not a branch.");
220 static const char upstream_missing[] =
221 N_("the requested upstream branch '%s' does not exist");
222 static const char upstream_advice[] =
223 N_("\n"
224 "If you are planning on basing your work on an upstream\n"
225 "branch that already exists at the remote, you may need to\n"
226 "run \"git fetch\" to retrieve it.\n"
227 "\n"
228 "If you are planning to push out a new local branch that\n"
229 "will track its remote counterpart, you may want to use\n"
230 "\"git push -u\" to set the upstream config as you push.");
231
232 void create_branch(const char *name, const char *start_name,
233                    int force, int reflog, int clobber_head,
234                    int quiet, enum branch_track track)
235 {
236         struct commit *commit;
237         struct object_id oid;
238         char *real_ref;
239         struct strbuf ref = STRBUF_INIT;
240         int forcing = 0;
241         int dont_change_ref = 0;
242         int explicit_tracking = 0;
243
244         if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
245                 explicit_tracking = 1;
246
247         if (validate_new_branchname(name, &ref, force,
248                                     track == BRANCH_TRACK_OVERRIDE ||
249                                     clobber_head)) {
250                 if (!force)
251                         dont_change_ref = 1;
252                 else
253                         forcing = 1;
254         }
255
256         real_ref = NULL;
257         if (get_oid(start_name, &oid)) {
258                 if (explicit_tracking) {
259                         if (advice_set_upstream_failure) {
260                                 error(_(upstream_missing), start_name);
261                                 advise(_(upstream_advice));
262                                 exit(1);
263                         }
264                         die(_(upstream_missing), start_name);
265                 }
266                 die(_("Not a valid object name: '%s'."), start_name);
267         }
268
269         switch (dwim_ref(start_name, strlen(start_name), oid.hash, &real_ref)) {
270         case 0:
271                 /* Not branching from any existing branch */
272                 if (explicit_tracking)
273                         die(_(upstream_not_branch), start_name);
274                 break;
275         case 1:
276                 /* Unique completion -- good, only if it is a real branch */
277                 if (!starts_with(real_ref, "refs/heads/") &&
278                     validate_remote_tracking_branch(real_ref)) {
279                         if (explicit_tracking)
280                                 die(_(upstream_not_branch), start_name);
281                         else
282                                 real_ref = NULL;
283                 }
284                 break;
285         default:
286                 die(_("Ambiguous object name: '%s'."), start_name);
287                 break;
288         }
289
290         if ((commit = lookup_commit_reference(&oid)) == NULL)
291                 die(_("Not a valid branch point: '%s'."), start_name);
292         oidcpy(&oid, &commit->object.oid);
293
294         if (reflog)
295                 log_all_ref_updates = LOG_REFS_NORMAL;
296
297         if (!dont_change_ref) {
298                 struct ref_transaction *transaction;
299                 struct strbuf err = STRBUF_INIT;
300                 char *msg;
301
302                 if (forcing)
303                         msg = xstrfmt("branch: Reset to %s", start_name);
304                 else
305                         msg = xstrfmt("branch: Created from %s", start_name);
306
307                 transaction = ref_transaction_begin(&err);
308                 if (!transaction ||
309                     ref_transaction_update(transaction, ref.buf,
310                                            oid.hash, forcing ? NULL : null_sha1,
311                                            0, msg, &err) ||
312                     ref_transaction_commit(transaction, &err))
313                         die("%s", err.buf);
314                 ref_transaction_free(transaction);
315                 strbuf_release(&err);
316                 free(msg);
317         }
318
319         if (real_ref && track)
320                 setup_tracking(ref.buf + 11, real_ref, track, quiet);
321
322         strbuf_release(&ref);
323         free(real_ref);
324 }
325
326 void remove_branch_state(void)
327 {
328         unlink(git_path_cherry_pick_head());
329         unlink(git_path_revert_head());
330         unlink(git_path_merge_head());
331         unlink(git_path_merge_rr());
332         unlink(git_path_merge_msg());
333         unlink(git_path_merge_mode());
334         unlink(git_path_squash_msg());
335 }
336
337 void die_if_checked_out(const char *branch, int ignore_current_worktree)
338 {
339         const struct worktree *wt;
340
341         wt = find_shared_symref("HEAD", branch);
342         if (!wt || (ignore_current_worktree && wt->is_current))
343                 return;
344         skip_prefix(branch, "refs/heads/", &branch);
345         die(_("'%s' is already checked out at '%s'"),
346             branch, wt->path);
347 }
348
349 int replace_each_worktree_head_symref(const char *oldref, const char *newref,
350                                       const char *logmsg)
351 {
352         int ret = 0;
353         struct worktree **worktrees = get_worktrees(0);
354         int i;
355
356         for (i = 0; worktrees[i]; i++) {
357                 struct ref_store *refs;
358
359                 if (worktrees[i]->is_detached)
360                         continue;
361                 if (worktrees[i]->head_ref &&
362                     strcmp(oldref, worktrees[i]->head_ref))
363                         continue;
364
365                 refs = get_worktree_ref_store(worktrees[i]);
366                 if (refs_create_symref(refs, "HEAD", newref, logmsg))
367                         ret = error(_("HEAD of working tree %s is not updated"),
368                                     worktrees[i]->path);
369         }
370
371         free_worktrees(worktrees);
372         return ret;
373 }