77#include "reflog-walk.h"
88#include "refs.h"
99#include "string-list.h"
10+ #include "color.h"
1011
1112struct decoration name_decoration = { "object names" };
1213
13- static void add_name_decoration (const char * prefix , const char * name , struct object * obj )
14+ enum decoration_type {
15+ DECORATION_NONE = 0 ,
16+ DECORATION_REF_LOCAL ,
17+ DECORATION_REF_REMOTE ,
18+ DECORATION_REF_TAG ,
19+ DECORATION_REF_STASH ,
20+ DECORATION_REF_HEAD ,
21+ };
22+
23+ static char decoration_colors [][COLOR_MAXLEN ] = {
24+ GIT_COLOR_RESET ,
25+ GIT_COLOR_BOLD_GREEN , /* REF_LOCAL */
26+ GIT_COLOR_BOLD_RED , /* REF_REMOTE */
27+ GIT_COLOR_BOLD_YELLOW , /* REF_TAG */
28+ GIT_COLOR_BOLD_MAGENTA , /* REF_STASH */
29+ GIT_COLOR_BOLD_CYAN , /* REF_HEAD */
30+ };
31+
32+ static const char * decorate_get_color (int decorate_use_color , enum decoration_type ix )
33+ {
34+ if (decorate_use_color )
35+ return decoration_colors [ix ];
36+ return "" ;
37+ }
38+
39+ static int parse_decorate_color_slot (const char * slot )
40+ {
41+ /*
42+ * We're comparing with 'ignore-case' on
43+ * (because config.c sets them all tolower),
44+ * but let's match the letters in the literal
45+ * string values here with how they are
46+ * documented in Documentation/config.txt, for
47+ * consistency.
48+ *
49+ * We love being consistent, don't we?
50+ */
51+ if (!strcasecmp (slot , "branch" ))
52+ return DECORATION_REF_LOCAL ;
53+ if (!strcasecmp (slot , "remoteBranch" ))
54+ return DECORATION_REF_REMOTE ;
55+ if (!strcasecmp (slot , "tag" ))
56+ return DECORATION_REF_TAG ;
57+ if (!strcasecmp (slot , "stash" ))
58+ return DECORATION_REF_STASH ;
59+ if (!strcasecmp (slot , "HEAD" ))
60+ return DECORATION_REF_HEAD ;
61+ return -1 ;
62+ }
63+
64+ int parse_decorate_color_config (const char * var , const int ofs , const char * value )
65+ {
66+ int slot = parse_decorate_color_slot (var + ofs );
67+ if (slot < 0 )
68+ return 0 ;
69+ if (!value )
70+ return config_error_nonbool (var );
71+ color_parse (value , var , decoration_colors [slot ]);
72+ return 0 ;
73+ }
74+
75+ /*
76+ * log-tree.c uses DIFF_OPT_TST for determining whether to use color
77+ * for showing the commit sha1, use the same check for --decorate
78+ */
79+ #define decorate_get_color_opt (o , ix ) \
80+ decorate_get_color(DIFF_OPT_TST((o), COLOR_DIFF), ix)
81+
82+ static void add_name_decoration (enum decoration_type type , const char * name , struct object * obj )
1483{
15- int plen = strlen (prefix );
1684 int nlen = strlen (name );
17- struct name_decoration * res = xmalloc (sizeof (struct name_decoration ) + plen + nlen );
18- memcpy (res -> name , prefix , plen );
19- memcpy ( res -> name + plen , name , nlen + 1 ) ;
85+ struct name_decoration * res = xmalloc (sizeof (struct name_decoration ) + nlen );
86+ memcpy (res -> name , name , nlen + 1 );
87+ res -> type = type ;
2088 res -> next = add_decoration (& name_decoration , obj , res );
2189}
2290
2391static int add_ref_decoration (const char * refname , const unsigned char * sha1 , int flags , void * cb_data )
2492{
2593 struct object * obj = parse_object (sha1 );
94+ enum decoration_type type = DECORATION_NONE ;
2695 if (!obj )
2796 return 0 ;
97+
98+ if (!prefixcmp (refname , "refs/heads" ))
99+ type = DECORATION_REF_LOCAL ;
100+ else if (!prefixcmp (refname , "refs/remotes" ))
101+ type = DECORATION_REF_REMOTE ;
102+ else if (!prefixcmp (refname , "refs/tags" ))
103+ type = DECORATION_REF_TAG ;
104+ else if (!prefixcmp (refname , "refs/stash" ))
105+ type = DECORATION_REF_STASH ;
106+ else if (!prefixcmp (refname , "HEAD" ))
107+ type = DECORATION_REF_HEAD ;
108+
28109 if (!cb_data || * (int * )cb_data == DECORATE_SHORT_REFS )
29110 refname = prettify_refname (refname );
30- add_name_decoration ("" , refname , obj );
111+ add_name_decoration (type , refname , obj );
31112 while (obj -> type == OBJ_TAG ) {
32113 obj = ((struct tag * )obj )-> tagged ;
33114 if (!obj )
34115 break ;
35- add_name_decoration ("tag: " , refname , obj );
116+ add_name_decoration (DECORATION_REF_TAG , refname , obj );
36117 }
37118 return 0 ;
38119}
@@ -60,6 +141,10 @@ void show_decorations(struct rev_info *opt, struct commit *commit)
60141{
61142 const char * prefix ;
62143 struct name_decoration * decoration ;
144+ const char * color_commit =
145+ diff_get_color_opt (& opt -> diffopt , DIFF_COMMIT );
146+ const char * color_reset =
147+ decorate_get_color_opt (& opt -> diffopt , DECORATION_NONE );
63148
64149 if (opt -> show_source && commit -> util )
65150 printf ("\t%s" , (char * ) commit -> util );
@@ -70,7 +155,14 @@ void show_decorations(struct rev_info *opt, struct commit *commit)
70155 return ;
71156 prefix = " (" ;
72157 while (decoration ) {
73- printf ("%s%s" , prefix , decoration -> name );
158+ printf ("%s" , prefix );
159+ fputs (decorate_get_color_opt (& opt -> diffopt , decoration -> type ),
160+ stdout );
161+ if (decoration -> type == DECORATION_REF_TAG )
162+ fputs ("tag: " , stdout );
163+ printf ("%s" , decoration -> name );
164+ fputs (color_reset , stdout );
165+ fputs (color_commit , stdout );
74166 prefix = ", " ;
75167 decoration = decoration -> next ;
76168 }
0 commit comments