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>
This commit is contained in:
Junio C Hamano 2010-01-29 22:03:24 -08:00
parent b2c2e4c22c
commit 13be3e31f1
5 changed files with 46 additions and 12 deletions

View File

@ -138,6 +138,11 @@ advice.*::
Advice on how to set your identity configuration when Advice on how to set your identity configuration when
your information is guessed from the system username and your information is guessed from the system username and
domain name. Default: true. 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:: core.fileMode::

View File

@ -5,6 +5,7 @@ int advice_status_hints = 1;
int advice_commit_before_merge = 1; int advice_commit_before_merge = 1;
int advice_resolve_conflict = 1; int advice_resolve_conflict = 1;
int advice_implicit_identity = 1; int advice_implicit_identity = 1;
int advice_detached_head = 1;
static struct { static struct {
const char *name; const char *name;
@ -15,6 +16,7 @@ static struct {
{ "commitbeforemerge", &advice_commit_before_merge }, { "commitbeforemerge", &advice_commit_before_merge },
{ "resolveconflict", &advice_resolve_conflict }, { "resolveconflict", &advice_resolve_conflict },
{ "implicitidentity", &advice_implicit_identity }, { "implicitidentity", &advice_implicit_identity },
{ "detachedhead", &advice_detached_head },
}; };
int git_default_advice_config(const char *var, const char *value) int git_default_advice_config(const char *var, const char *value)

View File

@ -8,6 +8,7 @@ extern int advice_status_hints;
extern int advice_commit_before_merge; extern int advice_commit_before_merge;
extern int advice_resolve_conflict; extern int advice_resolve_conflict;
extern int advice_implicit_identity; extern int advice_implicit_identity;
extern int advice_detached_head;
int git_default_advice_config(const char *var, const char *value); int git_default_advice_config(const char *var, const char *value);

View File

@ -488,6 +488,20 @@ static void report_tracking(struct branch_info *new)
strbuf_release(&sb); 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, static void update_refs_for_switch(struct checkout_opts *opts,
struct branch_info *old, struct branch_info *old,
struct branch_info *new) 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, update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
REF_NODEREF, DIE_ON_ERR); REF_NODEREF, DIE_ON_ERR);
if (!opts->quiet) { if (!opts->quiet) {
if (old->path) if (old->path && advice_detached_head)
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); detach_advice(old->path, new->name);
describe_detached_head("HEAD is now at", new->commit); describe_detached_head("HEAD is now at", new->commit);
} }
} }

View File

@ -166,19 +166,31 @@ test_expect_success 'checkout -m with merge conflict' '
! test -s current ! 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 -f renamer && git clean -f &&
git checkout renamer^ 2>messages && git checkout renamer^ 2>messages &&
(cat >messages.expect <<EOF grep "HEAD is now at 7329388" messages &&
Note: moving to '\''renamer^'\'' which isn'\''t a local branch test 1 -eq $(wc -l <messages) &&
If you want to create a new branch from this checkout, you may do so H=$(git rev-parse --verify HEAD) &&
(now or later) by using -b with the checkout command again. Example: M=$(git show-ref -s --verify refs/heads/master) &&
git checkout -b <new_branch_name> test "z$H" = "z$M" &&
HEAD is now at 7329388... Initial A one, A two if git symbolic-ref HEAD >/dev/null 2>&1
EOF then
) && echo "OOPS, HEAD is still symbolic???"
test_cmp messages.expect messages && 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) && H=$(git rev-parse --verify HEAD) &&
M=$(git show-ref -s --verify refs/heads/master) && M=$(git show-ref -s --verify refs/heads/master) &&
test "z$H" = "z$M" && test "z$H" = "z$M" &&