diff和patch的使用一二

來源:互聯網
上載者:User

不重新整理一下,都快忘了,趁這個機會也貼上來吧。

 

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

 

應該是引用了某些大大的文章,但是不知道出處了,請見諒,呵呵

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.