1 #include "git-compat-util.h"
16 static int find_tracked_branch(struct remote
*remote
, void *priv
)
18 struct tracking
*tracking
= priv
;
20 if (!remote_find_tracking(remote
, &tracking
->spec
)) {
21 if (++tracking
->matches
== 1) {
22 tracking
->src
= tracking
->spec
.src
;
23 tracking
->remote
= remote
->name
;
25 free(tracking
->spec
.src
);
31 tracking
->spec
.src
= NULL
;
37 static int should_setup_rebase(const char *origin
)
40 case AUTOREBASE_NEVER
:
42 case AUTOREBASE_LOCAL
:
43 return origin
== NULL
;
44 case AUTOREBASE_REMOTE
:
45 return origin
!= NULL
;
46 case AUTOREBASE_ALWAYS
:
52 void install_branch_config(int flag
, const char *local
, const char *origin
, const char *remote
)
54 const char *shortname
= NULL
;
55 struct strbuf key
= STRBUF_INIT
;
56 int rebasing
= should_setup_rebase(origin
);
58 if (skip_prefix(remote
, "refs/heads/", &shortname
)
59 && !strcmp(local
, shortname
)
61 warning(_("Not setting branch %s as its own upstream."),
66 strbuf_addf(&key
, "branch.%s.remote", local
);
67 git_config_set(key
.buf
, origin
? origin
: ".");
70 strbuf_addf(&key
, "branch.%s.merge", local
);
71 git_config_set(key
.buf
, remote
);
75 strbuf_addf(&key
, "branch.%s.rebase", local
);
76 git_config_set(key
.buf
, "true");
80 if (flag
& BRANCH_CONFIG_VERBOSE
) {
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
);
89 _("Branch %s set up to track local branch %s by rebasing.") :
90 _("Branch %s set up to track local branch %s."),
95 _("Branch %s set up to track remote ref %s by rebasing.") :
96 _("Branch %s set up to track remote ref %s."),
100 _("Branch %s set up to track local ref %s by rebasing.") :
101 _("Branch %s set up to track local ref %s."),
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
112 static int setup_tracking(const char *new_ref
, const char *orig_ref
,
113 enum branch_track track
, int quiet
)
115 struct tracking tracking
;
116 int config_flags
= quiet
? 0 : BRANCH_CONFIG_VERBOSE
;
118 memset(&tracking
, 0, sizeof(tracking
));
119 tracking
.spec
.dst
= (char *)orig_ref
;
120 if (for_each_remote(find_tracked_branch
, &tracking
))
123 if (!tracking
.matches
)
125 case BRANCH_TRACK_ALWAYS
:
126 case BRANCH_TRACK_EXPLICIT
:
127 case BRANCH_TRACK_OVERRIDE
:
133 if (tracking
.matches
> 1)
134 return error(_("Not tracking: ambiguous information for ref %s"),
137 install_branch_config(config_flags
, new_ref
, tracking
.remote
,
138 tracking
.src
? tracking
.src
: orig_ref
);
144 int read_branch_desc(struct strbuf
*buf
, const char *branch_name
)
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
);
153 strbuf_addstr(buf
, v
);
155 strbuf_release(&name
);
159 int validate_new_branchname(const char *name
, struct strbuf
*ref
,
160 int force
, int attr_only
)
162 if (strbuf_check_branch_ref(ref
, name
))
163 die(_("'%s' is not a valid branch name."), name
);
165 if (!ref_exists(ref
->buf
))
167 else if (!force
&& !attr_only
)
168 die(_("A branch named '%s' already exists."), ref
->buf
+ strlen("refs/heads/"));
172 unsigned char sha1
[20];
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."));
181 static int check_tracking_branch(struct remote
*remote
, void *cb_data
)
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
);
190 static int validate_remote_tracking_branch(char *ref
)
192 return !for_each_remote(check_tracking_branch
, ref
);
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
[] =
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"
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.");
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
)
214 struct commit
*commit
;
215 unsigned char sha1
[20];
216 char *real_ref
, msg
[PATH_MAX
+ 20];
217 struct strbuf ref
= STRBUF_INIT
;
219 int dont_change_ref
= 0;
220 int explicit_tracking
= 0;
222 if (track
== BRANCH_TRACK_EXPLICIT
|| track
== BRANCH_TRACK_OVERRIDE
)
223 explicit_tracking
= 1;
225 if (validate_new_branchname(name
, &ref
, force
,
226 track
== BRANCH_TRACK_OVERRIDE
||
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
));
242 die(_(upstream_missing
), start_name
);
244 die(_("Not a valid object name: '%s'."), start_name
);
247 switch (dwim_ref(start_name
, strlen(start_name
), sha1
, &real_ref
)) {
249 /* Not branching from any existing branch */
250 if (explicit_tracking
)
251 die(_(upstream_not_branch
), start_name
);
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
);
264 die(_("Ambiguous object name: '%s'."), start_name
);
268 if ((commit
= lookup_commit_reference(sha1
)) == NULL
)
269 die(_("Not a valid branch point: '%s'."), start_name
);
270 hashcpy(sha1
, commit
->object
.sha1
);
273 snprintf(msg
, sizeof msg
, "branch: Reset to %s",
275 else if (!dont_change_ref
)
276 snprintf(msg
, sizeof msg
, "branch: Created from %s",
280 log_all_ref_updates
= 1;
282 if (!dont_change_ref
) {
283 struct ref_transaction
*transaction
;
284 struct strbuf err
= STRBUF_INIT
;
286 transaction
= ref_transaction_begin(&err
);
288 ref_transaction_update(transaction
, ref
.buf
,
289 sha1
, forcing
? NULL
: null_sha1
,
291 ref_transaction_commit(transaction
, &err
))
293 ref_transaction_free(transaction
);
294 strbuf_release(&err
);
297 if (real_ref
&& track
)
298 setup_tracking(ref
.buf
+ 11, real_ref
, track
, quiet
);
300 strbuf_release(&ref
);
304 void remove_branch_state(void)
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());
315 void die_if_checked_out(const char *branch
)
319 existing
= find_shared_symref("HEAD", branch
);
321 skip_prefix(branch
, "refs/heads/", &branch
);
322 die(_("'%s' is already checked out at '%s'"), branch
, existing
);