git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 4/3] branch: fix "copy" to never touch HEAD

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 22, 2017, 04:57 UTC
Message-ID
<xmqqvakbjpo5.fsf_-_@gitster.mtv.corp.google.com>
In-Reply-To
<xmqq60f6h03t.fsf@gitster.mtv.corp.google.com>

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>
---
 * Let's send an updated one as a follow-up to the discussion thread
   that it is a follow-up to.  The patch in this message is the same
   as the one I previously sent; the proposed log message has been
   updated somewhat.
 builtin/branch.c  |  9 +++------
 t/t3200-branch.sh | 10 +++++-----
 2 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/builtin/branch.c b/builtin/branch.c
index 89f64f4123..e2e3692838 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -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);
 
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 5d03ad16f6..be9b3784c6 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -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 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' '
-- 
2.14.1-929-g25eae544e9
Previous: Junio C HamanoNext: Brandon Williams
Message 10 of 14 in “What's cooking in git.git (Jul 2017, #01; Wed, 5)”
  1. Junio C HamanoJul 5, 2017
  2. Stefan BellerJul 5, 2017
  3. Junio C HamanoJul 7, 2017
  4. Stefan BellerJul 10, 2017
  5. 0/3 branch: add a --copy to go with --moveÆvar Arnfjörð Bjarmason, Jul 5, 2017
  6. 1/3 config: create a function to format section headersÆvar Arnfjörð Bjarmason, Jul 5, 2017
  7. 2/3 branch: add test for -m renaming multiple config sectionsÆvar Arnfjörð Bjarmason, Jul 5, 2017
  8. 3/3 branch: add a --copy (-c) option to go with --move (-m)Ævar Arnfjörð Bjarmason, Jul 5, 2017
  9. Junio C HamanoJul 6, 2017
  10. 4/3 branch: fix "copy" to never touch HEADJunio C Hamano, Sep 22, 2017
  11. Brandon WilliamsSep 22, 2017
  12. Ævar Arnfjörð BjarmasonSep 26, 2017
  13. Junio C HamanoSep 27, 2017
  14. Ævar Arnfjörð BjarmasonSep 29, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.