我正在学习 diff/patch,但我不明白为什么当我尝试应用它时,下面的命令序列创建的补丁文件不会在目录create_me.txt
内创建文件。Org
创建文件
$ ls -R
Org Upd
./Org:
./Upd:
create_me.txt
$ diff -ruN Org/ Upd/ > Org.patch
$ cat Org.patch
diff -ruN Org/create_me.txt Upd/create_me.txt
--- Org/create_me.txt 1970-01-01 01:00:00.000000000 +0100
+++ Upd/create_me.txt 2019-06-30 21:12:36.000000000 +0200
@@ -0,0 +1 @@
+content
$ patch -p0 < Org.patch
The next patch would create the file Upd/create_me.txt,
which already exists! Assume -R? [n]
该-N --new-file
标志将缺失的文件视为create_me.txt
空文件,并在缺失的目录中使用默认时间戳。使用标志删除文件-N
(见下文)效果很好,但反向操作会导致在上面的命令序列中看到错误消息,我无法理解。
删除文件
$ ls -R
Org Upd
./Org:
delete_me.txt identical.txt
./Upd:
identical.txt
$ diff -ruN Org/ Upd/ > Org.patch
$ cat Org.patch
diff -ruN Org/delete_me.txt Upd/delete_me.txt
--- Org/delete_me.txt 2019-06-30 21:32:50.000000000 +0200
+++ Upd/delete_me.txt 1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-content
$ patch -p0 < Org.patch
patching file Org/delete_me.txt
$ ls -R
Org Org.patch Upd
./Org:
identical.txt
./Upd:
identical.txt
我看到了两个与此重复的问题(https://stackoverflow.com/questions/23528758/how-to-create-patch-for-a-new-file-and-patch-it-back-to-the-original-directory,
https://askubuntu.com/questions/975879/patch-command-cant-create-the-new-file)但没有一个答案令我满意。这些答案通过将工作目录更改为要在其中创建文件的原始目录并从那里应用补丁来解决问题。这种方法有效,但它无法扩展到我希望使用 diff/patch 的目的,因此我希望有一个更广泛的解决方案,它可以从任何目录使用并使用-p0
补丁标志。
当前答案的创建文件的方式
$ ls -R
Org Upd
./Org:
identical.txt
./Upd:
create_me.txt identical.txt
$ diff -ruN Org/ Upd/ > Org.patch
$ cat Org.patch
diff -ruN Org/create_me.txt Upd/create_me.txt
--- Org/create_me.txt 1970-01-01 01:00:00.000000000 +0100
+++ Upd/create_me.txt 2019-06-30 21:53:09.000000000 +0200
@@ -0,0 +1 @@
+content
$ cd Org
$ patch -p1 < ../Org.patch
patching file create_me.txt
$ ls -R ..
Org Org.patch Upd
../Org:
create_me.txt identical.txt
../Upd:
create_me.txt identical.txt
也欢迎解释为什么当前答案有效而我的版本无效。
答案1
您的第一个补丁以及应用它的方式要求patch
创建一个名为 的文件Upd/create_me.txt
,而不是Org/create_me.txt
:完整路径很重要。当patch
看到日期为纪元 (170-01-01 00:00:00 UTC) 的条目时,它知道这代表一个不存在的文件;如果它是“开始”条目,它知道它应该创建一个文件,如果它是“结束”条目,它知道它应该删除一个文件。要创建或删除的文件的名称取自其他入口。
你的第二个补丁的工作方式相同:它告诉patch
删除Org/delete_me.txt
.
你的第三种方法有效,因为你告诉patch
忽略路径的第一部分,IE Org
或者Upd
。因此,它create_me.txt
在当前目录中创建一个名为Org
.
要使您的第一个示例正常工作,您可以在补丁中替换Upd/create_me.txt
为。Org/create_me.txt