git diff與linux diff的輸出格式之unified format
前言
前面有一篇文章《一個有些意思的項目–文件夾對比工具(一)》,裏面簡單講了下diff算法之–Myers算法。
既然是算法,就會有實現,比如git diff中有Myers的實現,git diff默認就是用了這個算法(也可以選擇其他算法);這個Myers算法,在linux的diff工具中也有實現;或者在一些js庫、java庫等都有實現。
另外,既然是算法,那就有輸入和輸出,如果大家都正確實現的話,按理說輸出格式也是能達成統一的。
接下來我們就看一下在各個軟件中的輸出格式。
git diff 輸出格式
樣例文件
附原文件內容,有興趣可以跟着試試。
1111111111111111
2222222
333333333333333
4444444444444444444
55555555555
666666666
1111111111111111
2222222
333333333333333
4444444448878784444444444
insert1
55555555555
insert2
666666666
insert3
輸出格式
之前我以為只能在版本間對比文件差異,原來文件也是可以直接對比的,如下:
git diff test.txt test2.txt
這裡可以看到,輸出中還包含了一些兩側沒變動的行,這是怎麼回事呢?主要是,默認情況下,會輸出差異行的上下文(即差異行的前面幾行和後面幾行,默認是三行)。
為了方便我們對比差異,我們先開啟一個選項,不展示上下文。
-U
–unified=
Generate diffs with
lines of context instead of the usual three. Implies --patch
.
開啟這個選項後,輸出如下:
我們看的裏面有很多奇怪的符號,看得似懂非懂的,還有一些數字,也不知道啥意思,我們暫且不表,接下來,看看linux diff工具的輸出。
linux diff輸出格式
樣例文件
同上。
輸出格式(-U選項)
-U選項,在linux diff文檔里,是這個意思,我們指定 -U 0,就是0行上下文。
-u, -U NUM, --unified[=NUM] output NUM (default 3) lines of unified context
看起來,格式差不太多哈,不過內容不太一樣,這個先不用管,大家雖然都是同一個算法,但是部分工具會使用該算法的變體,所以輸出有些不同也是正常。
先聚焦於輸出格式即可。
默認輸出格式(不帶各類選項)
看起來有點奇怪,輸出都沒有那些@@符號了,好像格式不同了,這是咋回事。
輸出格式(-c選項)
其實還有個選項,如下:
-c, -C NUM, --context[=NUM] output NUM (default 3) lines of copied context
這個看起來像是上下文之類的,我們測試下:
看上去和默認格式、-U格式都不同。
linux diff輸出的兩種格式(官方文檔)
具體內容都是來自於官方文檔://www.gnu.org/software/diffutils/manual/html_node/index.html
這裡提到了兩種格式:
-
Context Format,即-c選項時,這種對比文件時,感覺不是很直觀;主要的場景是,用diff來生成代碼補丁,代碼差異行上下有上下文,方便補丁程序patch來進行差異代碼定位。
The context output format shows several lines of context around the lines that differ. It is the standard format for distributing updates to source code.
-
Unified Format,即-u選項時,這種對比文件時,感覺還比較方便看;官方定義如下:
The unified output format is a variation on the context format that is more compact because it omits redundant context lines.
即該格式是context format的變體,因為省略了冗餘的上下文行,顯得更加緊湊。
unified format格式
簡介
不知道大家發現沒,git diff和linux diff(-u)時,產生的格式是一樣的,即unified format。
為什麼單獨講這個格式呢,因為我發現,有很多文件差異相關的第三方庫,不管是js、java啥的,產生的格式都是unified format。
而且,js中還有一個很廣泛的庫diff2html,是可以接收unified format格式的文件為輸入,渲染為美觀大方的html組件。
所以,在軟件生態來說,該格式已經是一個相對通用的交互格式了,類似於json、xml這樣的標準格式,所以,我們就講解它。
詳解
以如下輸出來舉例:
unified format一開始就是文件列表,就是上圖的:
--- a/test.txt
+++ b/test2.txt
接下來就是差異段列表了,上圖一共兩個差異段,有點看不懂?那我們再看看樣例文件在beyond compare中的對比效果。
以如下差異段來說:
@@ -4 +4,2 @@
-4444444444444444444
+4444444448878784444444444
+insert1
@@ 這一行,表示一個匯總信息,其中的-4,其實應該是-4,1。 “-“代表文件--- a/test.txt
,4代表第四行,test.txt的第4行,就是4444444444444444444
這一行,被省略的1,表示展示的text.txt從第4行開始的行的數量。
比如,4,2表示展示第4、5行,4,3表示展示第4、5、6行。
+4,2同理,”+”代表文件+++ a/test2.txt
,也就是展示4開頭的兩行,即第4、5行。
大家再看看這個圖,不知道是不是可以理解了:
另外,@@是header行,算是一個匯總信息,就像是一個協議包的包頭一樣,說明包的內容的長度等,或者像是http里的content-length字段。
接下來,就是具體的內容,
@@ -4 +4,2 @@
-4444444444444444444
+4444444448878784444444444
+insert1
比如,-4444444444444444444
的「-」不僅表示屬於文件text.txt
,還表示這行是要被刪除的。「+」也是同理,表示是要新增的行。
還有一種情況是,兩邊行相等(比如需要展示上下文的時候),這種時候的話,前綴就是一個空字符,「 」。
具體看下面:
//www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html
擴展資料:
//en.wikipedia.org/wiki/Diff#:~:text=The unified format (要會上網)
diff2html渲染unified format
之前提到unified format就是個中間格式,只要大家都按這個格式來,生態就建立起來了。
接下來,我們就把前面那個字符串用一個js庫:diff2html來渲染一下,看看效果。
先在js中定義個字面量diffString,再用diff2html這個js庫來渲染:
const diffString = `--- a/test.txt
+++ b/test2.txt
@@ -4 +4,2 @@
-4444444444444444444
+4444444448878784444444444
+insert1
@@ -6 +7,3 @@
-666666666
\ No newline at end of file
+insert2
+666666666
+insert3`;
document.addEventListener('DOMContentLoaded', function () {
const targetElement = document.getElementById('filesExistInBothDir');
const configuration = {
// 渲染文件列表
drawFileList: true,
// 文件列表顯示/隱藏的開關
fileListToggle: false,
// 默認展示文件列表
fileListStartVisible: false,
// 文件內容可收起/展開的開關
fileContentToggle: true,
matching: 'lines',
// 左右兩側雙欄展示
outputFormat: 'side-by-side',
// 雙欄展示模式時,拖動左邊的橫向滾動條,右側同步滾動
synchronisedScroll: true,
// 高亮代碼
highlight: true,
renderNothingWhenEmpty: true,
};
const diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration);
diff2htmlUi.draw();
diff2htmlUi.highlightCode();
效果如下:
html源文件上傳了,感興趣可以看看:
//dump-1252523945.cos.ap-shanghai.myqcloud.com/img/compare-result-162513.html