7
7
#include "reflog-walk.h"
8
8
#include "refs.h"
9
9
#include "string-list.h"
10
+ #include "color.h"
10
11
11
12
struct decoration name_decoration = { "object names" };
12
13
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 )
14
83
{
15
- int plen = strlen (prefix );
16
84
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 ;
20
88
res -> next = add_decoration (& name_decoration , obj , res );
21
89
}
22
90
23
91
static int add_ref_decoration (const char * refname , const unsigned char * sha1 , int flags , void * cb_data )
24
92
{
25
93
struct object * obj = parse_object (sha1 );
94
+ enum decoration_type type = DECORATION_NONE ;
26
95
if (!obj )
27
96
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
+
28
109
if (!cb_data || * (int * )cb_data == DECORATE_SHORT_REFS )
29
110
refname = prettify_refname (refname );
30
- add_name_decoration ("" , refname , obj );
111
+ add_name_decoration (type , refname , obj );
31
112
while (obj -> type == OBJ_TAG ) {
32
113
obj = ((struct tag * )obj )-> tagged ;
33
114
if (!obj )
34
115
break ;
35
- add_name_decoration ("tag: " , refname , obj );
116
+ add_name_decoration (DECORATION_REF_TAG , refname , obj );
36
117
}
37
118
return 0 ;
38
119
}
@@ -60,6 +141,10 @@ void show_decorations(struct rev_info *opt, struct commit *commit)
60
141
{
61
142
const char * prefix ;
62
143
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 );
63
148
64
149
if (opt -> show_source && commit -> util )
65
150
printf ("\t%s" , (char * ) commit -> util );
@@ -70,7 +155,14 @@ void show_decorations(struct rev_info *opt, struct commit *commit)
70
155
return ;
71
156
prefix = " (" ;
72
157
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 );
74
166
prefix = ", " ;
75
167
decoration = decoration -> next ;
76
168
}
0 commit comments