19

What's the difference between patch -p0 and patch -p1?

Is there any difference at all?

24

The most common way to create a patch is to run the diff command or some version control's built-in diff-like command. Sometimes, you're just comparing two files, and you run diff like this:

diff -u version_by_alice.txt version_by_bob.txt >alice_to_bob.patch

Then you get a patch that contains changes for one file and doesn't contain a file name at all. When you apply that patch, you need to specify which file you want to apply it to:

patch <alice_to_bob.patch version2_by_alice.txt

Often, you're comparing two versions of a whole multi-file project contained in a directory. A typical invocation of diff looks like this:

diff -ru old_version new_version >some.patch

Then the patch contains file names, given in header lines like diff -ru old_version/dir/file new_version/dir/file. You need to tell patch to strip the prefix (old_version or new_version) from the file name. That's what -p1 means: strip one level of directory.

Sometimes, the header lines in the patch contain the file name directly with no lead-up. This is common with version control systems; for example cvs diff produces header lines that look like diff -r1.42 foo. Then there is no prefix to strip, so you must specify -p0.

In the special case when there are no subdirectories in the trees that you're comparing, no -p option is necessary: patch will discard all the directory part of the file names. But most of the time, you do need either -p0 or -p1, depending on how the patch was produced.

| improve this answer | |
  • 1
    This has confused me for so long. Why is the behavior of no subdirectories different from -p0? I've always assumed that -p0 was default, so I always had issues if it was supposed to be p0 – Brydon Gibson Sep 26 '19 at 15:34
  • @BrydonGibson I suspect that originally the idea was that the patch author could indifferently write diff old/foo new/foo >my.patch or diff ../old/foo foo >my.patch or diff foo.old foo >my.patch and the user could apply it with patch <my.patch without having to care how the patch was produced, and then -p was added as a convenience. But I don't actually know, patch is an old utility and by the time I started using it -p0 or -p1 were already the most common ways to use it. – Gilles 'SO- stop being evil' Sep 26 '19 at 16:23
  • Another instance of man pages failing to be useful, at least for GNU/patch. Thanks for the clear explanation! – brainplot Jan 29 at 21:35
16

From the man:

-pnum or --strip=num Strip the smallest prefix containing num leading slashes from each file name found in the patch file. A sequence of one or more adjacent slashes is counted as a single slash. This controls how file names found in the patch file are treated, in case you keep your files in a different directory than the person who sent out the patch. For example, supposing the file name in the patch file was:

 /u/howard/src/blurfl/blurfl.c

setting -p0 gives the entire file name unmodified, -p1 gives

 u/howard/src/blurfl/blurfl.c

without the leading slash, -p4 gives

 blurfl/blurfl.c
| improve this answer | |
5

The difference is that the number after -p would specify the number of path components that would be removed.

Say we have a path /Barack/Obama. Executing a patch on it with the -p0 argument will treat the path as is:

/Barack/Obama

But we can trim the path while patching:

-p1 will remove the root slash (note that it will just be Barack now, without a slash left to it):

Barack/Obama

-p2 will remove Barack (and adjacent right slash):

 Obama

To expand on the "why" of this patch behavior, read this thread.

| improve this answer | |

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.