How to apply patches

Wednesday 21 May 2008

Occasionally I write things here simply so that I won’t forget them, here’s one of them. Applying patches is something I do infrequently enough that I have to re-figure it out each time.

If you have a patch file called my.patch that looks like this (in part):

=== modified file 'cogapp/cogapp.py'
--- cogapp/cogapp.py 2005-12-04 20:27:41 +0000
+++ cogapp/cogapp.py 2008-05-21 09:00:08 +0000
@@ -37,6 +37,7 @@
                     A %s in the CMD will be filled with the filename.
     -x          Excise all the generated output without running the generator
     -z          The [[[end]]] marker can be omitted, and is assumed at eof.
+    -N          Write the output as binary file (with LF line-endings).
     -v          Print the version of cog and exit.
     -h          Print this help.
 """

then to apply the patch, cd to the directory that has cogapp in it, and use this command:

patch -p0 < my.patch

The patch command is one of those inscrutable Unix-culture tools which does not behave as I expect. In this case, there seems to be no syntax that names my.patch explicitly, only an input redirect works. And zero seems not to be the default for the -p switch, so it needs to be specified, but the help text doesn’t mention the default value, so I’m not sure what it is.

Comments

[gravatar]
Simon Brunning 7:55 AM on 21 May 2008

Try the -i flag:

patch -p0 -i my.patch

[gravatar]
rik@rikkus.info 8:00 AM on 21 May 2008

If it's GNU patch, it will respond to the --help argument, as most GNU utils do.

[gravatar]
elliot murphy 8:20 AM on 21 May 2008

I've always found patch unintuitive as well. I like how bzr has a built in patch command, which is less jarring (and available anywhere bzr is installed, so it makes life easier on windows).

jitter:~ emurphy$ bzr help patch
Purpose: Apply a named patch to the current tree.
Usage: bzr patch [FILENAME]

[gravatar]
Jan 8:34 AM on 21 May 2008

$ man patch # to the rescue:

-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 direc-
tory 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

and not specifying -p at all just gives you blurfl.c. Whatever you end up with is looked for
either in the current directory, or the directory specified by the -d option.

[gravatar]
Ned Batchelder 9:11 AM on 21 May 2008

I should have read the man page! Thanks Jan for pointing out the obvious. I'm using these tools under cygwin on Windows, which actually has good man page support, but I'm not used to using it! I knew behind it all there was reason...

[gravatar]
bialix 4:39 AM on 22 May 2008

on Windows I always specify --binary flag too.

Add a comment:

Ignore this:
Leave this empty:
Name is required. Either email or web are required. Email won't be displayed and I won't spam you. Your web site won't be indexed by search engines.
Don't put anything here:
Leave this empty:
URLs auto-link and some tags are allowed: <a><b><i><p><br><pre>.