3.10. Apply a patch from someone else

Sometimes you need to apply a patch to your private source tree. Maybe because you want to try a patch from someone on the developer mailing list, or you want to check your own patch before submitting.

[Warning]Warning!

If you have problems applying a patch, make sure the line endings (CR/NL) of the patch and your source files match.

3.10.1. Using patch

Given the file new.diff containing a unified diff, the right way to call the patch tool depends on what the pathnames in new.diff look like. If they're relative to the top-level source directory - for example, if a patch to prefs.c just has prefs.c as the file name - you'd run it as:

patch -p0 <new.diff

If they're relative to a higher-level directory, you'd replace 0 with the number of higher-level directories in the path, e.g. if the names are wireshark.orig/prefs.c and wireshark.mine/prefs.c, you'd run it with:

patch -p1 <new.diff

If they're relative to a subdirectory of the top-level directory, you'd run patch in that directory and run it with -p0.

If you run it without -p at all, the patch tool flattens path names, so that if you have a patch file with patches to Makefile.am and wiretap/Makefile.am, it'll try to apply the first patch to the top-level Makefile.am and then apply the wiretap/Makefile.am patch to the top-level Makefile.am as well.

At which position in the filesystem should the patch tool be called?

If the pathnames are relative to the top-level source directory, or to a directory above that directory, you'd run it in the top-level source directory.

If they're relative to a subdirectory - for example, if somebody did a patch to "packet-ip.c" and ran "diff" or "svn diff" in the "epan/dissectors" directory - you'd run it in that subdirectory. It is preferred that people NOT submit patches like that - especially if they're only patching files that exist in multiple directories, such as Makefile.am.

3.10.2. CVS diff (obsolete)

One other thing to note - "cvs diff" produces output that at least some versions of "patch" can't handle; you'd get something such as


Index: missing/dlnames.c
===================================================================
RCS file: /tcpdump/master/tcpdump/missing/dlnames.c,v
retrieving revision 1.5
diff -c -r1.5 dlnames.c
*** missing/dlnames.c   18 Nov 2003 23:09:43 -0000      1.5
--- missing/dlnames.c   31 Aug 2004 21:45:16 -0000
***************

	

from "cvs diff -c", and something similar from "cvs diff -u", and "patch", unfortunately, would use the "diff -c" or "diff -u" line and try to patch "dlnames.c" in the directory you're in, rather than in the "missing" subdirectory.

For "cvs diff -c" or "cvs diff -u" diffs, there's a Python script "cvsdiff-fix.py" in the "tools" directory in the Wireshark source tree; it will fix up those lines in "cvs diff" output. It reads its standard input by default, or can be given a file name on the command line, and writes to the standard output, so if you're typing at a command interpreter that does piping, you could do something such as

python tools/cvsdiff.py patchfile | patch -p0 -

to use "patchfile". (You might be able to leave the "python" out of the command line on many UN*Xes.)

"svn diff" doesn't produce a "diff -c" or "diff -u" line, so its output doesn't have that problem. Regular "diff -c" or "diff -u" output also shouldn't have that problem.