git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Nicolas Pitre <nico@fluxnic.net>
Cc: Mark Lodato <lodatom@gmail.com>,
	Sverre Rabbelier <srabbelier@gmail.com>,
	Git List <git@vger.kernel.org>, Ron1 <ron1@flownet.com>,
	Jacob Helwig <jacob.helwig@gmail.com>
Subject: Re: master^ is not a local branch -- huh?!?
Date: Fri, 29 Jan 2010 22:03:24 -0800	[thread overview]
Message-ID: <7v8wbg2kpf.fsf@alter.siamese.dyndns.org> (raw)
In-Reply-To: <alpine.LFD.2.00.1001292305500.1681@xanadu.home> (Nicolas Pitre's message of "Fri\, 29 Jan 2010 23\:39\:25 -0500 \(EST\)")

Nicolas Pitre <nico@fluxnic.net> writes:

> First, I'm afraid that "Checking out commit 'foobar'" might be confusing 
> as this may happen through either a remote branch, a tag, or any random 
> commit.  It seems to me that "Checking out 'v2.5'" is less confusing 
> than "Checking out commit 'v2.5'".  But that's a minor detail and 
> probably a personal preference.
> ...
> To the contrary: this "detached HEAD" is exactly what you need if you 
> want to relate to any documentation or perform a search for more 
> information.  Like it or not, this detached HEAD term is exactly what 
> this Git concept is all about and how it is designated everywhere.  The 
> sooner Git users see and learn about it the better.

As I am not good at keeping track of different proposals to change this
word here and that word there, I expect this will probably need at least
few rotations of earth to get input from people in different timezones,
and I think this is post 1.7.0 item anyway, I'll queue the attached draft
in 'pu' and keep it there, to make it easier for others to tweak the
message.

-- >8 --
Subject: [PATCH] Reword "detached HEAD" notification

The old "advice" message explained how to create a branch after going into
a detached HEAD state but didn't make it clear why the user may want to do
so.  Also "moving to ... which isn't a local branch" was unclear if it is
complaining, if it is describing the new state, or if it is explaining why
the HEAD is detached (the true reason is the last one).

Give the established phrase 'detached HEAD' first to make it easy for
users to look up the concept in documentation, and briefly describe what
can be done in the state (i.e. play around without having to clean up)
before telling the user how to keep what was done during the temporary
state.

Allow the long description to be hidden by setting advice.detachedHead
configuration to false.

We might want to customize the advice depending on how the commit to check
out was spelled (e.g. instead of "new-branch-name", we way want to say
"topic" when "git checkout origin/topic" triggered this message) in later
updates, but this encapsulates that into a separate function and it should
be a good first step.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/config.txt |    5 +++++
 advice.c                 |    2 ++
 advice.h                 |    1 +
 builtin-checkout.c       |   18 ++++++++++++++++--
 t/t7201-co.sh            |   32 ++++++++++++++++++++++----------
 5 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 17901e2..fee44d8 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -138,6 +138,11 @@ advice.*::
 		Advice on how to set your identity configuration when
 		your information is guessed from the system username and
 		domain name. Default: true.
+
+	detachedHead::
+		Advice shown when you used linkgit::git-checkout[1] to
+		move to the detach HEAD state, to instruct how to create
+		a local branch after the fact.  Default: true.
 --
 
 core.fileMode::
diff --git a/advice.c b/advice.c
index 936d98b..0be4b5f 100644
--- a/advice.c
+++ b/advice.c
@@ -5,6 +5,7 @@ int advice_status_hints = 1;
 int advice_commit_before_merge = 1;
 int advice_resolve_conflict = 1;
 int advice_implicit_identity = 1;
+int advice_detached_head = 1;
 
 static struct {
 	const char *name;
@@ -15,6 +16,7 @@ static struct {
 	{ "commitbeforemerge", &advice_commit_before_merge },
 	{ "resolveconflict", &advice_resolve_conflict },
 	{ "implicitidentity", &advice_implicit_identity },
+	{ "detachedhead", &advice_detached_head },
 };
 
 int git_default_advice_config(const char *var, const char *value)
diff --git a/advice.h b/advice.h
index 9b7a3ad..3244ebb 100644
--- a/advice.h
+++ b/advice.h
@@ -8,6 +8,7 @@ extern int advice_status_hints;
 extern int advice_commit_before_merge;
 extern int advice_resolve_conflict;
 extern int advice_implicit_identity;
+extern int advice_detached_head;
 
 int git_default_advice_config(const char *var, const char *value);
 
diff --git a/builtin-checkout.c b/builtin-checkout.c
index 5277817..c5ab783 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -488,6 +488,20 @@ static void report_tracking(struct branch_info *new)
 	strbuf_release(&sb);
 }
 
+static void detach_advice(const char *old_path, const char *new_name)
+{
+	const char fmt[] =
+	"Note: checking out '%s'.\n\n"
+	"You are in 'detached HEAD' state. You can look around, make experimental\n"
+	"changes and commit them, and you can discard any commits you make in this\n"
+	"state without impacting any branches by performing another checkout.\n\n"
+	"If you want to create a new branch to retain commits you create, you may\n"
+	"do so (now or later) by using -b with the checkout command again. Example:\n\n"
+	"  git checkout -b new_branch_name\n\n";
+
+	fprintf(stderr, fmt, new_name);
+}
+
 static void update_refs_for_switch(struct checkout_opts *opts,
 				   struct branch_info *old,
 				   struct branch_info *new)
@@ -522,8 +536,8 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 		update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
 			   REF_NODEREF, DIE_ON_ERR);
 		if (!opts->quiet) {
-			if (old->path)
-				fprintf(stderr, "Note: moving to '%s' which isn't a local branch\nIf you want to create a new branch from this checkout, you may do so\n(now or later) by using -b with the checkout command again. Example:\n  git checkout -b <new_branch_name>\n", new->name);
+			if (old->path && advice_detached_head)
+				detach_advice(old->path, new->name);
 			describe_detached_head("HEAD is now at", new->commit);
 		}
 	}
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 6442f71..d20ed61 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -166,19 +166,31 @@ test_expect_success 'checkout -m with merge conflict' '
 	! test -s current
 '
 
-test_expect_success 'checkout to detach HEAD' '
+test_expect_success 'checkout to detach HEAD (with advice declined)' '
 
+	git config advice.detachedHead false &&
 	git checkout -f renamer && git clean -f &&
 	git checkout renamer^ 2>messages &&
-	(cat >messages.expect <<EOF
-Note: moving to '\''renamer^'\'' which isn'\''t a local branch
-If you want to create a new branch from this checkout, you may do so
-(now or later) by using -b with the checkout command again. Example:
-  git checkout -b <new_branch_name>
-HEAD is now at 7329388... Initial A one, A two
-EOF
-) &&
-	test_cmp messages.expect messages &&
+	grep "HEAD is now at 7329388" messages &&
+	test 1 -eq $(wc -l <messages) &&
+	H=$(git rev-parse --verify HEAD) &&
+	M=$(git show-ref -s --verify refs/heads/master) &&
+	test "z$H" = "z$M" &&
+	if git symbolic-ref HEAD >/dev/null 2>&1
+	then
+		echo "OOPS, HEAD is still symbolic???"
+		false
+	else
+		: happy
+	fi
+'
+
+test_expect_success 'checkout to detach HEAD' '
+	git config advice.detachedHead true &&
+	git checkout -f renamer && git clean -f &&
+	git checkout renamer^ 2>messages &&
+	grep "HEAD is now at 7329388" messages &&
+	test 1 -lt $(wc -l <messages) &&
 	H=$(git rev-parse --verify HEAD) &&
 	M=$(git show-ref -s --verify refs/heads/master) &&
 	test "z$H" = "z$M" &&
-- 
1.7.0.rc0.187.g226c

  parent reply	other threads:[~2010-01-30  6:03 UTC|newest]

Thread overview: 118+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-29 20:20 master^ is not a local branch -- huh?!? Ron1
2010-01-29 20:27 ` Jacob Helwig
2010-01-29 20:35   ` Sverre Rabbelier
2010-01-29 20:38     ` Jacob Helwig
2010-01-29 20:48     ` Junio C Hamano
2010-01-29 20:56       ` Sverre Rabbelier
2010-01-29 21:09         ` [PATCH] checkout: warn about 'branch name' rather than 'local branch' Sverre Rabbelier
2010-01-29 21:19           ` [PATCH] checkout: Fix test for s/local branch/branch name/ change Jacob Helwig
2010-01-29 21:20             ` Sverre Rabbelier
2010-01-29 21:40           ` [PATCH] checkout: warn about 'branch name' rather than 'local branch' Nicolas Pitre
2010-01-29 21:50             ` Ron Garret
2010-01-29 21:42           ` Junio C Hamano
2010-01-29 21:45             ` Sverre Rabbelier
2010-01-29 21:35         ` master^ is not a local branch -- huh?!? Junio C Hamano
2010-01-29 21:20       ` Nicolas Pitre
2010-01-29 21:21         ` Sverre Rabbelier
2010-01-29 21:29           ` Nicolas Pitre
2010-01-29 21:32             ` Sverre Rabbelier
2010-01-29 21:51               ` Nicolas Pitre
2010-01-29 21:58                 ` Junio C Hamano
2010-01-29 22:00                   ` Sverre Rabbelier
2010-01-29 22:34                   ` Nicolas Pitre
2010-01-29 22:39                     ` Junio C Hamano
2010-01-29 22:46                       ` Jacob Helwig
2010-01-29 23:43                       ` Nicolas Pitre
2010-01-30  0:14                         ` Junio C Hamano
2010-01-30  0:18                           ` Sverre Rabbelier
2010-01-30  0:29                             ` Junio C Hamano
2010-01-30  0:35                               ` Sverre Rabbelier
2010-01-30  0:38                               ` Michael Witten
2010-01-30  0:39                               ` Nicolas Pitre
2010-01-30  1:01                               ` Mark Lodato
2010-01-30  1:22                                 ` Nicolas Pitre
2010-01-30  2:38                                   ` Ron Garret
2010-01-30  2:59                                     ` Junio C Hamano
2010-01-30  3:26                                       ` Ron Garret
2010-01-30  4:03                                         ` Nicolas Pitre
2010-01-30  5:06                                           ` Jay Soffian
2010-01-30  5:09                                         ` Junio C Hamano
2010-01-30  4:52                                       ` Jay Soffian
2010-01-30  5:15                                         ` Nicolas Pitre
2010-01-30  5:21                                           ` Junio C Hamano
2010-01-30  6:25                                             ` Ron Garret
2010-01-30 18:25                                               ` Junio C Hamano
2010-01-30  5:45                                           ` Jay Soffian
2010-01-30  5:18                                         ` Junio C Hamano
2010-01-30  6:23                                         ` Ron Garret
2010-01-30  2:40                                   ` Mark Lodato
2010-01-30  3:11                                     ` Nicolas Pitre
2010-01-30  3:59                                       ` Mark Lodato
2010-01-30  4:39                                         ` Nicolas Pitre
2010-01-30  5:05                                           ` Nicolas Pitre
2010-01-30  5:11                                             ` Jay Soffian
2010-01-30  5:25                                               ` Nicolas Pitre
2010-01-30  5:53                                           ` Mark Lodato
2010-01-30  6:03                                           ` Junio C Hamano [this message]
2010-01-30  8:59                 ` Jeff King
2010-01-30 18:40                   ` Ron Garret
2010-01-29 23:16               ` A Large Angry SCM
2010-01-29 21:49         ` Junio C Hamano
2010-01-30  2:13         ` Johannes Schindelin
2010-01-30  3:15           ` Nicolas Pitre
2010-01-29 20:35   ` Johannes Schindelin
2010-01-29 21:16     ` Ron1
2010-01-29 21:25       ` Jacob Helwig
2010-01-29 21:43         ` Ron Garret
2010-01-29 21:59           ` Junio C Hamano
2010-01-29 22:18             ` Ron Garret
2010-01-31  7:32     ` Junio C Hamano
2010-01-29 20:32 ` Octavio Alvarez
2010-01-29 21:34   ` Ron Garret
2010-01-29 22:32     ` Octavio Alvarez
2010-01-29 22:47       ` Ron Garret
2010-01-29 23:05         ` Octavio Alvarez
2010-01-29 23:12         ` Junio C Hamano
2010-01-29 23:30           ` Ron Garret
2010-01-29 23:28         ` Julian Phillips
2010-01-30  0:14           ` Ron Garret
2010-01-30  0:18             ` Ron Garret
2010-01-30 19:02               ` Junio C Hamano
2010-01-30 19:24                 ` Ron Garret
2010-01-29 20:36 ` Scott R. Godin
2010-01-29 21:24   ` Ron Garret
2010-01-29 21:28     ` Sverre Rabbelier
2010-01-29 21:40       ` Ron Garret
2010-01-29 21:54       ` Junio C Hamano
2010-01-29 22:12         ` Ron Garret
2010-01-30  0:33           ` Michael Witten
2010-01-30  3:06             ` Junio C Hamano
2010-01-30  6:16               ` Ron Garret
2010-01-30  6:45                 ` Junio C Hamano
2010-01-30  7:31                   ` Ron Garret
2010-01-30  8:02                     ` Junio C Hamano
2010-01-30  8:56                       ` Ron Garret
  -- strict thread matches above, loose matches on Subject: below --
2010-02-01 11:52 Steve Diver
2010-02-01 17:38 ` Junio C Hamano
2010-02-01 17:58   ` Sergei Organov
2010-02-01 22:52     ` Ron Garret
2010-02-01 23:01       ` Petr Baudis
2010-02-01 23:25       ` Nicolas Pitre
2010-02-01 23:37       ` Junio C Hamano
2010-02-01 23:56         ` Ron Garret
2010-02-02  0:15           ` Petr Baudis
2010-02-02  0:45             ` Ron Garret
2010-02-02  0:53               ` Junio C Hamano
2010-02-02  1:12                 ` Ron Garret
2010-02-02 19:19                   ` J. Bruce Fields
2010-02-02 22:04                     ` Ron Garret
2010-02-03 18:27                       ` J. Bruce Fields
2010-02-02  4:05               ` Nicolas Pitre
2010-02-02  5:23                 ` Ron Garret
2010-02-02  5:43                   ` Nicolas Pitre
2010-02-02 21:07                   ` tytso
2010-02-02  0:26           ` Junio C Hamano
2010-02-02  0:21       ` Junio C Hamano
2010-02-01 18:12   ` Nicolas Pitre
2010-02-01 18:27     ` Jay Soffian
2010-02-01 22:34     ` Steve Diver

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7v8wbg2kpf.fsf@alter.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=jacob.helwig@gmail.com \
    --cc=lodatom@gmail.com \
    --cc=nico@fluxnic.net \
    --cc=ron1@flownet.com \
    --cc=srabbelier@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).