INTRODUCTION ------------ Patchtool is a tool aimed to simplify common operations with patchfiles. It was designed using real world's experience with the subject and expected to be very handy for an active porter. MODES OF OPERATION ------------------ The tool has the following two basic modes of operation: o generation/update of patchfiles. In this mode user provides list of working files for which patchfiles are to be generated and the tool generates or updates corresponding patches automatically guessing if there is an original version (.orig file, rcs(1)) or it is a completely new file; o automatic update of the existing patchfiles. In this mode user provides a list of patchfiles or directories containing patchfiles and the tool re-generates specified patches. In this mode the tool tries hard to guess whether the patchfile in question is already up to date or not and updates only those patchfiles, which are found to be outdated. The following options are supported: -a -- automatically save resulting diff into a patchfile; -f -- don't ask any question if target patchfile already exists and is to be replaced; -u -- run tool in the "update" mode (see above); -i -- perform requested operation (generate or update) even if the patchfile seems to be up-to-date based on last modification time of all files involved. The tool supports dozen environment variables that can be used to override default settings. You can find complete list at the top of patchtool.py, following are the most useful ones: PT_CVS_ID -- CVS id to be added at the top of each patchfile generated ("FreeBSD"); PT_DIFF_ARGS -- diff(1) args used to generate patchfile ("-du"); PT_DIFF_SUFX -- suffix used to save original version of the file (".orig"); KNOWN BUGS AND LIMITATIONS -------------------------- o It is assumed that each patchfile contains exactly one diff, so the tool may remove useful diffs when there are several diffs merged into one patchfile. Actually I don't think that it is a bug, because Porter's Handbook clearly demands to follow a "one diff - one patchfile" rule. Perhaps portlint(1) should be extended to warn about such abuses; o only '+++' supported as the prefix for the name of target file in the patchfile. Neither '***' nor 'Index:' are not recognised/supported yet; o please keep in mind that when you are trying to do automatic update and some of the patches are for auto-generated/mangled files (e.g. configure script in the situation when USE_LIBTOOL is used) then you would end up with some of patchfiles containing bogus hunks; o by default the tool tries to recognise saved original version on the file first by probing file with '.orig' suffix added and if it fails then by probing file with ',v' suffix added. If you use other suffix to save original version, for example '~', then set PT_DIFF_SUFX environment variable to match your settings, otherwise the tool will not function properly. REPORTING BUGS AND PROPOSING ENHANCEMENTS ----------------------------------------- The author of the tool is Maxim Sobolev <sobomax@FreeBSD.org>. Any bug reports, patches, proposals or suggestions are encouraged. You can do it either contacting author directly at the e-mail above or submitting a FreeBSD problem report. EXAMPLES -------- Following are several sample sessions which show common usage patterns for this tool. 1. Generation mode (useful when creating new port). $ cd /somewhere/foo ; make [compilation blows with error in src/bar/baz.c] $ cd work/foo-1.0/src/bar [dig here and there and finally find that the problem in baz.c] $ cp baz.c baz.c.orig $ vi baz.c [fixing it] $ patchtool baz.c [reading diff] $ patchtool -a baz.c Generating patchfile: patch-src_bar_baz.c...ok $ cd ../../../../ $ make [works as expected, wow!] $ make install clean $ send-pr [...] 2. Generation mode when target patchfile already exists (Minor port update). $ cd /somewhere/foo ; make [...] 1 out of 4 hunks failed--saving rejects to Makefile.rej >> Patch patch-aa failed to apply cleanly. *** Error code 1 $ cd work/foo-1.0 [examining Makefile.rej] $ vi Makefile [merging changes by hand] $ patchtool Makefile [reading diff] $ patchtool -a Makefile Target patchfile "patch-aa" already exists, do you want to replace it? [y/N]: y Generating patchfile: patch-aa...ok $ cd ../../ $ make clean $ make install clean $ send-pr [...] 3. "Gross" update mode (Major update, when several existing patches do not apply cleanly). $ cd /somewhere/foo $ vi Makefile [increase PORTVERSION] $ make fetch makesum patch [several patches are failing to apply cleanly] $ cd work/foo-1.0 [doing merging work, finally all changes are merged] $ cd ../../ ; make all install [compile and works like a charm] $ pwd /somewhere/foo $ patchtool -u ./ Updating patchfile: patch-aa Updating patchfile: patch-as Updating patchfile: patch-foo.c Updating patchfile: patch-foo_bar.c $ make clean $ send-pr [...]