字符级别的彩色diff

colordiff 只能高亮显示行级别的不同,如果需要高亮被修改的字符,需要使用其他工具,比如 diff-highlight ,有不同语言的版本,Python 版使用 pip3 install diff-highlight 来安装。此功能的效果就类似 Github,如图:

Github diff

命令行

通过以下命令在命令行高亮 diff 结果:

diff -u file1 file2 | diff-highlight

转存为HTML

通过以下脚本将 diff 结果保存到 HTML 文件中,方便查看。

#!/bin/bash
# Character-Level color diff

[ $# -lt 2 ] && echo "$0 file1 file2" && exit 1

DIFFTMP=$1-$2-diff.tmp
HTML=$1-$2-diff.html
type diff-highlight >/dev/null 2>&1 || { echo >&2 "Need diff-highlight installed. Please install it via pip3."; exit 1; }
diff -u $1 $2 |diff-highlight > $DIFFTMP

cat > $HTML <<EOF
<html>
<head>
<title>diff $1 $2</title>
<style type="text/css">
.del {background-color:#ffeef0;}
.add {background-color:#e6ffed;}
.del-word {background-color:#fdb8c0;}
.add-word {background-color:#acf2bd;}
.hunk {background-color:#f1f8ff;}
.code {
	position: relative;
    padding-right: 50px;
    padding-left: 50px;
    line-height: 25px;
    vertical-align: top;
	font-size: 18px;
}
pre {
	font-family: Source Code Pro,sans-serif;
}
</style>
</head>
</body>
<div class="code">
<h1> Diff for $1 and $2</h1>
<hr>
<pre>
EOF

cat $DIFFTMP | \
	sed 's/^\x1b\[32m/<span class="add">/g' | \
	sed 's/^\x1b\[31m/<span class="del">/g' | \
	sed 's/\x1b\[32m\x1b\[7m/<span class="add-word">/g' | \
	sed 's/\x1b\[31m\x1b\[7m/<span class="del-word">/g' | \
	sed 's/\x1b\[32m/<span class="add">/g' | \
	sed 's/\x1b\[31m/<span class="del">/g' | \
	sed 's/\x1b\[0m/<\/span>/g' | \
	sed -r 's/^@@(.*)$/<span class="hunk">@@\1<\/span>/g' \
	>> $HTML

cat >> $HTML <<EOF
</pre>
</div>
</body>
</html>
EOF

效果如图,和 Github 类似。

diff-highlight HTML

问题

在 msys2 上 diff-highlight(版本为1.2.0) 处理中文可能有问题,如下示例:

--- 1.md        2020-06-28 10:18:18.032559700 +0800
+++ 2.md        2020-06-28 10:18:15.740609300 +0800
@@ -1 +1 @@
-十进制字符串
+十进制浮点字符串

会被解析为:

diff-highlight 中文处理问题

中文 "" 的十六进制表示为 e588b6 ,"" 的十六进制表示为 e5ad97,可见 diff-highlight 错误的拆分了这两个字,导致出现乱码。但是在 Ubuntu 上同样版本的 diff-highlight 没有这个问题。

另外也可以考虑使用 git 里带的一个 Perl 版本的 diff-highlight,msys2 上路径为 /usr/share/git/diff-highlight,Ubuntu 上路径为 /usr/share/doc/git/contrib/diff-highlight,进入路径之后执行 make,生成 diff-highlight,移动到 /usr/bin 目录后即可使用。相比 Python 版本,在 msys2 上也能正确处理中文,和 Python 版本有一点差异,如下图:

Python 和 Perl 版本的 diff-highlight 差异

上面是 Python 版本,下面是 Perl 版本,个人更喜欢 Python 的处理结果,能更好的看出变更内容。

另外,如图所示,Perl 版本的还需要配合 colordiff 来使用。

参考资料

1. diff-highlight: https://stackoverflow.com/a/39878687
2. remove ^[: https://stackoverflow.com/a/6534712

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注