1

I'm learning about diff/patch and I don't understand why the patch file created by the command sequence below doesn't create the file create_me.txt inside the Org directory when I try to apply it.

Creating a file

$ 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]

The -N --new-file flag treats absent files such as create_me.txt as empty files with a default timestamp inside the directory where it is missing. Deleting a file using the -N flag (see below) works perfectly but the reverse operation results in the error message seen in the command sequence above which I can't wrap my head around.

Deleting a file

$ 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

I have seen two duplicate questions to this one (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) but none of the answers satisfy me. These answers solve the problem by changing the working directory to the original directory in which the file is going to be created and applying the patch from there. This approach works but it isn't scalable to what I'm hoping to use diff/patch for and I would therefore love a more broad solution which can be used from any directory and uses the -p0 patch flag.

Current answer's way to create a file

$ 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

An explanation to why the current answer works and my version doesn't would also be welcome.

1

Your first patch, and the way you’re applying it, is asking patch to create a file named Upd/create_me.txt, not Org/create_me.txt: the full path is significant. When patch sees an entry dated at the epoch (170-01-01 00:00:00 UTC), it knows that that represents a non-existent file; if it’s the “start” entry, it knows it’s supposed to create a file, and if it’s the “end” entry, it knows it’s supposed to delete a file. The name of the file to be created or deleted is taken from the other entry.

Your second patch works in the same way: it tells patch to delete Org/delete_me.txt.

Your third approach works because you’re telling patch to ignore the first part of the path, i.e. Org or Upd. Thus it creates a file named create_me.txt in the current directory, Org.

To get your first example to work, you can replace Upd/create_me.txt with Org/create_me.txt in the patch.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.