![在此範例中,「 patch -p1」將補丁套用到哪些檔案?](https://rvso.com/image/109227/%E5%9C%A8%E6%AD%A4%E7%AF%84%E4%BE%8B%E4%B8%AD%EF%BC%8C%E3%80%8C%20patch%20-p1%E3%80%8D%E5%B0%87%E8%A3%9C%E4%B8%81%E5%A5%97%E7%94%A8%E5%88%B0%E5%93%AA%E4%BA%9B%E6%AA%94%E6%A1%88%EF%BC%9F.png)
要在提交中恢復對文件的更改,請從https://stackoverflow.com/a/2620822/156458
#!/bin/bash
function output_help {
echo "usage: git-revert-single-file <sha1> <file>"
}
sha1=$1
file=$2
if [[ $sha1 ]]; then
git diff $sha1..$sha1^ -- $file | patch -p1
else
output_help
fi
補丁檔案應用於哪些檔案patch -p1
(即 的輸出 git diff $sha1..$sha1^ -- $file
)?
它適用於工作目錄中的所有檔案嗎?
但工作目錄可能與提交目錄不同$sha1
。那麼,將$sha1^
和之間的差異應用$sha1
到工作目錄是否有意義,它可能與 相同,也可能不同$sha1
?
謝謝。
答案1
git diff $sha1..$sha1^
產生一個恢復提交的補丁$sha1
(它列出了該提交與其父提交之間的差異)。如果$file
指定,它將將該補丁限制為$file
給定提交中所做的更改。
然後將該補丁提供給,這將刪除(和)patch -p1
使用的假目錄名稱,並嘗試將補丁套用到補丁中列出的任何檔案 (git
a/
b/
IE,$file
如果它在給定提交中被命名並更改,或者在給定提交中更改了所有文件,包括子目錄中的文件)。如果目前目錄及其子目錄中存在的檔案有很大不同(或副檔名遺失),patch
則將無法套用修補程式。
這是透過以下事實實現的:統一格式的補丁(由git diff
( 和diff -u
) 產生)包含正在修補的檔案的名稱以及補丁的上下文。這是一個範例(不是來自git
,但它顯示了這個想法):
diff -ur cli-common-0.9+nmu1.orig/policy-remove cli-common-0.9+nmu1/policy-remove
--- cli-common-0.9+nmu1.orig/policy-remove 2015-02-25 21:34:08.000000000 +0100
+++ cli-common-0.9+nmu1/policy-remove 2017-04-08 20:47:09.029065259 +0200
@@ -11,4 +11,4 @@
#echo "Removing GAC policy file ($POLICY) from available GACs"
/usr/share/cli-common/gac-package-remove $POLICY > /dev/null
-rm /usr/share/cli-common/packages.d/$POLICY.installcligac
+rm -f /usr/share/cli-common/packages.d/$POLICY.installcligac
該補丁表示它正在修改名為 的檔案cli-common-0.9+nmu1.orig/policy-remove
以產生名為 的檔案cli-common-0.9+nmu1/policy-remove
。更改本身從第 11 行開始,涵蓋 4 行,包括上下文(即@@ -11,4
);在目標中,更改的行位於相同位置 ( +11,4 @@
)。更改上方有三行上下文,然後是更改本身,刪除以 開頭的行rm
並新增以 開頭的行rm -f
。套用此功能時patch
,它將尋找適當命名的檔案(如果使用選項指示,則在刪除路徑元件後-p
),並將檔案中的上下文與修補程式進行比較;僅當上下文匹配(在幾行內,取決於模糊選項)才會套用變更。
該腳本的全部目的是嘗試恢復給定提交中對單個文件所做的更改(因此得名)。這是否可能取決於自提交以來對文件所做的更改;但在實踐中它通常非常有用。 (要恢復完整的提交,您可以使用git revert
它。)