author | Junio C Hamano <gitster@pobox.com> | |
Wed, 14 Dec 2011 06:53:08 +0000 (22:53 -0800) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Wed, 14 Dec 2011 06:53:08 +0000 (22:53 -0800) |
* 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"
Allow checkout -B <current-branch> to update the current branch
branch: allow a no-op "branch -M <current-branch> HEAD"
diff --git a/branch.c b/branch.c
index d91a099fdd22b9131a1d2ddaf3778b645c53eca0..a715a1174982970943ed2c4fc1c2ab4906699fdc 100644 (file)
--- a/branch.c
+++ b/branch.c
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)
{
struct ref_lock *lock = NULL;
struct commit *commit;
explicit_tracking = 1;
if (validate_new_branchname(name, &ref, force,
- track == BRANCH_TRACK_OVERRIDE)) {
+ track == BRANCH_TRACK_OVERRIDE ||
+ clobber_head)) {
if (!force)
dont_change_ref = 1;
else
diff --git a/branch.h b/branch.h
index 1493f73722161cc191f0c7fd655781d8b748ed41..b99c5a369e31a85d1fff822460e69a79d8c6102b 100644 (file)
--- a/branch.h
+++ b/branch.h
* branch for (if any).
*/
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
diff --git a/builtin/branch.c b/builtin/branch.c
index e1e486e4c51194e09df3779be254cb72855d1103..465ff6a513f3e314d4a526b6f8ee9f7a7c7b43f4 100644 (file)
--- a/builtin/branch.c
+++ b/builtin/branch.c
struct strbuf oldref = STRBUF_INIT, newref = STRBUF_INIT, logmsg = STRBUF_INIT;
struct strbuf oldsection = STRBUF_INIT, newsection = STRBUF_INIT;
int recovery = 0;
+ int clobber_head_ok;
if (!oldname)
die(_("cannot rename the current branch while not on any."));
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",
oldref.buf, newref.buf);
if (kinds != REF_LOCAL_BRANCH)
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,
- force_create, reflog, track);
+ force_create, reflog, 0, track);
} else
usage_with_options(builtin_branch_usage, options);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index b7c630287dda662630af9883655ed23bd50e7b7e..3f5d9b629a515d1531ff801fabdb9a72246d5d5c 100644 (file)
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
else
create_branch(old->name, opts->new_branch, new->name,
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;
setup_branch_path(new);
}
create_symref("HEAD", new->path, msg.buf);
if (!opts->quiet) {
if (old->path && !strcmp(new->path, old->path)) {
- fprintf(stderr, _("Already on '%s'\n"),
- new->name);
+ if (opts->new_branch_force)
+ fprintf(stderr, _("Reset branch '%s'\n"),
+ new->name);
+ else
+ fprintf(stderr, _("Already on '%s'\n"),
+ new->name);
} else if (opts->new_branch) {
if (opts->branch_exists)
fprintf(stderr, _("Switched to and reset branch '%s'\n"), new->name);
struct strbuf buf = STRBUF_INIT;
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);
}
index 75874e85dfbcae8ea9634693a93524841b741559..2741262369e40a05cdc6732e4c9e6f04acb63bba 100755 (executable)
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 -B branch1-scratch &&
+
setup_dirty_mergeable &&
- git commit -mfooble &&
- test_must_fail git checkout -B branch1 initial &&
- test_must_fail test_dirty_mergeable
+ git checkout -B branch1-scratch initial &&
+ test_dirty_mergeable
'
test_done
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index bc73c2099b5069ab136a1d93aef5a8ab4a0dad1f..76903323af37ed1a96b5a11c27eb1e9d63a0e9ef 100755 (executable)
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -115,6 +115,22 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
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' '
git branch t &&
test_path_is_file .git/refs/heads/t &&