branch: show more information when HEAD is detached

This prints more helpful info when HEAD is detached: is it detached because of bisect or rebase? What is the original branch name in those cases? Is it detached because the user checks out a remote ref or a tag (and which one)? Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Mar 13, 2013 at 18:42 UTC c8183cd2851965665655738fc399c44f546d5b79
3 files changed +29 -5
builtin/branch.c
+25 -1
@@ -18,6 +18,7 @@
18 #include "string-list.h"
19 #include "column.h"
20 #include "utf8.h"
21 +#include "wt-status.h"
22
23 static const char * const builtin_branch_usage[] = {
24 N_("git branch [options] [-r | -a] [--merged | --no-merged]"),
@@ -550,6 +551,29 @@ static int calc_maxwidth(struct ref_list *refs)
551 return w;
552 }
553
554 +static char *get_head_description(void)
555 +{
556 + struct strbuf desc = STRBUF_INIT;
557 + struct wt_status_state state;
558 + memset(&state, 0, sizeof(state));
559 + wt_status_get_state(&state, 1);
560 + if (state.rebase_in_progress ||
561 + state.rebase_interactive_in_progress)
562 + strbuf_addf(&desc, _("(no branch, rebasing %s)"),
563 + state.branch);
564 + else if (state.bisect_in_progress)
565 + strbuf_addf(&desc, _("(no branch, bisecting %s)"),
566 + state.branch);
567 + else if (state.detached_from)
568 + strbuf_addf(&desc, _("(detached from %s)"),
569 + state.detached_from);
570 + else
571 + strbuf_addstr(&desc, _("(no branch)"));
572 + free(state.branch);
573 + free(state.onto);
574 + free(state.detached_from);
575 + return strbuf_detach(&desc, NULL);
576 +}
577
578 static void show_detached(struct ref_list *ref_list)
579 {
@@ -557,7 +581,7 @@ static void show_detached(struct ref_list *ref_list)
581
582 if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) {
583 struct ref_item item;
560 - item.name = xstrdup(_("(no branch)"));
584 + item.name = get_head_description();
585 item.width = utf8_strwidth(item.name);
586 item.kind = REF_LOCAL_BRANCH;
587 item.dest = NULL;
t/t3203-branch-output.sh
+3 -3
@@ -94,13 +94,13 @@ test_expect_success 'git branch -v pattern does not show branch summaries' '
94 test_must_fail git branch -v branch*
95 '
96
97 -cat >expect <<'EOF'
98 -* (no branch)
97 +test_expect_success 'git branch shows detached HEAD properly' '
98 + cat >expect <<EOF &&
99 +* (detached from $(git rev-parse --short HEAD^0))
100 branch-one
101 branch-two
102 master
103 EOF
103 -test_expect_success 'git branch shows detached HEAD properly' '
104 git checkout HEAD^0 &&
105 git branch >actual &&
106 test_i18ncmp expect actual
t/t6030-bisect-porcelain.sh
+1 -1
@@ -164,7 +164,7 @@ test_expect_success 'bisect start: existing ".git/BISECT_START" not modified if
164 cp .git/BISECT_START saved &&
165 test_must_fail git bisect start $HASH4 foo -- &&
166 git branch > branch.output &&
167 - test_i18ngrep "* (no branch)" branch.output > /dev/null &&
167 + test_i18ngrep "* (no branch, bisecting other)" branch.output > /dev/null &&
168 test_cmp saved .git/BISECT_START
169 '
170 test_expect_success 'bisect start: no ".git/BISECT_START" if mistaken rev' '