Skip to content

Commit e5435ff

Browse files
committed
branch: fix "copy" to never touch HEAD
When creating a new branch B by copying the branch A that happens to be the current branch, it also updates HEAD to point at the new branch. It probably was made this way because "git branch -c A B" piggybacked its implementation on "git branch -m A B", This does not match the usual expectation. If I were sitting on a blue chair, and somebody comes and repaints it to red, I would accept ending up sitting on a chair that is now red (I am also OK to stand, instead, as there no longer is my favourite blue chair). But if somebody creates a new red chair, modelling it after the blue chair I am sitting on, I do not expect to be booted off of the blue chair and ending up on sitting on the new red one. Let's fix this before it hits 'next'. Those who want to create a new branch and switch to it can do "git checkout B" after doing a "git branch -c B", and if that operation is so useful and deserves a short-hand way to do so, perhaps extend "git checkout -b B" to copy configurations while creating the new branch B. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 52d59cc commit e5435ff

File tree

2 files changed

+8
-11
lines changed

2 files changed

+8
-11
lines changed

builtin/branch.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -506,12 +506,9 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
506506
oldref.buf + 11);
507507
}
508508

509-
if (replace_each_worktree_head_symref(oldref.buf, newref.buf, logmsg.buf)) {
510-
if (copy)
511-
die(_("Branch copied to %s, but HEAD is not updated!"), newname);
512-
else
513-
die(_("Branch renamed to %s, but HEAD is not updated!"), newname);
514-
}
509+
if (!copy &&
510+
replace_each_worktree_head_symref(oldref.buf, newref.buf, logmsg.buf))
511+
die(_("Branch renamed to %s, but HEAD is not updated!"), newname);
515512

516513
strbuf_release(&logmsg);
517514

t/t3200-branch.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ test_expect_success 'git branch --copy is a synonym for -c' '
422422
test_cmp expect actual
423423
'
424424

425-
test_expect_success 'git branch -c ee ef should copy and checkout branch ef' '
425+
test_expect_success 'git branch -c ee ef should copy ee to create branch ef' '
426426
git checkout -b ee &&
427427
git reflog exists refs/heads/ee &&
428428
git config branch.ee.dummy Hello &&
@@ -431,7 +431,7 @@ test_expect_success 'git branch -c ee ef should copy and checkout branch ef' '
431431
git reflog exists refs/heads/ef &&
432432
test $(git config branch.ee.dummy) = Hello &&
433433
test $(git config branch.ef.dummy) = Hello &&
434-
test $(git rev-parse --abbrev-ref HEAD) = ef
434+
test $(git rev-parse --abbrev-ref HEAD) = ee
435435
'
436436

437437
test_expect_success 'git branch -c f/f g/g should work' '
@@ -494,12 +494,12 @@ test_expect_success 'git branch -C c1 c2 should succeed when c1 is checked out'
494494
git checkout -b c1 &&
495495
git branch c2 &&
496496
git branch -C c1 c2 &&
497-
test $(git rev-parse --abbrev-ref HEAD) = c2
497+
test $(git rev-parse --abbrev-ref HEAD) = c1
498498
'
499499

500-
test_expect_success 'git branch -C c1 c2 should add entries to .git/logs/HEAD' '
500+
test_expect_success 'git branch -C c1 c2 should never touch HEAD' '
501501
msg="Branch: copied refs/heads/c1 to refs/heads/c2" &&
502-
grep "$msg$" .git/logs/HEAD
502+
! grep "$msg$" .git/logs/HEAD
503503
'
504504

505505
test_expect_success 'git branch -C master should work when master is checked out' '

0 commit comments

Comments
 (0)