#include "refs.h"
#include "remote.h"
#include "commit.h"
+#include "sequencer.h"
struct tracking {
struct refspec spec;
return 0;
}
+int validate_new_branchname(const char *name, struct strbuf *ref,
+ int force, int attr_only)
+{
+ if (strbuf_check_branch_ref(ref, name))
+ die("'%s' is not a valid branch name.", name);
+
+ if (!ref_exists(ref->buf))
+ return 0;
+ else if (!force && !attr_only)
+ die("A branch named '%s' already exists.", ref->buf + strlen("refs/heads/"));
+
+ if (!attr_only) {
+ const char *head;
+ unsigned char sha1[20];
+
+ head = resolve_ref("HEAD", sha1, 0, NULL);
+ if (!is_bare_repository() && head && !strcmp(head, ref->buf))
+ die("Cannot force update the current branch.");
+ }
+ return 1;
+}
+
void create_branch(const char *head,
const char *name, const char *start_name,
int force, int reflog, enum branch_track track)
if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
explicit_tracking = 1;
- if (strbuf_check_branch_ref(&ref, name))
- die("'%s' is not a valid branch name.", name);
-
- if (resolve_ref(ref.buf, sha1, 1, NULL)) {
- if (!force && track == BRANCH_TRACK_OVERRIDE)
+ if (validate_new_branchname(name, &ref, force,
+ track == BRANCH_TRACK_OVERRIDE)) {
+ if (!force)
dont_change_ref = 1;
- else if (!force)
- die("A branch named '%s' already exists.", name);
- else if (!is_bare_repository() && !strcmp(head, name))
- die("Cannot force update the current branch.");
- forcing = 1;
+ else
+ forcing = 1;
}
real_ref = NULL;
die("Cannot setup tracking information; starting point is not a branch.");
break;
case 1:
- /* Unique completion -- good, only if it is a real ref */
- if (explicit_tracking && !strcmp(real_ref, "HEAD"))
- die("Cannot setup tracking information; starting point is not a branch.");
+ /* Unique completion -- good, only if it is a real branch */
+ if (prefixcmp(real_ref, "refs/heads/") &&
+ prefixcmp(real_ref, "refs/remotes/")) {
+ if (explicit_tracking)
+ die("Cannot setup tracking information; starting point is not a branch.");
+ else
+ real_ref = NULL;
+ }
break;
default:
die("Ambiguous object name: '%s'.", start_name);
log_all_ref_updates = 1;
if (forcing)
- snprintf(msg, sizeof msg, "branch: Reset from %s",
+ snprintf(msg, sizeof msg, "branch: Reset to %s",
start_name);
else if (!dont_change_ref)
snprintf(msg, sizeof msg, "branch: Created from %s",
start_name);
if (real_ref && track)
- setup_tracking(name, real_ref, track);
+ setup_tracking(ref.buf+11, real_ref, track);
if (!dont_change_ref)
if (write_ref_sha1(lock, sha1, msg) < 0)
void remove_branch_state(void)
{
+ unlink(git_path("CHERRY_PICK_HEAD"));
+ unlink(git_path("REVERT_HEAD"));
unlink(git_path("MERGE_HEAD"));
unlink(git_path("MERGE_RR"));
unlink(git_path("MERGE_MSG"));
unlink(git_path("MERGE_MODE"));
unlink(git_path("SQUASH_MSG"));
+ remove_sequencer_state(0);
}