讓 mercurial 使用基於字的版本比較

Dwdiff 是一個基於字 (word) 的命令行差異比較軟體。

1.jpg

dwdiff 基於字的比較結果

2.png

▲ 傳統 diff (基於行)的比較結果

……挺有趣的吧!


某些時候--比方說寫小說的時候--每一行的長度都長得叫人髮指,diff 的輸出根本沒有參考價值,這時就可以拿 dwdiff 來用。重要的是,dwdiff 還支援自訂分隔符號,因此不只是用空白分隔的英文,就連中文也可以派上用場,只要把各種標點符號設為分隔符號就成了。

關於安裝也很簡單:如果在 debian 系環境下,只要 sudo apt-get install dwdiff 就能把 dwdiff 裝好。

另一方面,Mercurial 也有著 extdiff 插件,這個插件可以援用各種外部工具取代內建的 diff 指令。這太好了,忍不住手賤想說要如何把這兩隻程式聚合起來。

廢話不多說,請將下面這坨東西貼入 .hgrc 中。

[extdiff]
dwdiff =
delimiter=',、。!?;「」().,()[]{}<>=-+*/\\:;?\\"';
cmd="dwdiff -L -c -C4 -d \""{$delimiter}"\"";
echo "";
if [ -d $parent ]; then
LANG=C diff -qr $parent $child |
awk '$0 ~ /^File/{print $2}' |
xargs file |
grep text |
awk '{sub(/:$/, "", $1); print $1}' |
awk '{str1=$0;
sub(/^$parent/, " $child", str1);
print $0 " " str1}' |
sort |
awk -v cmd="$cmd" \
'{print "### dwdiff ------\n " $1 " --> " $2 "\n";
system(cmd " " $0);
print "";}';
else
echo "### dwdiff ------\n" $parent " --> " $child "\n"
$cmd $parent $child;
echo ""
fi

上面程式碼會這麼一大堆,主要是因為 dwdiff 不允許作用在資料夾上,只能運行在檔案層級,而 diff 指令無論資料夾或檔案路徑都雙雙接受。因此,依照需要 diff 的檔案數量不同,mercurial 也有可能會傳來檔案路徑或資料夾路徑。故必須寫個 if else 適配器來將輸入重整為 dwdiff 可接受的形式。

然後就可以如同使用 hg diff 那般,用 hg dwdiff 爽爽用了。