]> git.ipfire.org Git - thirdparty/git.git/commitdiff
branch: fix "copy" to never touch HEAD
authorJunio C Hamano <gitster@pobox.com>
Fri, 22 Sep 2017 03:24:50 +0000 (12:24 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sat, 23 Sep 2017 23:42:12 +0000 (08:42 +0900)
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 <gitster@pobox.com>
builtin/branch.c
t/t3200-branch.sh

index 89f64f4123a5ef609a20324606f23157b901d4e8..e2e3692838e305b7ab8e569fecf6ae8b3a73e6ac 100644 (file)
@@ -506,12 +506,9 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
                                oldref.buf + 11);
        }
 
-       if (replace_each_worktree_head_symref(oldref.buf, newref.buf, logmsg.buf)) {
-               if (copy)
-                       die(_("Branch copied to %s, but HEAD is not updated!"), newname);
-               else
-                       die(_("Branch renamed to %s, but HEAD is not updated!"), newname);
-       }
+       if (!copy &&
+           replace_each_worktree_head_symref(oldref.buf, newref.buf, logmsg.buf))
+               die(_("Branch renamed to %s, but HEAD is not updated!"), newname);
 
        strbuf_release(&logmsg);
 
index 5d03ad16f68c94af1ab0991897070f1442e78924..e286ddaf2314bc64bd515b6ba44089dc7098fe6d 100755 (executable)
@@ -422,7 +422,7 @@ test_expect_success 'git branch --copy is a synonym for -c' '
        test_cmp expect actual
 '
 
-test_expect_success 'git branch -c ee ef should copy and checkout branch ef' '
+test_expect_success 'git branch -c ee ef should copy ee to create branch ef' '
        git checkout -b ee &&
        git reflog exists refs/heads/ee &&
        git config branch.ee.dummy Hello &&
@@ -431,7 +431,7 @@ test_expect_success 'git branch -c ee ef should copy and checkout branch ef' '
        git reflog exists refs/heads/ef &&
        test $(git config branch.ee.dummy) = Hello &&
        test $(git config branch.ef.dummy) = Hello &&
-       test $(git rev-parse --abbrev-ref HEAD) = ef
+       test $(git rev-parse --abbrev-ref HEAD) = ee
 '
 
 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'
        git checkout -b c1 &&
        git branch c2 &&
        git branch -C c1 c2 &&
-       test $(git rev-parse --abbrev-ref HEAD) = c2
+       test $(git rev-parse --abbrev-ref HEAD) = c1
 '
 
-test_expect_success 'git branch -C c1 c2 should add entries to .git/logs/HEAD' '
+test_expect_success 'git branch -C c1 c2 should never touch HEAD' '
        msg="Branch: copied refs/heads/c1 to refs/heads/c2" &&
-       grep "$msg$" .git/logs/HEAD
+       grep "$msg$" .git/logs/HEAD
 '
 
 test_expect_success 'git branch -C master should work when master is checked out' '