@@ -609,14 +609,18 @@ static void check_blank_at_eof(mmfile_t *mf1, mmfile_t *mf2,
609609 ecbdata -> blank_at_eof_in_postimage = (at - l2 ) + 1 ;
610610}
611611
612- static void emit_line_0 (struct diff_options * o , const char * set , const char * reset ,
612+ static void emit_line_0 (struct diff_options * o ,
613+ const char * set , unsigned reverse , const char * reset ,
613614 int first , const char * line , int len )
614615{
615616 int has_trailing_newline , has_trailing_carriage_return ;
616617 int nofirst ;
617618 FILE * file = o -> file ;
618619
619- fputs (diff_line_prefix (o ), file );
620+ if (first )
621+ fputs (diff_line_prefix (o ), file );
622+ else if (!len )
623+ return ;
620624
621625 if (len == 0 ) {
622626 has_trailing_newline = (first == '\n' );
@@ -634,8 +638,10 @@ static void emit_line_0(struct diff_options *o, const char *set, const char *res
634638 }
635639
636640 if (len || !nofirst ) {
641+ if (reverse && want_color (o -> use_color ))
642+ fputs (GIT_COLOR_REVERSE , file );
637643 fputs (set , file );
638- if (!nofirst )
644+ if (first && !nofirst )
639645 fputc (first , file );
640646 fwrite (line , len , 1 , file );
641647 fputs (reset , file );
@@ -649,7 +655,7 @@ static void emit_line_0(struct diff_options *o, const char *set, const char *res
649655static void emit_line (struct diff_options * o , const char * set , const char * reset ,
650656 const char * line , int len )
651657{
652- emit_line_0 (o , set , reset , line [0 ], line + 1 , len - 1 );
658+ emit_line_0 (o , set , 0 , reset , line [0 ], line + 1 , len - 1 );
653659}
654660
655661enum diff_symbol {
@@ -1168,7 +1174,8 @@ static void dim_moved_lines(struct diff_options *o)
11681174
11691175static void emit_line_ws_markup (struct diff_options * o ,
11701176 const char * set , const char * reset ,
1171- const char * line , int len , char sign ,
1177+ const char * line , int len ,
1178+ const char * set_sign , char sign ,
11721179 unsigned ws_rule , int blank_at_eof )
11731180{
11741181 const char * ws = NULL ;
@@ -1179,14 +1186,20 @@ static void emit_line_ws_markup(struct diff_options *o,
11791186 ws = NULL ;
11801187 }
11811188
1182- if (!ws )
1183- emit_line_0 (o , set , reset , sign , line , len );
1184- else if (blank_at_eof )
1189+ if (!ws && !set_sign )
1190+ emit_line_0 (o , set , 0 , reset , sign , line , len );
1191+ else if (!ws ) {
1192+ /* Emit just the prefix, then the rest. */
1193+ emit_line_0 (o , set_sign ? set_sign : set , !!set_sign , reset ,
1194+ sign , "" , 0 );
1195+ emit_line_0 (o , set , 0 , reset , 0 , line , len );
1196+ } else if (blank_at_eof )
11851197 /* Blank line at EOF - paint '+' as well */
1186- emit_line_0 (o , ws , reset , sign , line , len );
1198+ emit_line_0 (o , ws , 0 , reset , sign , line , len );
11871199 else {
11881200 /* Emit just the prefix, then the rest. */
1189- emit_line_0 (o , set , reset , sign , "" , 0 );
1201+ emit_line_0 (o , set_sign ? set_sign : set , !!set_sign , reset ,
1202+ sign , "" , 0 );
11901203 ws_check_emit (line , len , ws_rule ,
11911204 o -> file , set , reset , ws );
11921205 }
@@ -1196,7 +1209,7 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
11961209 struct emitted_diff_symbol * eds )
11971210{
11981211 static const char * nneof = " No newline at end of file\n" ;
1199- const char * context , * reset , * set , * meta , * fraginfo ;
1212+ const char * context , * reset , * set , * set_sign , * meta , * fraginfo ;
12001213 struct strbuf sb = STRBUF_INIT ;
12011214
12021215 enum diff_symbol s = eds -> s ;
@@ -1209,7 +1222,7 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
12091222 context = diff_get_color_opt (o , DIFF_CONTEXT );
12101223 reset = diff_get_color_opt (o , DIFF_RESET );
12111224 putc ('\n' , o -> file );
1212- emit_line_0 (o , context , reset , '\\' ,
1225+ emit_line_0 (o , context , 0 , reset , '\\' ,
12131226 nneof , strlen (nneof ));
12141227 break ;
12151228 case DIFF_SYMBOL_SUBMODULE_HEADER :
@@ -1236,7 +1249,18 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
12361249 case DIFF_SYMBOL_CONTEXT :
12371250 set = diff_get_color_opt (o , DIFF_CONTEXT );
12381251 reset = diff_get_color_opt (o , DIFF_RESET );
1239- emit_line_ws_markup (o , set , reset , line , len , ' ' ,
1252+ set_sign = NULL ;
1253+ if (o -> flags .dual_color_diffed_diffs ) {
1254+ char c = !len ? 0 : line [0 ];
1255+
1256+ if (c == '+' )
1257+ set = diff_get_color_opt (o , DIFF_FILE_NEW );
1258+ else if (c == '@' )
1259+ set = diff_get_color_opt (o , DIFF_FRAGINFO );
1260+ else if (c == '-' )
1261+ set = diff_get_color_opt (o , DIFF_FILE_OLD );
1262+ }
1263+ emit_line_ws_markup (o , set , reset , line , len , set_sign , ' ' ,
12401264 flags & (DIFF_SYMBOL_CONTENT_WS_MASK ), 0 );
12411265 break ;
12421266 case DIFF_SYMBOL_PLUS :
@@ -1263,7 +1287,20 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
12631287 set = diff_get_color_opt (o , DIFF_FILE_NEW );
12641288 }
12651289 reset = diff_get_color_opt (o , DIFF_RESET );
1266- emit_line_ws_markup (o , set , reset , line , len , '+' ,
1290+ if (!o -> flags .dual_color_diffed_diffs )
1291+ set_sign = NULL ;
1292+ else {
1293+ char c = !len ? 0 : line [0 ];
1294+
1295+ set_sign = set ;
1296+ if (c == '-' )
1297+ set = diff_get_color_opt (o , DIFF_FILE_OLD );
1298+ else if (c == '@' )
1299+ set = diff_get_color_opt (o , DIFF_FRAGINFO );
1300+ else if (c != '+' )
1301+ set = diff_get_color_opt (o , DIFF_CONTEXT );
1302+ }
1303+ emit_line_ws_markup (o , set , reset , line , len , set_sign , '+' ,
12671304 flags & DIFF_SYMBOL_CONTENT_WS_MASK ,
12681305 flags & DIFF_SYMBOL_CONTENT_BLANK_LINE_EOF );
12691306 break ;
@@ -1291,7 +1328,20 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
12911328 set = diff_get_color_opt (o , DIFF_FILE_OLD );
12921329 }
12931330 reset = diff_get_color_opt (o , DIFF_RESET );
1294- emit_line_ws_markup (o , set , reset , line , len , '-' ,
1331+ if (!o -> flags .dual_color_diffed_diffs )
1332+ set_sign = NULL ;
1333+ else {
1334+ char c = !len ? 0 : line [0 ];
1335+
1336+ set_sign = set ;
1337+ if (c == '+' )
1338+ set = diff_get_color_opt (o , DIFF_FILE_NEW );
1339+ else if (c == '@' )
1340+ set = diff_get_color_opt (o , DIFF_FRAGINFO );
1341+ else if (c != '-' )
1342+ set = diff_get_color_opt (o , DIFF_CONTEXT );
1343+ }
1344+ emit_line_ws_markup (o , set , reset , line , len , set_sign , '-' ,
12951345 flags & DIFF_SYMBOL_CONTENT_WS_MASK , 0 );
12961346 break ;
12971347 case DIFF_SYMBOL_WORDS_PORCELAIN :
@@ -1482,6 +1532,7 @@ static void emit_hunk_header(struct emit_callback *ecbdata,
14821532 const char * frag = diff_get_color (ecbdata -> color_diff , DIFF_FRAGINFO );
14831533 const char * func = diff_get_color (ecbdata -> color_diff , DIFF_FUNCINFO );
14841534 const char * reset = diff_get_color (ecbdata -> color_diff , DIFF_RESET );
1535+ const char * reverse = ecbdata -> color_diff ? GIT_COLOR_REVERSE : "" ;
14851536 static const char atat [2 ] = { '@' , '@' };
14861537 const char * cp , * ep ;
14871538 struct strbuf msgbuf = STRBUF_INIT ;
@@ -1502,6 +1553,8 @@ static void emit_hunk_header(struct emit_callback *ecbdata,
15021553 ep += 2 ; /* skip over @@ */
15031554
15041555 /* The hunk header in fraginfo color */
1556+ if (ecbdata -> opt -> flags .dual_color_diffed_diffs )
1557+ strbuf_addstr (& msgbuf , reverse );
15051558 strbuf_addstr (& msgbuf , frag );
15061559 strbuf_add (& msgbuf , line , ep - line );
15071560 strbuf_addstr (& msgbuf , reset );
0 commit comments