ClassRooms/PatchBasics

Back to ClassRooms

Here will be put a lesson about patch tool basics. Any improvement is welcome, and everybody is warmly welcome to participate.

Goal

 * Learn the essential about patch tool
 * the student must be able to :
 * fake a patch application
 * analyze the result of the fake application
 * separate bad hunks
 * correct rejected hunks

Introduction
In this lesson, we'll discover how work the universal and essential tool (dev point of view) named patch.

How things work
Imagine you downloaded a brand new tree from the repo, and add some changes. To summarize, we can consider the delta (diff between original file and the new modified one), as a text file, containing 3 lines of context before the changes, and 3 lines of context, after the changes. Something modified or removed in the original file will be a line starting with - (minus), and something added, will be a line starting with + (plus).


 * a hunk means : the 3 (default value) lines of context before the changes + one continuous part of the changes (may be several lines) + 3 lines after.
 * a patch means : a text file containing one or several hunks.
 * a fuzz is detected when, applying a patch the line where the context starts, is not exactly the one expected. To be sure no garbage is introduced, patch creates a .orig file, just in case. Most of the time, the fuzz can be ignored (but it's safe to check).
 * a .rej file is created when a hunk cannot be applied. Either the context is wrong, or something is not possible. The manual application of the change is mandatory in this case.
 * A patch file is a simple text file, and thus, there is no need to add a suffix, e.g. .diff or .patch, but this is prefered, e.g. when the text editor is able to recognize, the changes will appear following colored syntax rules. Some softwares like Midnight Commander are extremely well designed to read, extract and even fix malformed patches.

Apply a patch(fast approach)
Below, some examples, to help the newcomer :

First fake the application
patch -p0 --dry-run < aPatch.diff

Then apply it for true patch -p0 --dry-run < aPatch.diff

Reverse a patch
Fake reversing it patch -p1 -R < anotherPatch.patch

Apply it for true patch -p1 -R < anotherPatch.patch

Most usefull patch options
==> most usefull reference : man patch

Strip prefix containing num leading slashes in the path
- pnum (e.g. : -p0)

Every hunk contains the path where changes have to be applied. The patch might not match with the current one, and sometimes, the path must be modified.

Taken from man patch : -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 adja- cent 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 directory 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

Fake the patch application
--dry-run option is the safest way to avoid garbage, when e.g. appling a malformed or simply a wrong patch.

man patch says : --dry-run Print the results of applying the patches without actually changing any files.

Reverse a patch application
Suppose you already applied a patch, and want to exactly reverse it. This action can be achieved, using the -R (for reverse) option.

e.g. : patch -R -p0 < aPatch.diff