2010-10-10 98 views
29

有時,無論出於何種原因,我必須生成錯誤方向的補丁文件(在Linux下)。我知道我可以通過使用-R開關通過patch應用它來解決這個問題,但如果有一種永久反轉修補程序文件的方法,那將會很不錯。有沒有可以做到這一點的實用工具,或一個可以保證正常工作的正則表達式?永久反轉補丁文件

UPDATE

烈瑞安suggested a neat way of doing this。但是,它需要訪問原始源文件。所以我想我應該更新我的問題,說明我更多的是在給定補丁文件本身的情況下實現這一點。

回答

44

您可以從patchutils使用工具interdiff(1)。特別是,interdiff手冊頁說:

要扭轉一個補丁,使用/ dev/null作爲 DIFF2。

所以,

$ interdiff file.patch /dev/null > reversed.patch 
+0

不起作用。我試圖將反轉補丁應用到使用正向補丁修補的文件中,並且失敗。所以這不會產生正確的反轉補丁,至少不是所有的補丁。我不知道是否interdiff被破壞,或者這種方法是錯誤的 – matteo 2017-03-09 17:00:53

+0

我看到,*應該按照interdiff的手冊頁工作,所以這是一個interdiff中的錯誤 – matteo 2017-03-09 17:01:41

14

嘗試:

patch -R file.txt file.patch 
diff file.txt.orig file.txt > file.patch.rev 
// you can then `rm file.txt.orig file.patch` 

編輯:

要扭轉一個統一的diff,你需要改變三樣東西:

  • 補丁頭
  • 塊頭部
  • the + to - and - to +

因此,這裏是怎樣一個看起來像一個補丁頭:

--- b.asm 2010-09-24 12:03:43.000000000 +1000  
+++ a.asm 2010-09-24 23:28:43.000000000 +1000 

你需要扭轉它,所以它看起來是這樣的:

--- a.asm 2010-09-24 23:28:43.000000000 +1000 
+++ b.asm 2010-09-24 12:03:43.000000000 +1000  

基本切換順序,並切換+ ++到---反之亦然。

接下來,塊頭部:

@@ -29,5 +27,7 @@ 

你需要扭轉的數字,所以它看起來像這樣:

@@ -27,7 +29,5 @@ 

基本上,切換數字對

和最後一個,切換每一行以+開頭,每一行以 - 開頭。

編輯:

切換塊頭部,你可以這樣做:

sed -e "s/@@ -\([0-9]\+,[0-9]\+\) +\([0-9]\+,[0-9]\+\) @@/@@ -\2 +\1 @@/" 

至+切換到 - 和 - +,你可以這樣做:

sed -e "s/^+/P/" -e "s/^-/+/" -e "s/^P/-/" 

最後:

扭轉補丁頭,這樣做:

head -2 orig.diff | tac | sed -e "s/+++/PPP/" -e "s/---/+++/" -e "s/PPP/---/" > head 
tail orig.diff -n+3 > tail 
cat head tail > headtail 
rm head tail 

所以,最後,我們的(快速和骯髒的)腳本的樣子:

#!/usr/bin/env sh 
F="$1" 
head -2 $F | tac | sed -e "s/+++/PPP/" -e "s/---/+++/" -e "s/PPP/---/" > $F.head 
tail $F -n+3 | sed -e "s/@@ -\([0-9]\+,[0-9]\+\) +\([0-9]\+,[0-9]\+\) @@/@@ -\2 +\1 @@/" -e "s/^+/P/" -e "s/^-/+/" -e "s/^P/-/" > $F.tail 
cat $F.head $F.tail 
rm $F.head $F.tail 

我測試了它,它似乎工作。

不過,爲了使事情更容易維護,和清潔:

#!/usr/bin/env sh 
swap() { 
    sed -e "s/^$1/PPP/" -e "s/^$2/$1/" -e "s/^PPP/$2/" 
} 
file_header() { 
    head -2 $1 | tac | swap +++ --- 
} 
fix_chunk_header() { 
    sed -e "s/@@ -\([0-9]\+,[0-9]\+\) +\([0-9]\+,[0-9]\+\) @@/@@ -\2 +\1 @@/" 
} 
fix_lines() { 
    swap + - 
} 
file="$1" 
file_header $file 
tail $file -n+3 | fix_chunk_header | fix_lines 
+0

+1:我沒有想到這一點。但出於興趣,有沒有辦法做到不訪問原始文件? – 2010-10-10 22:16:38

+0

@Oli Charlesworth:當你在第一行調用它時,file.txt.orig文件是由補丁生成的自動備份。我只是使用該備份來重新生成反向修補程序。 – 2010-10-10 22:18:55

+0

@Lie Ryan:我的意思是,如果我*只有*有補丁文件,我怎麼能做到這一點? – 2010-10-10 22:20:25

0

我已經在應用補丁程序patch -N -p0 < path/file.patch,但我開始編纂面臨的問題是由於不完整的代碼,我所做的就是運行這個命令patch -p0 -R < path/file.patch。推薦這個link