不重新整理一下,都快忘了,趁這個機會也貼上來吧。
diff
diff是產生源碼補丁的必備工具。其命令格式為:
diff [命令列選項] 原始檔案 新檔案
常用命令列選項如下:
-r 遞迴處理目錄 -u 輸出統一格式(unified format)
-N patch裡包含新檔案 -a patch裡可以包含二進位檔案
它的輸出在stdout上,所以你可能需要把它重新導向到一個檔案。diff的輸出有“傳統格式”和“統一格式”之分,現在大都使用統一格式:
傳統格式樣本:
[hahalee@builder]$ diff a.txt b.txt
1a2
> here we insert a new line
3d3
< why not this third line?
統一格式樣本:
[hahalee@builder]$ diff -u a.txt b.txt
--- a.txt Thu Apr 6 15:58:34 2000
+++ b.txt Thu Apr 6 15:57:53 2000
@@ -1,3 +1,3 @@
This is line one
+here we insert a new line
and this is line two
-why not this third line?
通過比較可以看出,傳統格式的patch檔案比較小,除了要刪除/插入的行外沒有冗餘資訊。統一格式則儲存了上下文(預設是上下各三行,最少需要兩行),這樣,patch的時候可以允許行號不精確匹配的情況出現。另外,在patch檔案的開頭明確地用---和+++標示出原始檔案和當前檔案,也方便閱讀。要選用統一格式,用u 開關。
通常,我們需要對整個軟體包做修改,並產生一個patch檔案,下面是典型的操作過程。這裡就要用到前面介紹的幾個命令列開關了:
tar xzvf software.tar.gz # 展開原始軟體包,其目錄為software
cp _a software software-orig # 做個修改前的備份
cd software
[修改,測試……]
cd ..
diff _ruNa software-orig software > software-my.patch
現在我們就可以儲存software-my.patch做為這次修改的結果,至於原始軟體包,可以不必儲存。等到下次需要再修改的時候,可以用patch命令把這個補丁打進原始包,再繼續工作。比如是在linux kernel上做的工作,就不必每次儲存幾十兆修改後的源碼了。這是好處之一,好處之二是維護方便,由於unified patch格式有一定的模糊比對能力,能減少原軟體包升級帶來的維護工作量(見後)
patch
patch命令跟diff配合使用,把產生的補丁應用到現有代碼上。常用命令列選項:
patch [命令列選項] [待patch的檔案[patch]]
-pn patch level(n是數字) -b[尾碼] 產生備份,預設是.orig
為了說明什麼是patch level,這裡看一個patch檔案的頭標記。
diff -ruNa xc.orig/config/cf/Imake.cf xc.bsd/config/cf/Imake.cf
--- xc.orig/config/cf/Imake.cf Fri Jul 30 12:45:47 1999
+++ xc.new/config/cf/Imake.cf Fri Jan 21 13:48:44 2000
這個patch如果直接應用,它會去找xc.orig/config/cf目錄下的Imake.cf檔案,假如你的源碼樹的根目錄是預設的xc而不是xc.orig,除了mvxc xc.orig之外,有無簡單的方法應用此patch呢?patch level就是為此而設:patch會把目標路徑名砍去開頭patch
level個節(由/分開的部分)。在本例中,可以用下述命令:
cd xc; patch _p1 < /pathname/xxx.patch
完成操作。注意,由於沒有指定patch檔案,patch程式預設從stdin讀入,所以用了輸入重新導向。
如果patch成功,預設是不建備份檔案的(註:FreeBSD下的patch工具預設是儲存備份),如果你需要,可以加上b開關。這樣把修改前的檔案以“原檔案名稱.orig”的名字做備份。如果你喜歡其它尾碼名,也可以用“b尾碼”來指定。
如果patch失敗,patch會把成功的patch行給patch上,同時(無條件)產生備份檔案和一個.rej檔案。.rej檔案裡是沒有成功提交的patch行,需要手工patch上去。這種情況在原碼升級的時候有可能會發生。
關於二進位檔案的說明:binary檔案可以原始方式存入patch檔案。diff可以產生(加-a選項),patch也可以識別。如果覺得這樣的patch檔案太難看,解決方案之一是用uuencode處理該binary檔案。
diff 以行為單位比較兩個文字檔(或者是目錄),並將不同之處輸出到標準輸出上,
patch可以讀入這些輸出,並按照一定的指令使源檔案(目錄)更新
diff 以行為單位比較兩個文字檔(或者是目錄),並將不同之處輸出到標準輸出上,
patch可以讀入這些輸出,並按照一定的指令使源檔案(目錄)更新
diffutils-2.7.2-2
patch-2.5.4-10
1, diff
options:
-r --recursive
-p --show-c-function //標識不同之處所在的函數名(只用於C程式)
-e --ed //ed 命令格式 diff -e test1 test2
//混合ed命令格式(無參數) diff test1 test2
-f //RCS命令簡單格式 diff -f test1 test2 Revision Control
System
-c --context //舊版上下文格式 diff -c test1 test2
-u --unified //新版上下文格式 diff -u test1 test2
-N //如果某個檔案只在一個目錄中出現,則假定在另一個目錄中為空白檔案.
diff的輸出格式有三種:列舉方式,命令模式,上下文模式
命令模式有:ed命令模式和RCS(Revision Control System)
上下文模式有:舊版和新版
命令模式記錄的是從test1更新到test2所需要執行的命令,而上下文模式可讀性更好一些.
Linux核心原始碼就是按照新版上下文模式用diff組織的,
eg. diff -Nur linux-2.4.15 linux
2. patch
patch [options] [originalfile] [patchfile]
如果patchfile為空白,則從標準輸入讀取
一般使用下面的形式:
patch -p[num] < patchfile
如果不提供p參數將忽略所有的目錄資訊,
-p0表示使用全部的路徑資訊
-p1表示忽略第一"/"以前的目錄,依次類推
patch可以直接操作上下文格式以及混合ed格式的diff輸出檔案,而將ed格式檔案通過管道提交給ed程式,
不清楚如何處理RCS格式檔案.
eg.
bzcat linux-2.6.1.patch.bz2 | patch -p0
如果希望恢複到原來的版本可以使用 -R (--reverse)參數
但是只對上下文格式的diff檔案有效.
eg. patch -R < program-1.2.patch
3. diff-patch和CVS的配合使用
在這種情況下,注意不要把CVS目錄包括進去
eg.
patch -Nur program-1.0 program-1.1 --exclude=CVS
應該是引用了某些大大的文章,但是不知道出處了,請見諒,呵呵