Skip to content

Commit 7958774

Browse files
committed
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"
2 parents e39888b + 39bd6f7 commit 7958774

File tree

6 files changed

+47
-13
lines changed

6 files changed

+47
-13
lines changed

branch.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ int validate_new_branchname(const char *name, struct strbuf *ref,
160160

161161
void create_branch(const char *head,
162162
const char *name, const char *start_name,
163-
int force, int reflog, enum branch_track track)
163+
int force, int reflog, int clobber_head,
164+
enum branch_track track)
164165
{
165166
struct ref_lock *lock = NULL;
166167
struct commit *commit;
@@ -175,7 +176,8 @@ void create_branch(const char *head,
175176
explicit_tracking = 1;
176177

177178
if (validate_new_branchname(name, &ref, force,
178-
track == BRANCH_TRACK_OVERRIDE)) {
179+
track == BRANCH_TRACK_OVERRIDE ||
180+
clobber_head)) {
179181
if (!force)
180182
dont_change_ref = 1;
181183
else

branch.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
* branch for (if any).
1414
*/
1515
void create_branch(const char *head, const char *name, const char *start_name,
16-
int force, int reflog, enum branch_track track);
16+
int force, int reflog,
17+
int clobber_head, enum branch_track track);
1718

1819
/*
1920
* Validates that the requested branch may be created, returning the

builtin/branch.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ static void rename_branch(const char *oldname, const char *newname, int force)
568568
unsigned char sha1[20];
569569
struct strbuf oldsection = STRBUF_INIT, newsection = STRBUF_INIT;
570570
int recovery = 0;
571+
int clobber_head_ok;
571572

572573
if (!oldname)
573574
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)
583584
die(_("Invalid branch name: '%s'"), oldname);
584585
}
585586

586-
validate_new_branchname(newname, &newref, force, 0);
587+
/*
588+
* A command like "git branch -M currentbranch currentbranch" cannot
589+
* cause the worktree to become inconsistent with HEAD, so allow it.
590+
*/
591+
clobber_head_ok = !strcmp(oldname, newname);
592+
593+
validate_new_branchname(newname, &newref, force, clobber_head_ok);
587594

588595
strbuf_addf(&logmsg, "Branch: renamed %s to %s",
589596
oldref.buf, newref.buf);
@@ -730,7 +737,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
730737
if (kinds != REF_LOCAL_BRANCH)
731738
die(_("-a and -r options to 'git branch' do not make sense with a branch name"));
732739
create_branch(head, argv[0], (argc == 2) ? argv[1] : head,
733-
force_create, reflog, track);
740+
force_create, reflog, 0, track);
734741
} else
735742
usage_with_options(builtin_branch_usage, options);
736743

builtin/checkout.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,9 @@ static void update_refs_for_switch(struct checkout_opts *opts,
540540
else
541541
create_branch(old->name, opts->new_branch, new->name,
542542
opts->new_branch_force ? 1 : 0,
543-
opts->new_branch_log, opts->track);
543+
opts->new_branch_log,
544+
opts->new_branch_force ? 1 : 0,
545+
opts->track);
544546
new->name = opts->new_branch;
545547
setup_branch_path(new);
546548
}
@@ -565,8 +567,12 @@ static void update_refs_for_switch(struct checkout_opts *opts,
565567
create_symref("HEAD", new->path, msg.buf);
566568
if (!opts->quiet) {
567569
if (old->path && !strcmp(new->path, old->path)) {
568-
fprintf(stderr, _("Already on '%s'\n"),
569-
new->name);
570+
if (opts->new_branch_force)
571+
fprintf(stderr, _("Reset branch '%s'\n"),
572+
new->name);
573+
else
574+
fprintf(stderr, _("Already on '%s'\n"),
575+
new->name);
570576
} else if (opts->new_branch) {
571577
if (opts->branch_exists)
572578
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)
10571063
struct strbuf buf = STRBUF_INIT;
10581064

10591065
opts.branch_exists = validate_new_branchname(opts.new_branch, &buf,
1060-
!!opts.new_branch_force, 0);
1066+
!!opts.new_branch_force,
1067+
!!opts.new_branch_force);
10611068

10621069
strbuf_release(&buf);
10631070
}

t/t2018-checkout-branch.sh

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,13 @@ test_expect_success 'checkout -b <describe>' '
189189
test_cmp expect actual
190190
'
191191

192-
test_expect_success 'checkout -B to the current branch fails before merging' '
192+
test_expect_success 'checkout -B to the current branch works' '
193193
git checkout branch1 &&
194+
git checkout -B branch1-scratch &&
195+
194196
setup_dirty_mergeable &&
195-
git commit -mfooble &&
196-
test_must_fail git checkout -B branch1 initial &&
197-
test_must_fail test_dirty_mergeable
197+
git checkout -B branch1-scratch initial &&
198+
test_dirty_mergeable
198199
'
199200

200201
test_done

t/t3200-branch.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,22 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
115115
git branch -M baz bam
116116
'
117117

118+
test_expect_success 'git branch -M master should work when master is checked out' '
119+
git checkout master &&
120+
git branch -M master
121+
'
122+
123+
test_expect_success 'git branch -M master master should work when master is checked out' '
124+
git checkout master &&
125+
git branch -M master master
126+
'
127+
128+
test_expect_success 'git branch -M master2 master2 should work when master is checked out' '
129+
git checkout master &&
130+
git branch master2 &&
131+
git branch -M master2 master2
132+
'
133+
118134
test_expect_success 'git branch -v -d t should work' '
119135
git branch t &&
120136
test_path_is_file .git/refs/heads/t &&

0 commit comments

Comments
 (0)