diff options
author | Alex Henrie <alexhenrie24@gmail.com> | 2022-02-25 23:12:13 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2022-02-25 22:21:48 -0800 |
commit | 808213ba36ea72408cc45117a825ad9a714535ba (patch) | |
tree | 46ce0e0ac916122d22dfe7ddd552c36beff5714d | |
parent | dab1b7905d0b295f1acef9785bb2b9cbb0fdec84 (diff) | |
download | git-808213ba36ea72408cc45117a825ad9a714535ba.tar.gz |
switch: mention the --detach option when dying due to lack of a branch
Users who are accustomed to doing `git checkout <tag>` assume that
`git switch <tag>` will do the same thing. Inform them of the --detach
option so they aren't left wondering why `git switch` doesn't work but
`git checkout` does.
Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | Documentation/config/advice.txt | 3 | ||||
-rw-r--r-- | advice.c | 1 | ||||
-rw-r--r-- | advice.h | 1 | ||||
-rw-r--r-- | builtin/checkout.c | 30 | ||||
-rwxr-xr-x | t/t2060-switch.sh | 11 |
5 files changed, 35 insertions, 11 deletions
diff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt index adee26fbbb..c40eb09cb7 100644 --- a/Documentation/config/advice.txt +++ b/Documentation/config/advice.txt @@ -85,6 +85,9 @@ advice.*:: linkgit:git-switch[1] or linkgit:git-checkout[1] to move to the detach HEAD state, to instruct how to create a local branch after the fact. + suggestDetachingHead:: + Advice shown when linkgit:git-switch[1] refuses to detach HEAD + without the explicit `--detach` option. checkoutAmbiguousRemoteBranchName:: Advice shown when the argument to linkgit:git-checkout[1] and linkgit:git-switch[1] @@ -42,6 +42,7 @@ static struct { [ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] = { "checkoutAmbiguousRemoteBranchName", 1 }, [ADVICE_COMMIT_BEFORE_MERGE] = { "commitBeforeMerge", 1 }, [ADVICE_DETACHED_HEAD] = { "detachedHead", 1 }, + [ADVICE_SUGGEST_DETACHING_HEAD] = { "suggestDetachingHead", 1 }, [ADVICE_FETCH_SHOW_FORCED_UPDATES] = { "fetchShowForcedUpdates", 1 }, [ADVICE_GRAFT_FILE_DEPRECATED] = { "graftFileDeprecated", 1 }, [ADVICE_IGNORED_HOOK] = { "ignoredHook", 1 }, @@ -20,6 +20,7 @@ struct string_list; ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME, ADVICE_COMMIT_BEFORE_MERGE, ADVICE_DETACHED_HEAD, + ADVICE_SUGGEST_DETACHING_HEAD, ADVICE_FETCH_SHOW_FORCED_UPDATES, ADVICE_GRAFT_FILE_DEPRECATED, ADVICE_IGNORED_HOOK, diff --git a/builtin/checkout.c b/builtin/checkout.c index d9b31bbb6d..9244827ca0 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -1397,23 +1397,31 @@ static void die_expecting_a_branch(const struct branch_info *branch_info) { struct object_id oid; char *to_free; + int code; if (dwim_ref(branch_info->name, strlen(branch_info->name), &oid, &to_free, 0) == 1) { const char *ref = to_free; if (skip_prefix(ref, "refs/tags/", &ref)) - die(_("a branch is expected, got tag '%s'"), ref); - if (skip_prefix(ref, "refs/remotes/", &ref)) - die(_("a branch is expected, got remote branch '%s'"), ref); - die(_("a branch is expected, got '%s'"), ref); + code = die_message(_("a branch is expected, got tag '%s'"), ref); + else if (skip_prefix(ref, "refs/remotes/", &ref)) + code = die_message(_("a branch is expected, got remote branch '%s'"), ref); + else + code = die_message(_("a branch is expected, got '%s'"), ref); } - if (branch_info->commit) - die(_("a branch is expected, got commit '%s'"), branch_info->name); - /* - * This case should never happen because we already die() on - * non-commit, but just in case. - */ - die(_("a branch is expected, got '%s'"), branch_info->name); + else if (branch_info->commit) + code = die_message(_("a branch is expected, got commit '%s'"), branch_info->name); + else + /* + * This case should never happen because we already die() on + * non-commit, but just in case. + */ + code = die_message(_("a branch is expected, got '%s'"), branch_info->name); + + if (advice_enabled(ADVICE_SUGGEST_DETACHING_HEAD)) + advise(_("If you want to detach HEAD at the commit, try again with the --detach option.")); + + exit(code); } static void die_if_some_operation_in_progress(void) diff --git a/t/t2060-switch.sh b/t/t2060-switch.sh index ebb961be29..5a7caf958c 100755 --- a/t/t2060-switch.sh +++ b/t/t2060-switch.sh @@ -32,6 +32,17 @@ test_expect_success 'switch and detach' ' test_must_fail git symbolic-ref HEAD ' +test_expect_success 'suggestion to detach' ' + test_must_fail git switch main^{commit} 2>stderr && + grep "try again with the --detach option" stderr +' + +test_expect_success 'suggestion to detach is suppressed with advice.suggestDetachingHead=false' ' + test_config advice.suggestDetachingHead false && + test_must_fail git switch main^{commit} 2>stderr && + ! grep "try again with the --detach option" stderr +' + test_expect_success 'switch and detach current branch' ' test_when_finished git switch main && git switch main && |