1INTRODUCTION
2------------
3Patchtool is a tool aimed to simplify common operations with patchfiles. It
4was designed using real world's experience with the subject and expected to be
5very handy for an active porter.
6
7
8MODES OF OPERATION
9------------------
10The tool has the following two basic modes of operation:
11o generation/update of patchfiles. In this mode user provides list of working
12  files for which patchfiles are to be generated and the tool generates or
13  updates corresponding patches automatically guessing if there is an original
14  version (.orig file, rcs(1)) or it is a completely new file;
15
16o automatic update of the existing patchfiles. In this mode user provides a
17  list of patchfiles or directories containing patchfiles and the tool
18  re-generates specified patches. In this mode the tool tries hard to guess
19  whether the patchfile in question is already up to date or not and updates
20  only those patchfiles, which are found to be outdated.
21
22The following options are supported:
23  -a -- automatically save resulting diff into a patchfile;
24  -f -- don't ask any question if target patchfile already exists and is to be
25        replaced;
26  -u -- run tool in the "update" mode (see above);
27  -i -- perform requested operation (generate or update) even if the
28	patchfile seems to be up-to-date based on last modification time of
29	all files involved.
30
31The tool supports dozen environment variables that can be used to override
32default settings. You can find complete list at the top of patchtool.py,
33following are the most useful ones:
34PT_CVS_ID	-- CVS id to be added at the top of each patchfile generated
35		   ("FreeBSD");
36PT_DIFF_ARGS	-- diff(1) args used to generate patchfile ("-du");
37PT_DIFF_SUFX	-- suffix used to save original version of the file (".orig");
38
39
40KNOWN BUGS AND LIMITATIONS
41--------------------------
42o It is assumed that each patchfile contains exactly one diff, so the tool
43  may remove useful diffs when there are several diffs merged into one
44  patchfile. Actually I don't think that it is a bug, because Porter's
45  Handbook clearly demands to follow a "one diff - one patchfile" rule.
46  Perhaps portlint(1) should be extended to warn about such abuses;
47
48o only '+++' supported as the prefix for the name of target file in the
49  patchfile. Neither '***' nor 'Index:' are not recognised/supported yet;
50
51o please keep in mind that when you are trying to do automatic update and
52  some of the patches are for auto-generated/mangled files (e.g. configure
53  script in the situation when USE_LIBTOOL is used) then you would end up
54  with some of patchfiles containing bogus hunks;
55
56o by default the tool tries to recognise saved original version on the file
57  first by probing file with '.orig' suffix added and if it fails then by
58  probing file with ',v' suffix added. If you use other suffix to save
59  original version, for example '~', then set PT_DIFF_SUFX environment
60  variable to match your settings, otherwise the tool will not function
61  properly.
62
63
64REPORTING BUGS AND PROPOSING ENHANCEMENTS
65-----------------------------------------
66The author of the tool is Maxim Sobolev <sobomax@FreeBSD.org>. Any bug
67reports, patches, proposals or suggestions are encouraged. You can do it
68either contacting author directly at the e-mail above or submitting a FreeBSD
69problem report.
70
71
72EXAMPLES
73--------
74Following are several sample sessions which show common usage patterns for
75this tool.
76
771. Generation mode (useful when creating new port).
78$ cd /somewhere/foo ; make
79[compilation blows with error in src/bar/baz.c]
80$ cd work/foo-1.0/src/bar
81[dig here and there and finally find that the problem in baz.c]
82$ cp baz.c baz.c.orig
83$ vi baz.c
84[fixing it]
85$ patchtool baz.c
86[reading diff]
87$ patchtool -a baz.c
88Generating patchfile: patch-src_bar_baz.c...ok
89$ cd ../../../../
90$ make
91[works as expected, wow!]
92$ make install clean
93$ send-pr
94[...]
95
962. Generation mode when target patchfile already exists (Minor port update).
97$ cd /somewhere/foo ; make
98[...]
991 out of 4 hunks failed--saving rejects to Makefile.rej
100>> Patch patch-aa failed to apply cleanly.
101*** Error code 1
102$ cd work/foo-1.0
103[examining Makefile.rej]
104$ vi Makefile
105[merging changes by hand]
106$ patchtool Makefile
107[reading diff]
108$ patchtool -a Makefile
109Target patchfile "patch-aa" already exists, do you want to  replace it? [y/N]: y
110Generating patchfile: patch-aa...ok
111$ cd ../../
112$ make clean
113$ make install clean
114$ send-pr
115[...]
116
1173. "Gross" update mode (Major update, when several existing patches do not apply
118   cleanly).
119$ cd /somewhere/foo
120$ vi Makefile
121[increase PORTVERSION]
122$ make fetch makesum patch
123[several patches are failing to apply cleanly]
124$ cd work/foo-1.0
125[doing merging work, finally all changes are merged]
126$ cd ../../ ; make all install
127[compile and works like a charm]
128$ pwd
129/somewhere/foo
130$ patchtool -u ./
131Updating patchfile: patch-aa
132Updating patchfile: patch-as
133Updating patchfile: patch-foo.c
134Updating patchfile: patch-foo_bar.c
135$ make clean
136$ send-pr
137[...]
138