Saturday, December 6, 2008


Before we delve into applying patches, let us have a look at a sample patch file.

--- old_test 2008-12-07 15:43:27.000000000 +0530
+++ new_test 2008-12-07 15:43:39.000000000 +0530
@@ -1,5 +1,6 @@

The first line gives details about the original file and the second line about the modified file.
Then "@@ -1,5 +1,6 @@" marks the beginning of the hunk. This line tells the patch command where, in the file-to-be-patched should it find the specified change.

The line prefixed by "+" is the line that was added in the modified version. Other lines constitute the context.

Now why is context important?
Here's why. Consider this scenario. You work on this amazing new idea on a file called blah.c. At the same time, another of your friend modifies the same file to implement his crazy new idea. So, would your patch not apply to your friend's version of blah.c?
Chances are, it will!.. because patch tries to find the same "context" in the neighbourhood of the original line numbers. If it does, patch applies successfully!... Now this is what makes patches a good idea!.. DISTRIBUTED DEVELOPMENT!

So, coming back to the patch command,
>> patch -pNUM < patch-file

Note that patch reads the patch file from the standard input. So, you have to redirect the standard input to the patch file.

the -p option is used to specify number of components to strip.
Here's a line from a patch file. Lets take it up as an example to understand the -p option
diff --git a/wlan/driver/linux/some-name.c b/wlan/driver/linux/some-name.c

the -p option works on the path "a/wlan/driver/linux/some-name.c".
with -p1 : it strips one element from the LHS of the path. Thus, it will try to find "wlan" directory in the current directory.

with, -p2 : patch will strip the first 2 components. i.e. "a" and "wlan" and it will try to find "driver" directory in the current directory.

and so on.
If you don't give a -p option, -p1 is used by default.

Unapplying patches:
It is possible that you applied a wrong patch to your code. Or you find out after applying the patch that the damn thing is not going to work. Or there is a regression. Whatever. The point is, you want to revert the patch.

Just pass a "-R" option to patch and it will try to unapply the patch. Although, do read the man page carefully before using this option.

Random notes on the patch command:
1) Use the strip-level option (-p) properly. If patch command doesn't find the file to be patched, chances are that you have specified an improper strip level option. (In that case, patch becomes interactive and asks you the path of the file to be patched. Most of the times, it means that you need to correct the strip-level option. so, exit with ctrl+c and give the correct strip level)

2) In case, one of the hunk fails (Which is the case when, the original file is modified by someone else prior to applying the patch and there is a conflict), the hunk that failed is saved in the "filename.rej" file. You need to apply that change manually. Just open the .rej file, see which hunk failed and make the changes manually. Also, the original version of the file is saved in filename.orig, just in-case you changed your mind or you are just too lazy to do the hard-work.

3) A patch is a defacto standard to give out changes like bug-fixes, minor feature additions, security patches etc. Patches are extensively used when a team is working on the same workspace (which is almost always the case). Revision control softwares like git, SVN, CVS, perforce, etc all support patches extensively in all their operations.
Patches are something you really want to know!

Hope it helped!


CDK said...

good one ... thats one more article off the wanted list...keep 'em coming...

Vedang said...

brilliant. just what i wanted at the moment.
and P.S thanks for putting in the explanation of -p1. finally understand what was happening while applying patches during the project! :D

Aditya said...

Thanks a lot. I had been looking for this a LONG time. Looking forward to more such articles.

Furquan said...

Thanks a lot.....It really helped us a lot..... :)