@@ -28,8 +28,9 @@ static const char * const builtin_branch_usage[] = {
28
28
NULL
29
29
};
30
30
31
- #define REF_LOCAL_BRANCH 0x01
32
- #define REF_REMOTE_BRANCH 0x02
31
+ #define REF_DETACHED_HEAD 0x01
32
+ #define REF_LOCAL_BRANCH 0x02
33
+ #define REF_REMOTE_BRANCH 0x04
33
34
34
35
static const char * head ;
35
36
static unsigned char head_sha1 [20 ];
@@ -352,8 +353,12 @@ static int append_ref(const char *refname, const struct object_id *oid, int flag
352
353
break ;
353
354
}
354
355
}
355
- if (ARRAY_SIZE (ref_kind ) <= i )
356
- return 0 ;
356
+ if (ARRAY_SIZE (ref_kind ) <= i ) {
357
+ if (!strcmp (refname , "HEAD" ))
358
+ kind = REF_DETACHED_HEAD ;
359
+ else
360
+ return 0 ;
361
+ }
357
362
358
363
/* Don't add types the caller doesn't want */
359
364
if ((kind & ref_list -> kinds ) == 0 )
@@ -535,6 +540,8 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
535
540
int color ;
536
541
struct strbuf out = STRBUF_INIT , name = STRBUF_INIT ;
537
542
const char * prefix = "" ;
543
+ const char * desc = item -> name ;
544
+ char * to_free = NULL ;
538
545
539
546
if (item -> ignore )
540
547
return ;
@@ -547,6 +554,10 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
547
554
color = BRANCH_COLOR_REMOTE ;
548
555
prefix = remote_prefix ;
549
556
break ;
557
+ case REF_DETACHED_HEAD :
558
+ color = BRANCH_COLOR_CURRENT ;
559
+ desc = to_free = get_head_description ();
560
+ break ;
550
561
default :
551
562
color = BRANCH_COLOR_PLAIN ;
552
563
break ;
@@ -558,7 +569,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
558
569
color = BRANCH_COLOR_CURRENT ;
559
570
}
560
571
561
- strbuf_addf (& name , "%s%s" , prefix , item -> name );
572
+ strbuf_addf (& name , "%s%s" , prefix , desc );
562
573
if (verbose ) {
563
574
int utf8_compensation = strlen (name .buf ) - utf8_strwidth (name .buf );
564
575
strbuf_addf (& out , "%c %s%-*s%s" , c , branch_get_color (color ),
@@ -581,6 +592,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
581
592
}
582
593
strbuf_release (& name );
583
594
strbuf_release (& out );
595
+ free (to_free );
584
596
}
585
597
586
598
static int calc_maxwidth (struct ref_list * refs , int remote_bonus )
@@ -601,22 +613,6 @@ static int calc_maxwidth(struct ref_list *refs, int remote_bonus)
601
613
return max ;
602
614
}
603
615
604
- static void show_detached (struct ref_list * ref_list , int maxwidth )
605
- {
606
- struct commit * head_commit = lookup_commit_reference_gently (head_sha1 , 1 );
607
-
608
- if (head_commit && is_descendant_of (head_commit , ref_list -> with_commit )) {
609
- struct ref_item item ;
610
- item .name = get_head_description ();
611
- item .kind = REF_LOCAL_BRANCH ;
612
- item .dest = NULL ;
613
- item .commit = head_commit ;
614
- item .ignore = 0 ;
615
- print_ref_item (& item , maxwidth , ref_list -> verbose , ref_list -> abbrev , 1 , "" );
616
- free (item .name );
617
- }
618
- }
619
-
620
616
static int print_ref_list (int kinds , int detached , int verbose , int abbrev , struct commit_list * with_commit , const char * * pattern )
621
617
{
622
618
int i ;
@@ -643,7 +639,14 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
643
639
cb .ref_list = & ref_list ;
644
640
cb .pattern = pattern ;
645
641
cb .ret = 0 ;
642
+ /*
643
+ * First we obtain all regular branch refs and if the HEAD is
644
+ * detached then we insert that ref to the end of the ref_fist
645
+ * so that it can be printed and removed first.
646
+ */
646
647
for_each_rawref (append_ref , & cb );
648
+ if (detached )
649
+ head_ref (append_ref , & cb );
647
650
/*
648
651
* The following implementation is currently duplicated in ref-filter. It
649
652
* will eventually be removed when we port branch.c to use ref-filter APIs.
@@ -681,14 +684,12 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
681
684
682
685
qsort (ref_list .list , ref_list .index , sizeof (struct ref_item ), ref_cmp );
683
686
684
- detached = (detached && (kinds & REF_LOCAL_BRANCH ));
685
- if (detached && match_patterns (pattern , "HEAD" ))
686
- show_detached (& ref_list , maxwidth );
687
-
688
687
for (i = 0 ; i < ref_list .index ; i ++ ) {
689
- int current = !detached &&
690
- (ref_list .list [i ].kind == REF_LOCAL_BRANCH ) &&
688
+ int current = !detached && (ref_list .list [i ].kind == REF_LOCAL_BRANCH ) &&
691
689
!strcmp (ref_list .list [i ].name , head );
690
+ /* If detached the first ref_item is the current ref */
691
+ if (detached && i == 0 )
692
+ current = 1 ;
692
693
print_ref_item (& ref_list .list [i ], maxwidth , verbose ,
693
694
abbrev , current , remote_prefix );
694
695
}
@@ -914,7 +915,11 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
914
915
die (_ ("branch name required" ));
915
916
return delete_branches (argc , argv , delete > 1 , kinds , quiet );
916
917
} else if (list ) {
917
- int ret = print_ref_list (kinds , detached , verbose , abbrev ,
918
+ int ret ;
919
+ /* git branch --local also shows HEAD when it is detached */
920
+ if (kinds & REF_LOCAL_BRANCH )
921
+ kinds |= REF_DETACHED_HEAD ;
922
+ ret = print_ref_list (kinds , detached , verbose , abbrev ,
918
923
with_commit , argv );
919
924
print_columns (& output , colopts , NULL );
920
925
string_list_clear (& output , 0 );
0 commit comments