diff是unix系統的乙個非常重要的工具程式。
它用來比較兩個文字檔案的差異,是**版本號管理的基石之中的乙個。你在命令列下,輸入:
$ diff 《變動前的檔案》 《變動後的檔案》diff就會告訴你,這兩個檔案有何差異。它的顯示結果不太好懂,以下我就來說明,怎樣讀懂diff。
一、diff的三種格式
因為歷史原因,diff有三種格式:
* 正常格式(normal diff)我們依次來看。* 上下文格式(context diff)
* 合併格式(unified diff)
二、演示樣例檔案
為了便於解說,先新建兩個演示樣例檔案。
第乙個檔案叫做f1,內容是每行乙個a,一共7行。
aaa第二個檔案叫做f2,改動f1而成,第4行變成b,其它不變。aaaa
aaa三、正常格式的diff如今對f1和f2進行比較:baa
a
$ diff f1 f2這時,diff就會顯示正常格式的結果:
4c4第一行是乙個提示,用來說明變動位置。< a
---> b
4c4它分成三個部分:前面的"4",表示f1的第4行有變化;中間的"c"表示變動的模式是內容改變(change),其它模式還有"新增"(a,代表addition)和"刪除"(d,代表deletion);後面的"4",表示變動後變成f2的第4行。
第二行分成兩個部分。
< a前面的小於號,表示要從f1其中去除該行(也就是第4行),後面的"a"表示該行的內容。
第三行用來切割f1和f2。
---第四行,類似於第二行。
> b前面的大於號表示f2新增了該行,後面的"b"表示該行的內容。
四、上下文格式的diff
上個世紀80年代初,加州大學伯克利分校推出bsd版本號的unix時,認為diff的顯示結果太簡單,最好增加上下文,便於了解發生的變動。因此,推出了上下文格式的diff。
它的用法是增加c引數(代表context)。
$ diff -c f1 f2顯示結果例如以下:
*** f1 2012-08-29 16:45:41.000000000 +0800這個結果分成四個部分。--- f2 2012-08-29 16:45:51.000000000 +0800
***************
*** 1,7 ****aa
a!aaa
a--- 1,7 ----aa
a!baa
a
第一部分的兩行,顯示兩個檔案的基本情況:檔名稱和時間資訊。
*** f1 2012-08-29 16:45:41.000000000 +0800"***"表示變動前的檔案,"---"表示變動後的檔案。--- f2 2012-08-29 16:45:51.000000000 +0800
第二部分是15個星號,將檔案的基本情況與變動內容切割開。
***************第三部分顯示變動前的檔案,即f1。
*** 1,7 ****aa這時不僅顯示發生變化的第4行,還顯示第4行的前面三行和後面三行,因此一共顯示7行。所以,前面的"*** 1,7 ****"就表示,從第1行開始連續7行。a!aaa
a
另外,檔案內容的每一行最前面,另乙個標記位。假設為空,表示該行無變化;假設是感嘆號(!),表示該行有修改;假設是減號(-),表示該行被刪除;假設是加號(+),表示該行為新增。
第四部分顯示變動後的檔案,即f2。
--- 1,7 ----aa除了變動行(第4行)以外,也是上下文各顯示三行,總共顯示7行。a!baa
a
五、合併格式的diff
假設兩個檔案相似度非常高,那麼上下文格式的diff,將顯示大量反覆的內容,非常浪費空間。2023年,gnu diff領先推出了"合併格式"的diff,將f1和f2的上下文合併在一起顯示。
它的用法是增加u引數(代表unified)。
$ diff -u f1 f2顯示結果例如以下:
--- f1 2012-08-29 16:45:41.000000000 +0800它的第一部分,也是檔案的基本資訊。+++ f2 2012-08-29 16:45:51.000000000 +0800
@@ -1,7 +1,7 @@aa
a-a+ba
aa
--- f1 2012-08-29 16:45:41.000000000 +0800"---"表示變動前的檔案,"+++"表示變動後的檔案。+++ f2 2012-08-29 16:45:51.000000000 +0800
第二部分,變動的位置用兩個@作為起首和結束。
@@ -1,7 +1,7 @@前面的"-1,7"分成三個部分:減號表示第乙個檔案(即f1),"1"表示第1行,"7"表示連續7行。合在一起,就表示以下是第乙個檔案從第1行開始的連續7行。相同的,"+1,7"表示變動後,成為第二個檔案從第1行開始的連續7行。
第三部分是變動的詳細內容。
aaa除了有變動的那些行以外,也是上下文各顯示3行。它將兩個檔案的上下文,合併顯示在一起,所以叫做"合併格式"。每一行最前面的標誌位,空表示無變動,減號表示第乙個檔案刪除的行,加號表示第二個檔案新增的行。-a+baa
a
六、git格式的diff
版本號管理系統git,使用的是合併格式diff的變體。
$ git diff顯示結果例如以下:
diff --git a/f1 b/f1第一行表示結果為git格式的diff。index 6f8a38c..449b072 100644
--- a/f1
+++ b/f1
@@ -1,7 +1,7 @@aa
a-a+ba
aa
diff --git a/f1 b/f1進行比較的是,a版本號的f1(即變動前)和b版本號的f1(即變動後)。
第二行表示兩個版本號的git雜湊值(index區域的6f8a38c物件,與工作資料夾區域的449b072物件進行比較),最後的六位數字是物件的模式(普通檔案,644許可權)。
index 6f8a38c..449b072 100644第三行表示進行比較的兩個檔案。
--- a/f1"---"表示變動前的版本號,"+++"表示變動後的版本號。+++ b/f1
後面的行都與官方的合併格式diff同樣。
@@ -1,7 +1,7 @@aa七、閱讀材料* diff - wikipediaa-a+ba
aa
* how to work with diff representation in git
(完)本文**
linux select具體解釋
linux select 具體解釋 select 系統呼叫時用來讓我們的程式監視多個檔案控制代碼的狀態變化的。程式會停在 select 這裡等待,直到被監視的檔案控制代碼有乙個或多個發生了狀態改變。關於檔案控制代碼,事實上就是乙個整數,通過 socket 函式的宣告就明確了 int socket i...
htons函式具體解釋
part 1 htons函式具體解釋 在linux和windows網路程式設計時需要用到htons和htonl函式,用來將主機位元組順序轉換為網路位元組順序。在intel機器下,執行以下程式 int main 得到的結果是4096,初一看感覺很怪。解釋如下,數字16的16進製表示為0x0010,數字...
全域性鉤子具體解釋
dword dwthreadid 0,hwnd hwndcaller null return callnexthookex g hhook,ncode,wparam,lparam g hwndcaller hwndcaller 用了模組定義檔案時,在使用動態鏈結庫的時間就能夠直接用函式名呼叫函式了,...