summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/config.txt5
-rw-r--r--advice.c2
-rw-r--r--advice.h1
-rw-r--r--builtin-checkout.c18
-rwxr-xr-xt/t7201-co.sh32
5 files changed, 46 insertions, 12 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 17901e244a..fee44d8a4a 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 936d98ba2b..0be4b5f008 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 9b7a3ad1ca..3244ebb5c1 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 527781728e..c5ab7835e1 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 6442f710be..d20ed61b48 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" &&