Mercurial_ The Definitive Guide - Bryan O'Sullivan [95]
Since someone receiving a patch from the Alices of the Net would be unlikely to have unmodified and modified directories with exactly the same names, the patch command has a -p option that indicates the number of leading pathname components to strip when trying to apply a patch. This number is called the strip count.
An option of -p1 means “use a strip count of one.” If patch sees a filename foo/bar/baz in a file header, it will strip foo and try to patch a file named bar/baz. (Strictly speaking, the strip count refers to the number of path separators [and the components that go with them] to strip. A strip count of one will turn foo/bar into bar, but /foo/bar [notice the extra leading slash] into foo/bar.)
The “standard” strip count for patches is one; almost all patches contain one leading pathname component that needs to be stripped. Mercurial’s hg diff command generates pathnames in this form, and the hg import command and MQ expect patches to have a strip count of one.
If you receive a patch from someone that you want to add to your patch queue, and the patch needs a strip count other than one, you cannot just qimport the patch, because qimport does not yet have a -p option; see issue 311. Your best bet is to qnew a patch of your own, then use patch -pN to apply their patch, followed by hg addremove to pick up any files added or removed by the patch, followed by hg qrefresh. This complexity may become unnecessary; see issue 311 for details.
Strategies for Applying a Patch
When patch applies a hunk, it tries a handful of successively less accurate strategies to try to make the hunk apply. This falling-back technique often makes it possible to take a patch that was generated against an old version of a file and apply it against a newer version of that file.
First, patch tries an exact match, where the line numbers, the context, and the text to be modified must match exactly. If it cannot make an exact match, it tries to find an exact match for the context, without honoring the line numbering information. If this succeeds, it prints a line of output saying that the hunk was applied, but at some offset from the original line number.
If a context-only match fails, patch removes the first and last lines of the context, and tries a reduced context-only match. If the hunk with reduced context succeeds, patch prints a message saying that it applied the hunk with a fuzz factor (the number after the fuzz factor indicates how many lines of context patch had to trim before the patch applied).
When neither of these techniques works, patch prints a message saying that the hunk in question was rejected. It saves rejected hunks (also simply called “rejects”) to a file with the same name and an added .rej extension. It also saves an unmodified copy of the file with a .orig extension; the copy of the file without any extensions will contain any changes made by hunks that did apply cleanly. If you have a patch that modifies foo with six hunks, and one of them fails to apply, you will have: an unmodified foo.orig, a foo.rej containing one hunk, and foo, containing the changes made by the five successful hunks.
Some Quirks of Patch Representation
There are a few useful things to know about how patch works with files:
This should already be obvious, but patch cannot handle binary files.
Neither does it care about the executable bit; it creates new files as readable, but not executable.
patch treats the removal of a file as a diff between the file to be removed and the empty file. So your idea of “I deleted this file” looks like “every line of this file was deleted” in a patch.
It treats the addition of a file as a diff between the empty file and the file to be added. So in a patch, your idea of “I added this file” looks like “every line of this file was added.”
It treats a renamed file as the removal of the old name and the addition of