]> git.ipfire.org Git - thirdparty/git.git/blame - branch.c
checkout: teach check_linked_checkout() about symbolic link HEAD
[thirdparty/git.git] / branch.c
CommitLineData
303d1d0b 1#include "git-compat-util.h"
e496c003
DB
2#include "cache.h"
3#include "branch.h"
4#include "refs.h"
5#include "remote.h"
6#include "commit.h"
7
8struct tracking {
9 struct refspec spec;
10 char *src;
11 const char *remote;
12 int matches;
13};
14
15static 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
a9f2c136 36static int should_setup_rebase(const char *origin)
c998ae9b
DS
37{
38 switch (autorebase) {
39 case AUTOREBASE_NEVER:
40 return 0;
41 case AUTOREBASE_LOCAL:
a9f2c136 42 return origin == NULL;
c998ae9b 43 case AUTOREBASE_REMOTE:
a9f2c136 44 return origin != NULL;
c998ae9b
DS
45 case AUTOREBASE_ALWAYS:
46 return 1;
47 }
48 return 0;
49}
50
a9f2c136
JH
51void install_branch_config(int flag, const char *local, const char *origin, const char *remote)
52{
cf4fff57 53 const char *shortname = NULL;
a9f2c136
JH
54 struct strbuf key = STRBUF_INIT;
55 int rebasing = should_setup_rebase(origin);
56
cf4fff57 57 if (skip_prefix(remote, "refs/heads/", &shortname)
85e2233f
MM
58 && !strcmp(local, shortname)
59 && !origin) {
bc554df8 60 warning(_("Not setting branch %s as its own upstream."),
85e2233f
MM
61 local);
62 return;
63 }
64
a9f2c136
JH
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 }
d53a3503 77 strbuf_release(&key);
a9f2c136 78
72f60083 79 if (flag & BRANCH_CONFIG_VERBOSE) {
1d9aaed2 80 if (shortname) {
9fe0cf3a
A
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 }
72f60083 103 }
a9f2c136
JH
104}
105
e496c003
DB
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 */
9ed36cfa 111static int setup_tracking(const char *new_ref, const char *orig_ref,
f9a482e6 112 enum branch_track track, int quiet)
e496c003 113{
e496c003 114 struct tracking tracking;
f9a482e6 115 int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
e496c003 116
e496c003
DB
117 memset(&tracking, 0, sizeof(tracking));
118 tracking.spec.dst = (char *)orig_ref;
9ed36cfa 119 if (for_each_remote(find_tracked_branch, &tracking))
e496c003
DB
120 return 1;
121
9ed36cfa
JS
122 if (!tracking.matches)
123 switch (track) {
124 case BRANCH_TRACK_ALWAYS:
125 case BRANCH_TRACK_EXPLICIT:
4fc50066 126 case BRANCH_TRACK_OVERRIDE:
9ed36cfa
JS
127 break;
128 default:
129 return 1;
130 }
131
e496c003 132 if (tracking.matches > 1)
bc554df8 133 return error(_("Not tracking: ambiguous information for ref %s"),
e496c003
DB
134 orig_ref);
135
f9a482e6 136 install_branch_config(config_flags, new_ref, tracking.remote,
a9f2c136 137 tracking.src ? tracking.src : orig_ref);
e496c003 138
a9f2c136 139 free(tracking.src);
e496c003
DB
140 return 0;
141}
142
6f9a3321
JH
143int read_branch_desc(struct strbuf *buf, const char *branch_name)
144{
540b0f49 145 char *v = NULL;
6f9a3321
JH
146 struct strbuf name = STRBUF_INIT;
147 strbuf_addf(&name, "branch.%s.description", branch_name);
540b0f49
TA
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);
6f9a3321
JH
154 strbuf_release(&name);
155 return 0;
156}
157
fa799376
JH
158int validate_new_branchname(const char *name, struct strbuf *ref,
159 int force, int attr_only)
55c4a673 160{
55c4a673 161 if (strbuf_check_branch_ref(ref, name))
bc554df8 162 die(_("'%s' is not a valid branch name."), name);
55c4a673
CI
163
164 if (!ref_exists(ref->buf))
165 return 0;
fa799376 166 else if (!force && !attr_only)
bc554df8 167 die(_("A branch named '%s' already exists."), ref->buf + strlen("refs/heads/"));
55c4a673 168
fa799376
JH
169 if (!attr_only) {
170 const char *head;
171 unsigned char sha1[20];
55c4a673 172
7695d118 173 head = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
fa799376 174 if (!is_bare_repository() && head && !strcmp(head, ref->buf))
bc554df8 175 die(_("Cannot force update the current branch."));
fa799376 176 }
55c4a673
CI
177 return 1;
178}
179
41c21f22
JH
180static 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;
1d7358c5 186 return !remote_find_tracking(remote, &query);
41c21f22
JH
187}
188
189static int validate_remote_tracking_branch(char *ref)
190{
191 return !for_each_remote(check_tracking_branch, ref);
192}
193
e2b6aa5f 194static const char upstream_not_branch[] =
1a15d00b 195N_("Cannot setup tracking information; starting point '%s' is not a branch.");
a5e91c72 196static const char upstream_missing[] =
caa2036b
JK
197N_("the requested upstream branch '%s' does not exist");
198static const char upstream_advice[] =
199N_("\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.");
e2b6aa5f 207
e496c003
DB
208void create_branch(const char *head,
209 const char *name, const char *start_name,
39bd6f72 210 int force, int reflog, int clobber_head,
f9a482e6 211 int quiet, enum branch_track track)
e496c003 212{
e496c003
DB
213 struct commit *commit;
214 unsigned char sha1[20];
8415d5c7
JH
215 char *real_ref, msg[PATH_MAX + 20];
216 struct strbuf ref = STRBUF_INIT;
e496c003 217 int forcing = 0;
4fc50066
IL
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;
e496c003 223
fa799376 224 if (validate_new_branchname(name, &ref, force,
39bd6f72
JN
225 track == BRANCH_TRACK_OVERRIDE ||
226 clobber_head)) {
55c4a673 227 if (!force)
4fc50066 228 dont_change_ref = 1;
55c4a673
CI
229 else
230 forcing = 1;
e496c003
DB
231 }
232
233 real_ref = NULL;
a5e91c72 234 if (get_sha1(start_name, sha1)) {
caa2036b
JK
235 if (explicit_tracking) {
236 if (advice_set_upstream_failure) {
237 error(_(upstream_missing), start_name);
238 advise(_(upstream_advice));
239 exit(1);
240 }
1a15d00b 241 die(_(upstream_missing), start_name);
caa2036b 242 }
bc554df8 243 die(_("Not a valid object name: '%s'."), start_name);
a5e91c72 244 }
e496c003
DB
245
246 switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) {
247 case 0:
248 /* Not branching from any existing branch */
4fc50066 249 if (explicit_tracking)
1a15d00b 250 die(_(upstream_not_branch), start_name);
e496c003
DB
251 break;
252 case 1:
21b5b1e8 253 /* Unique completion -- good, only if it is a real branch */
59556548 254 if (!starts_with(real_ref, "refs/heads/") &&
41c21f22 255 validate_remote_tracking_branch(real_ref)) {
21b5b1e8 256 if (explicit_tracking)
1a15d00b 257 die(_(upstream_not_branch), start_name);
21b5b1e8
JH
258 else
259 real_ref = NULL;
260 }
e496c003
DB
261 break;
262 default:
bc554df8 263 die(_("Ambiguous object name: '%s'."), start_name);
e496c003
DB
264 break;
265 }
266
267 if ((commit = lookup_commit_reference(sha1)) == NULL)
bc554df8 268 die(_("Not a valid branch point: '%s'."), start_name);
e496c003
DB
269 hashcpy(sha1, commit->object.sha1);
270
e496c003 271 if (forcing)
da288e25 272 snprintf(msg, sizeof msg, "branch: Reset to %s",
e496c003 273 start_name);
4fc50066 274 else if (!dont_change_ref)
e496c003
DB
275 snprintf(msg, sizeof msg, "branch: Created from %s",
276 start_name);
277
d43f990f
RS
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, sha1,
db7516ab
RS
288 null_sha1, 0, !forcing, msg, &err) ||
289 ref_transaction_commit(transaction, &err))
d43f990f
RS
290 die("%s", err.buf);
291 ref_transaction_free(transaction);
292 strbuf_release(&err);
293 }
294
e496c003 295 if (real_ref && track)
82a0672f 296 setup_tracking(ref.buf + 11, real_ref, track, quiet);
e496c003 297
8415d5c7 298 strbuf_release(&ref);
9ed36cfa 299 free(real_ref);
e496c003 300}
c369e7b8
DB
301
302void remove_branch_state(void)
303{
d7e5c0cb 304 unlink(git_path("CHERRY_PICK_HEAD"));
82433cdf 305 unlink(git_path("REVERT_HEAD"));
c369e7b8 306 unlink(git_path("MERGE_HEAD"));
0af0ac7e 307 unlink(git_path("MERGE_RR"));
c369e7b8 308 unlink(git_path("MERGE_MSG"));
cf10f9fd 309 unlink(git_path("MERGE_MODE"));
c369e7b8
DB
310 unlink(git_path("SQUASH_MSG"));
311}