Merge branch 'ci/forbid-unwanted-current-branch-update'

* ci/forbid-unwanted-current-branch-update:
  Show interpreted branch name in error messages
  Prevent force-updating of the current branch
This commit is contained in:
Junio C Hamano 2011-08-28 21:19:31 -07:00
commit 1da6d98a9a
6 changed files with 65 additions and 24 deletions

View file

@ -135,6 +135,26 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
return 0;
}
int validate_new_branchname(const char *name, struct strbuf *ref, int force)
{
const char *head;
unsigned char sha1[20];
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)
die("A branch named '%s' already exists.", ref->buf + strlen("refs/heads/"));
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)
@ -151,17 +171,11 @@ void create_branch(const char *head,
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() && head && !strcmp(head, name))
die("Cannot force update the current branch.");
forcing = 1;
else
forcing = 1;
}
real_ref = NULL;

View file

@ -15,6 +15,14 @@
void create_branch(const char *head, const char *name, const char *start_name,
int force, int reflog, enum branch_track track);
/*
* Validates that the requested branch may be created, returning the
* interpreted ref in ref, force indicates whether (non-head) branches
* may be overwritten. A non-zero return value indicates that the force
* parameter was non-zero and the branch already exists.
*/
int validate_new_branchname(const char *name, struct strbuf *ref, int force);
/*
* Remove information about the state of working on the current
* branch. (E.g., MERGE_HEAD)

View file

@ -566,11 +566,7 @@ static void rename_branch(const char *oldname, const char *newname, int force)
die(_("Invalid branch name: '%s'"), oldname);
}
if (strbuf_check_branch_ref(&newref, newname))
die(_("Invalid branch name: '%s'"), newname);
if (resolve_ref(newref.buf, sha1, 1, NULL) && !force)
die(_("A branch named '%s' already exists."), newref.buf + 11);
validate_new_branchname(newname, &newref, force);
strbuf_addf(&logmsg, "Branch: renamed %s to %s",
oldref.buf, newref.buf);

View file

@ -1072,15 +1072,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
if (opts.new_branch) {
struct strbuf buf = STRBUF_INIT;
if (strbuf_check_branch_ref(&buf, opts.new_branch))
die(_("git checkout: we do not like '%s' as a branch name."),
opts.new_branch);
if (ref_exists(buf.buf)) {
opts.branch_exists = 1;
if (!opts.new_branch_force)
die(_("git checkout: branch %s already exists"),
opts.new_branch);
}
opts.branch_exists = validate_new_branchname(opts.new_branch, &buf, !!opts.new_branch_force);
strbuf_release(&buf);
}

View file

@ -118,6 +118,15 @@ test_expect_success 'checkout -b to an existing branch fails' '
test_must_fail do_checkout branch2 $HEAD2
'
test_expect_success 'checkout -b to @{-1} fails with the right branch name' '
git reset --hard HEAD &&
git checkout branch1 &&
git checkout branch2 &&
echo >expect "fatal: A branch named '\''branch1'\'' already exists." &&
test_must_fail git checkout -b @{-1} 2>actual &&
test_cmp expect actual
'
test_expect_success 'checkout -B to an existing branch resets branch to HEAD' '
git checkout branch1 &&
@ -180,4 +189,12 @@ test_expect_success 'checkout -b <describe>' '
test_cmp expect actual
'
test_expect_success 'checkout -B to the current branch fails before merging' '
git checkout branch1 &&
setup_dirty_mergeable &&
git commit -mfooble &&
test_must_fail git checkout -B branch1 initial &&
test_must_fail test_dirty_mergeable
'
test_done

View file

@ -98,6 +98,18 @@ test_expect_success 'git branch -m q r/q should fail when r exists' '
test_must_fail git branch -m q r/q
'
test_expect_success 'git branch -M foo bar should fail when bar is checked out' '
git branch bar &&
git checkout -b foo &&
test_must_fail git branch -M bar foo
'
test_expect_success 'git branch -M baz bam should succeed when baz is checked out' '
git checkout -b baz &&
git branch bam &&
git branch -M baz bam
'
mv .git/config .git/config-saved
test_expect_success 'git branch -m q q2 without config should succeed' '