patching.pod - Appropriate format for patches to the perl source tree
The latest version of this document is available from http://perrin.dimensional.com/perl/perlpatch.html
You may mail corrections, additions, and suggestions to me at dgris@tdrenterprises.com but the preferred method would be to follow the instructions set forth in this document and submit a patch 8-).
As an open source project Perl relies on patches and contributions from its users to continue functioning properly and to root out the inevitable bugs. But, some users are unsure as to the right way to prepare a patch and end up submitting seriously malformed patches. This makes it very difficult for the current maintainer to integrate said patches into their distribution. This document sets out usage guidelines for patches in an attempt to make everybody's life easier.
The most common problems appear to be patches being mangled by certain mailers (I won't name names, but most of these seem to be originating on boxes running a certain popular commercial operating system). Other problems include patches not rooted in the appropriate place in the directory structure, and patches not produced using standard utilities (such as diff).
Also, please create patches against a clean distribution of the perl source. This insures that everyone else can apply your patch without clobbering their source tree.
-u
or -c
arguments to diff. These produce, respectively, unified diffs (where the
changed line appears immediately next to the original) and context diffs
(where several lines surrounding the changes are included). See the manpage
for diff for more details.
Also, the preferred method for patching is -
diff [<CODE>-c</CODE> | <CODE>-u</CODE>] <old-file> <new-file>
Note the order of files.
Also, if your patch is to the core (rather than to a module) it is better to create it as a context diff as some machines have broken patch utilities that choke on unified diffs.
GNU diff has many desirable features not provided by most vendor-supplied diffs. Some examples using GNU diff:
# generate a patch for a newly added file % diff -u /dev/null new/file # generate a patch to remove a file (patch > v2.4 will remove it cleanly) % diff -u old/goner /dev/null # get additions, deletions along with everything else, recursively % diff -ruN olddir newdir # ignore whitespace % diff -bu a/file b/file # show function name in every hunk (safer, more informative) % diff -u -F '^[_a-zA-Z0-9]+ *(' old/file new/file
If you are submitting patches that affect multiple files then you should
backup the entire directory tree (to $source_root.old/ for example). This
will allow
diff <CODE>-c</CODE> <old-dir> <new-dir>
to create all the patches at once.
Know what you're testing. Read the docs, and the source. Tend to fail, not succeed. Interpret results strictly. Use unrelated features (this will flush out bizarre interactions). Use non-standard idioms (otherwise you are not testing TIMTOWTDI). Avoid using hardcoded test umbers whenever possible (the EXPECTED/GOT style found in t/op/tie.t is much more maintainable, and gives better failure reports). Give meaningful error messages when a test fails. Avoid using qx// and system() unless you are testing for them. If you do use them, make sure that you cover _all_ perl platforms. Unlink any temporary files you create. Promote unforeseen warnings to errors with $SIG{__WARN__}. Be sure to use the libraries and modules shipped with version being tested, not those that were already installed. Add comments to the code explaining what you are testing for. Make updating the '1..42' string unnecessary. Or make sure that you update it. Test _all_ behaviors of a given operator, library, or function- All optional arguments Return values in various contexts (boolean, scalar, list, lvalue) Use both global and lexical variables Don't forget the exceptional, pathological cases.
This should work for most patches-
cp MANIFEST MANIFEST.old emacs MANIFEST (make changes) cd .. diff -c perl5.008_42/MANIFEST.old perl5.008_42/MANIFEST > mypatch (testing the patch:) mv perl5.008_42/MANIFEST perl5.008_42/MANIFEST.new cp perl5.008_42/MANIFEST.old perl5.008_42/MANIFEST patch -p < mypatch (should succeed) diff perl5.008_42/MANIFEST perl5.008_42/MANIFEST.new (should produce no output)
If you have no choice in mailers and no way to get your hands on a better one there is, of course, a perl solution. Just do this-
perl -ne 'print pack("u*",$_)' patch > patch.uue
and post patch.uue with a note saying to unpack it using
perl -ne 'print unpack("u*",$_)' patch.uue > patch
[PATCH]5.xxx_xx (Area) Description
where the x's are replaced by the appropriate version number, area is a short keyword identifying what area of perl you are patching, and description is a very brief summary of the problem (don't forget this is an email header).
Examples-
[PATCH]5.004_04 (DOC) fix minor typos
[PATCH]5.004_99
(CORE) New warning for
foo()
when frobbing
[PATCH]5.005_42 (CONFIG) Added support for fribnatz 1.5
-p
argument to patch. This helps reconcile differing paths between the machine
the patch was created on and the machine on which it is being applied.
If you follow these guidelines it will make everybody's life a little easier. You'll have the satisfaction of having contributed to perl, others will have an easy time using your work, and it should be easier for the maintainers to coordinate the occasionally large numbers of patches received.
Also, just because you're not a brilliant coder doesn't mean that you can't contribute. As valuable as code patches are there is always a need for better documentation (especially considering the general level of joy that most programmers feel when forced to sit down and write docs). If all you do is patch the documentation you have still contributed more than the person who sent in an amazing new feature that noone can use because noone understands the code (what I'm getting at is that documentation is both the hardest part to do (because everyone hates doing it) and the most valuable).
Mostly, when contributing patches, imagine that it is you receiving hundreds of patches and that it is your responsibility to integrate them into the source. Obviously you'd want the patches to be as easy to apply as possible. Keep that in mind. 8-)
Last modified 21 May 1998 by Daniel Grisinger <dgris@perrin.dimensional.com>
Copyright (c) 1998 Daniel Grisinger
Adapted from a posting to perl5-porters by Tim Bunce (Tim.Bunce@ig.co.uk)
I'd like to thank the perl5-porters for their suggestions.
If rather than formatting bugs, you encounter substantive content errors in these documents, such as mistakes in the explanations or code, please use the perlbug utility included with the Perl distribution.