Merge branch 'jn/branch-move-to-self' into maint

* jn/branch-move-to-self:
  Allow checkout -B <current-branch> to update the current branch
  branch: allow a no-op "branch -M <current-branch> HEAD"
This commit is contained in:
Junio C Hamano 2011-12-28 11:32:33 -08:00
commit 79587741cb
6 changed files with 47 additions and 13 deletions

View File

@ -160,7 +160,8 @@ int validate_new_branchname(const char *name, struct strbuf *ref,
void create_branch(const char *head, void create_branch(const char *head,
const char *name, const char *start_name, const char *name, const char *start_name,
int force, int reflog, enum branch_track track) int force, int reflog, int clobber_head,
enum branch_track track)
{ {
struct ref_lock *lock = NULL; struct ref_lock *lock = NULL;
struct commit *commit; struct commit *commit;
@ -175,7 +176,8 @@ void create_branch(const char *head,
explicit_tracking = 1; explicit_tracking = 1;
if (validate_new_branchname(name, &ref, force, if (validate_new_branchname(name, &ref, force,
track == BRANCH_TRACK_OVERRIDE)) { track == BRANCH_TRACK_OVERRIDE ||
clobber_head)) {
if (!force) if (!force)
dont_change_ref = 1; dont_change_ref = 1;
else else

View File

@ -13,7 +13,8 @@
* branch for (if any). * branch for (if any).
*/ */
void create_branch(const char *head, const char *name, const char *start_name, void create_branch(const char *head, const char *name, const char *start_name,
int force, int reflog, enum branch_track track); int force, int reflog,
int clobber_head, enum branch_track track);
/* /*
* Validates that the requested branch may be created, returning the * Validates that the requested branch may be created, returning the

View File

@ -568,6 +568,7 @@ static void rename_branch(const char *oldname, const char *newname, int force)
unsigned char sha1[20]; unsigned char sha1[20];
struct strbuf oldsection = STRBUF_INIT, newsection = STRBUF_INIT; struct strbuf oldsection = STRBUF_INIT, newsection = STRBUF_INIT;
int recovery = 0; int recovery = 0;
int clobber_head_ok;
if (!oldname) if (!oldname)
die(_("cannot rename the current branch while not on any.")); die(_("cannot rename the current branch while not on any."));
@ -583,7 +584,13 @@ static void rename_branch(const char *oldname, const char *newname, int force)
die(_("Invalid branch name: '%s'"), oldname); die(_("Invalid branch name: '%s'"), oldname);
} }
validate_new_branchname(newname, &newref, force, 0); /*
* A command like "git branch -M currentbranch currentbranch" cannot
* cause the worktree to become inconsistent with HEAD, so allow it.
*/
clobber_head_ok = !strcmp(oldname, newname);
validate_new_branchname(newname, &newref, force, clobber_head_ok);
strbuf_addf(&logmsg, "Branch: renamed %s to %s", strbuf_addf(&logmsg, "Branch: renamed %s to %s",
oldref.buf, newref.buf); oldref.buf, newref.buf);
@ -730,7 +737,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
if (kinds != REF_LOCAL_BRANCH) if (kinds != REF_LOCAL_BRANCH)
die(_("-a and -r options to 'git branch' do not make sense with a branch name")); die(_("-a and -r options to 'git branch' do not make sense with a branch name"));
create_branch(head, argv[0], (argc == 2) ? argv[1] : head, create_branch(head, argv[0], (argc == 2) ? argv[1] : head,
force_create, reflog, track); force_create, reflog, 0, track);
} else } else
usage_with_options(builtin_branch_usage, options); usage_with_options(builtin_branch_usage, options);

View File

@ -540,7 +540,9 @@ static void update_refs_for_switch(struct checkout_opts *opts,
else else
create_branch(old->name, opts->new_branch, new->name, create_branch(old->name, opts->new_branch, new->name,
opts->new_branch_force ? 1 : 0, opts->new_branch_force ? 1 : 0,
opts->new_branch_log, opts->track); opts->new_branch_log,
opts->new_branch_force ? 1 : 0,
opts->track);
new->name = opts->new_branch; new->name = opts->new_branch;
setup_branch_path(new); setup_branch_path(new);
} }
@ -565,6 +567,10 @@ static void update_refs_for_switch(struct checkout_opts *opts,
create_symref("HEAD", new->path, msg.buf); create_symref("HEAD", new->path, msg.buf);
if (!opts->quiet) { if (!opts->quiet) {
if (old->path && !strcmp(new->path, old->path)) { if (old->path && !strcmp(new->path, old->path)) {
if (opts->new_branch_force)
fprintf(stderr, _("Reset branch '%s'\n"),
new->name);
else
fprintf(stderr, _("Already on '%s'\n"), fprintf(stderr, _("Already on '%s'\n"),
new->name); new->name);
} else if (opts->new_branch) { } else if (opts->new_branch) {
@ -1057,7 +1063,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
struct strbuf buf = STRBUF_INIT; struct strbuf buf = STRBUF_INIT;
opts.branch_exists = validate_new_branchname(opts.new_branch, &buf, opts.branch_exists = validate_new_branchname(opts.new_branch, &buf,
!!opts.new_branch_force, 0); !!opts.new_branch_force,
!!opts.new_branch_force);
strbuf_release(&buf); strbuf_release(&buf);
} }

View File

@ -189,12 +189,13 @@ test_expect_success 'checkout -b <describe>' '
test_cmp expect actual test_cmp expect actual
' '
test_expect_success 'checkout -B to the current branch fails before merging' ' test_expect_success 'checkout -B to the current branch works' '
git checkout branch1 && git checkout branch1 &&
git checkout -B branch1-scratch &&
setup_dirty_mergeable && setup_dirty_mergeable &&
git commit -mfooble && git checkout -B branch1-scratch initial &&
test_must_fail git checkout -B branch1 initial && test_dirty_mergeable
test_must_fail test_dirty_mergeable
' '
test_done test_done

View File

@ -115,6 +115,22 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
git branch -M baz bam git branch -M baz bam
' '
test_expect_success 'git branch -M master should work when master is checked out' '
git checkout master &&
git branch -M master
'
test_expect_success 'git branch -M master master should work when master is checked out' '
git checkout master &&
git branch -M master master
'
test_expect_success 'git branch -M master2 master2 should work when master is checked out' '
git checkout master &&
git branch master2 &&
git branch -M master2 master2
'
test_expect_success 'git branch -v -d t should work' ' test_expect_success 'git branch -v -d t should work' '
git branch t && git branch t &&
test_path_is_file .git/refs/heads/t && test_path_is_file .git/refs/heads/t &&