Skip to content

Commit 8744cef

Browse files
committed
Merge branch 'jk/diff-highlight-more'
Various updates to contrib/diff-highlight, including documentation updates, test improvements, and color configuration handling. * jk/diff-highlight-more: diff-highlight: fetch all config with one process diff-highlight: allow module callers to pass in color config diff-highlight: test color config diff-highlight: use test_decode_color in tests t: add matching negative attributes to test_decode_color diff-highlight: check diff-highlight exit status in tests diff-highlight: drop perl version dependency back to 5.8 diff-highlight: mention build instructions
2 parents 0a39ec2 + 6689a6e commit 8744cef

4 files changed

Lines changed: 112 additions & 36 deletions

File tree

contrib/diff-highlight/DiffHighlight.pm

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package DiffHighlight;
22

3-
require v5.26;
3+
require v5.008;
44
use warnings FATAL => 'all';
55
use strict;
66

@@ -9,18 +9,11 @@ use File::Spec;
99

1010
my $NULL = File::Spec->devnull();
1111

12-
# Highlight by reversing foreground and background. You could do
13-
# other things like bold or underline if you prefer.
14-
my @OLD_HIGHLIGHT = (
15-
color_config('color.diff-highlight.oldnormal'),
16-
color_config('color.diff-highlight.oldhighlight', "\x1b[7m"),
17-
color_config('color.diff-highlight.oldreset', "\x1b[27m")
18-
);
19-
my @NEW_HIGHLIGHT = (
20-
color_config('color.diff-highlight.newnormal', $OLD_HIGHLIGHT[0]),
21-
color_config('color.diff-highlight.newhighlight', $OLD_HIGHLIGHT[1]),
22-
color_config('color.diff-highlight.newreset', $OLD_HIGHLIGHT[2])
23-
);
12+
# The color theme is initially set to nothing here to allow outside callers
13+
# to set the colors for their application. If nothing is sent in we use
14+
# colors from git config in load_color_config().
15+
our @OLD_HIGHLIGHT = ();
16+
our @NEW_HIGHLIGHT = ();
2417

2518
my $RESET = "\x1b[m";
2619
my $COLOR = qr/\x1b\[[0-9;]*m/;
@@ -138,9 +131,21 @@ sub highlight_stdin {
138131
# of it being used in other settings. Let's handle our own
139132
# fallback, which means we will work even if git can't be run.
140133
sub color_config {
134+
our $cached_config;
141135
my ($key, $default) = @_;
142-
my $s = `git config --get-color $key 2>$NULL`;
143-
return length($s) ? $s : $default;
136+
137+
if (!defined $cached_config) {
138+
$cached_config = {};
139+
my $data = `git config --type=color --get-regexp '^color\.diff-highlight\.' 2>$NULL`;
140+
for my $line (split /\n/, $data) {
141+
my ($key, $color) = split ' ', $line, 2;
142+
$key =~ s/^color\.diff-highlight\.// or next;
143+
$cached_config->{$key} = $color;
144+
}
145+
}
146+
147+
my $s = $cached_config->{$key};
148+
return defined($s) ? $s : $default;
144149
}
145150

146151
sub show_hunk {
@@ -170,6 +175,29 @@ sub show_hunk {
170175
$line_cb->(@queue);
171176
}
172177

178+
sub load_color_config {
179+
# If the colors were NOT set from outside this module we load them on-demand
180+
# from the git config. Note that only one of elements 0 and 2 in each
181+
# array is used (depending on whether you are doing set/unset on an
182+
# attribute, or specifying normal vs highlighted coloring). So we use
183+
# element 1 as our check for whether colors were passed in; it should
184+
# always be set if you want highlighting to do anything.
185+
if (!defined $OLD_HIGHLIGHT[1]) {
186+
@OLD_HIGHLIGHT = (
187+
color_config('oldnormal'),
188+
color_config('oldhighlight', "\x1b[7m"),
189+
color_config('oldreset', "\x1b[27m")
190+
);
191+
}
192+
if (!defined $NEW_HIGHLIGHT[1]) {
193+
@NEW_HIGHLIGHT = (
194+
color_config('newnormal', $OLD_HIGHLIGHT[0]),
195+
color_config('newhighlight', $OLD_HIGHLIGHT[1]),
196+
color_config('newreset', $OLD_HIGHLIGHT[2])
197+
);
198+
};
199+
}
200+
173201
sub highlight_pair {
174202
my @a = split_line(shift);
175203
my @b = split_line(shift);
@@ -218,6 +246,7 @@ sub highlight_pair {
218246
}
219247

220248
if (is_pair_interesting(\@a, $pa, $sa, \@b, $pb, $sb)) {
249+
load_color_config();
221250
return highlight_line(\@a, $pa, $sa, \@OLD_HIGHLIGHT),
222251
highlight_line(\@b, $pb, $sb, \@NEW_HIGHLIGHT);
223252
}

contrib/diff-highlight/README

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,21 @@ visually distracting. Non-diff lines and existing diff coloration is
3939
preserved; the intent is that the output should look exactly the same as
4040
the input, except for the occasional highlight.
4141

42+
Build/Install
43+
-------------
44+
45+
You can build the `diff-highlight` script by running `make` from within
46+
the diff-highlight directory. There is no `make install` target; you can
47+
copy the built script to your $PATH.
48+
49+
You can run diff-highlight's internal tests by running `make test`. Note
50+
that you must also build Git itself first (by running `make` from the
51+
top-level of the project).
52+
4253
Use
4354
---
4455

45-
You can try out the diff-highlight program with:
56+
You can try out the built diff-highlight program with:
4657

4758
---------------------------------------------
4859
git log -p --color | /path/to/diff-highlight
@@ -127,6 +138,12 @@ Your script may set up one or more of the following variables:
127138
processing a logical chunk of input). The default function flushes
128139
stdout.
129140

141+
- @DiffHighlight::OLD_HIGHLIGHT and @DiffHighlight::NEW_HIGHLIGHT - these
142+
arrays specify the normal, highlighted, and reset colors (in that order)
143+
for old/new lines. If unset, values will be retrieved by calling `git
144+
config` (see "Color Config" above). Note that these should be the literal
145+
color bytes (starting with an ANSI escape code), not color names.
146+
130147
The script may then feed lines, one at a time, to DiffHighlight::handle_line().
131148
When lines are done processing, they will be fed to $line_cb. Note that
132149
DiffHighlight may queue up many input lines (to analyze a whole hunk)

contrib/diff-highlight/t/t9400-diff-highlight.sh

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ TEST_OUTPUT_DIRECTORY=$(pwd)
77
TEST_DIRECTORY="$CURR_DIR"/../../../t
88
DIFF_HIGHLIGHT="$CURR_DIR"/../diff-highlight
99

10-
CW="$(printf "\033[7m")" # white
11-
CR="$(printf "\033[27m")" # reset
12-
1310
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master
1411
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
1512
. "$TEST_DIRECTORY"/test-lib.sh
@@ -41,8 +38,10 @@ dh_test () {
4138
git show >commit.raw
4239
} >/dev/null &&
4340

44-
"$DIFF_HIGHLIGHT" <diff.raw | test_strip_patch_header >diff.act &&
45-
"$DIFF_HIGHLIGHT" <commit.raw | test_strip_patch_header >commit.act &&
41+
"$DIFF_HIGHLIGHT" <diff.raw >diff.hi &&
42+
test_strip_patch_header <diff.hi | test_decode_color >diff.act &&
43+
"$DIFF_HIGHLIGHT" <commit.raw >commit.hi &&
44+
test_strip_patch_header <commit.hi | test_decode_color >commit.act &&
4645
test_cmp patch.exp diff.act &&
4746
test_cmp patch.exp commit.act
4847
}
@@ -124,8 +123,8 @@ test_expect_success 'diff-highlight highlights the beginning of a line' '
124123
dh_test a b <<-EOF
125124
@@ -1,3 +1,3 @@
126125
aaa
127-
-${CW}b${CR}bb
128-
+${CW}0${CR}bb
126+
-<REVERSE>b<NOREVERSE>bb
127+
+<REVERSE>0<NOREVERSE>bb
129128
ccc
130129
EOF
131130
'
@@ -146,8 +145,8 @@ test_expect_success 'diff-highlight highlights the end of a line' '
146145
dh_test a b <<-EOF
147146
@@ -1,3 +1,3 @@
148147
aaa
149-
-bb${CW}b${CR}
150-
+bb${CW}0${CR}
148+
-bb<REVERSE>b<NOREVERSE>
149+
+bb<REVERSE>0<NOREVERSE>
151150
ccc
152151
EOF
153152
'
@@ -168,8 +167,8 @@ test_expect_success 'diff-highlight highlights the middle of a line' '
168167
dh_test a b <<-EOF
169168
@@ -1,3 +1,3 @@
170169
aaa
171-
-b${CW}b${CR}b
172-
+b${CW}0${CR}b
170+
-b<REVERSE>b<NOREVERSE>b
171+
+b<REVERSE>0<NOREVERSE>b
173172
ccc
174173
EOF
175174
'
@@ -211,8 +210,8 @@ test_expect_failure 'diff-highlight highlights mismatched hunk size' '
211210
dh_test a b <<-EOF
212211
@@ -1,3 +1,3 @@
213212
aaa
214-
-b${CW}b${CR}b
215-
+b${CW}0${CR}b
213+
-b<REVERSE>b<NOREVERSE>b
214+
+b<REVERSE>0<NOREVERSE>b
216215
+ccc
217216
EOF
218217
'
@@ -230,8 +229,8 @@ test_expect_success 'diff-highlight treats multibyte utf-8 as a unit' '
230229
echo "unic${o_stroke}de" >b &&
231230
dh_test a b <<-EOF
232231
@@ -1 +1 @@
233-
-unic${CW}${o_accent}${CR}de
234-
+unic${CW}${o_stroke}${CR}de
232+
-unic<REVERSE>${o_accent}<NOREVERSE>de
233+
+unic<REVERSE>${o_stroke}<NOREVERSE>de
235234
EOF
236235
'
237236

@@ -248,8 +247,8 @@ test_expect_failure 'diff-highlight treats combining code points as a unit' '
248247
echo "unico${combine_circum}de" >b &&
249248
dh_test a b <<-EOF
250249
@@ -1 +1 @@
251-
-unic${CW}o${combine_accent}${CR}de
252-
+unic${CW}o${combine_circum}${CR}de
250+
-unic<REVERSE>o${combine_accent}<NOREVERSE>de
251+
+unic<REVERSE>o${combine_circum}<NOREVERSE>de
253252
EOF
254253
'
255254

@@ -331,12 +330,12 @@ test_expect_success 'diff-highlight handles --graph with leading dash' '
331330
+++ b/file
332331
@@ -1,3 +1,3 @@
333332
before
334-
-the ${CW}old${CR} line
335-
+the ${CW}new${CR} line
333+
-the <REVERSE>old<NOREVERSE> line
334+
+the <REVERSE>new<NOREVERSE> line
336335
-leading dash
337336
EOF
338337
git log --graph -p -1 | "$DIFF_HIGHLIGHT" >actual.raw &&
339-
trim_graph <actual.raw | sed -n "/^---/,\$p" >actual &&
338+
trim_graph <actual.raw | sed -n "/^---/,\$p" | test_decode_color >actual &&
340339
test_cmp expect actual
341340
'
342341

@@ -351,4 +350,32 @@ test_expect_success 'highlight diff that removes final newline' '
351350
EOF
352351
'
353352

353+
test_expect_success 'configure set/reset colors' '
354+
test_config color.diff-highlight.oldhighlight bold &&
355+
test_config color.diff-highlight.oldreset nobold &&
356+
test_config color.diff-highlight.newhighlight italic &&
357+
test_config color.diff-highlight.newreset noitalic &&
358+
echo "prefix a suffix" >a &&
359+
echo "prefix b suffix" >b &&
360+
dh_test a b <<-\EOF
361+
@@ -1 +1 @@
362+
-prefix <BOLD>a<NORMAL_INTENSITY> suffix
363+
+prefix <ITALIC>b<NOITALIC> suffix
364+
EOF
365+
'
366+
367+
test_expect_success 'configure normal/highlight colors' '
368+
test_config color.diff-highlight.oldnormal red &&
369+
test_config color.diff-highlight.oldhighlight magenta &&
370+
test_config color.diff-highlight.newnormal green &&
371+
test_config color.diff-highlight.newhighlight yellow &&
372+
echo "prefix a suffix" >a &&
373+
echo "prefix b suffix" >b &&
374+
dh_test a b <<-\EOF
375+
@@ -1 +1 @@
376+
<RED>-prefix <RESET><MAGENTA>a<RESET><RED> suffix<RESET>
377+
<GREEN>+prefix <RESET><YELLOW>b<RESET><GREEN> suffix<RESET>
378+
EOF
379+
'
380+
354381
test_done

t/test-lib-functions.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ test_decode_color () {
4848
if (n == 2) return "FAINT";
4949
if (n == 3) return "ITALIC";
5050
if (n == 7) return "REVERSE";
51+
if (n == 22) return "NORMAL_INTENSITY";
52+
if (n == 23) return "NOITALIC";
53+
if (n == 27) return "NOREVERSE";
5154
if (n == 30) return "BLACK";
5255
if (n == 31) return "RED";
5356
if (n == 32) return "GREEN";

0 commit comments

Comments
 (0)