Two days ago I introduced patch files. Let's see how to generate them when the sources you are modifying are controlled by a version management system: CVS. (Note that others also have this feature; just read their documentation.)

Recalling the previous post, the common procedure to modify a source file, to later generate a patch, is to keep a backup of the original, like in:

$ cp file.c file.c.orig
$ vi file.c
edit, edit, edit...
$ diff -u file.c.orig file.c > patch.diff

This is acceptable if all you modify is a single file, but gets complicated when you have to patch many of them. Furthermore it may lead to "outdated" patches (which don't apply correctly to the latest version of the program).

But... if the sources you are modifying are controlled by CVS, things change completely. First of all, you don't have to save a copy of the original code, as it's already stored in the repository. That is, you can proceed to modify all the files you wish locally. So, how to generate the patch? All you have to do is run cvs diff -u from within the source directory. This will create a patch that includes the differences for all the files you've modified. The command accepts multiple (optional) arguments, which are the list of files (or directories) to be diffed (diffing the whole tree can be sloooow).

Once you do this, you'll note that the output generated by the command is slightly different from what I explained in the previous post (in fact, the header is bigger). Let's analyze a sample header:

Index: sys/arch/i386/conf/GENERIC
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/conf/GENERIC,v
retrieving revision 1.623
diff -u -r1.623 GENERIC
--- sys/arch/i386/conf/GENERIC 19 Jul 2004 14:23:59 -0000 1.623
+++ sys/arch/i386/conf/GENERIC 23 Jul 2004 12:39:16 -0000

The first line shows which local file is beeing diffed (matches the name in the --- line. The second, third and fourth lines give infomation about the file beeing retrieved from the CVS repository; in this case we can see that it picked up version 1.623 of the /cvsroot/src/sys/arch/i386/conf/GENERIC,v file, and that the diff command was called with the -u flag. The last two lines are as in regular patches. This information is there for the reader; the patch(1) utility will never use it.

Also note that generating patches from CVS (if available) gives a better impression to the person who has to review and apply the patch, so please use this feature.

For a complete example, check out this patch (which I'm quite proud of ;-) against the NetBSD repository.