summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Jonathan Nieder <jrnieder@gmail.com>2011-11-26 02:54:55 -0600
committerLibravatar Junio C Hamano <gitster@pobox.com>2011-11-28 11:40:46 -0800
commit39bd6f726109942c6f77f59638f6763c9f00706c (patch)
tree903f5b34643ab93fa0a164a3962c70461b20406b
parentbranch: allow a no-op "branch -M <current-branch> HEAD" (diff)
downloadtgif-39bd6f726109942c6f77f59638f6763c9f00706c.tar.xz
Allow checkout -B <current-branch> to update the current branch
When on master, "git checkout -B master <commit>" is a more natural way to say "git reset --keep <commit>", which was originally invented for the exact purpose of moving to the named commit while keeping the local changes around. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--branch.c6
-rw-r--r--branch.h3
-rw-r--r--builtin/branch.c2
-rw-r--r--builtin/checkout.c15
-rwxr-xr-xt/t2018-checkout-branch.sh9
5 files changed, 23 insertions, 12 deletions
diff --git a/branch.c b/branch.c
index 025a97be02..f85c438284 100644
--- a/branch.c
+++ b/branch.c
@@ -160,7 +160,8 @@ int validate_new_branchname(const char *name, struct strbuf *ref,
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;
@@ -175,7 +176,8 @@ void create_branch(const char *head,
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 1285158dd4..e125ff4ca8 100644
--- a/branch.h
+++ b/branch.h
@@ -13,7 +13,8 @@
* 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 24f33b241e..823789fc95 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -737,7 +737,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
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 2a80772425..ca00a8538a 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -540,7 +540,9 @@ static void update_refs_for_switch(struct checkout_opts *opts,
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);
}
@@ -565,8 +567,12 @@ static void update_refs_for_switch(struct checkout_opts *opts,
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);
@@ -1057,7 +1063,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
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);
}
diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh
index 75874e85df..2741262369 100755
--- a/t/t2018-checkout-branch.sh
+++ b/t/t2018-checkout-branch.sh
@@ -189,12 +189,13 @@ test_expect_success 'checkout -b <describe>' '
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