Whamcloud - gitweb
7d4c4b66f64a92b3069ad1a0d28f68885f0dbf06
[fs/lustre-release.git] / lustre / kernel_patches / scripts / docco.txt
1 Patch management scripts
2 Andrew Morton <akpm@digeo.com>
3 18 October 2002
4
5 This is a description of a bunch of shell scripts which I use for
6 managing kernel patches.  They are quite powerful.  They can be used on
7 projects other than the linux kernel.  They are easy to use, and fast.
8
9 You end up doing a ton of recompiling with these scripts, because
10 you're pushing and popping all the time.  ccache takes away the pain of
11 all that.  http://ccache.samba.org/ - be sure to put the cache
12 directory on the same fs as where you're working so that ccache can use
13 hardlinks.
14
15 The key philosophical concept is that your primary output is patches. 
16 Not ".c" files, not ".h" files.  But patches.  So patches are the
17 first-class object here.
18
19 Installation
20 ============
21
22 You place all the scripts somewhere in your path, or in
23 /usr/lib/patch-scripts.
24
25 Terminology
26 ===========
27
28 The patch scripts require three special directories called "pc",
29 "patches" and "txt".
30
31 If the environment variable PATCHSCRIPTS is set, it is taken to to be
32 the directory in which those three directories reside.  Typically, it
33 would be a relative pathname.  So
34
35         setenv PATCHSCRIPTS ./i-put-them-here
36
37 would tell the patch scripts to look in ./i-put-them-here/pc, etc.
38
39 If PATCHSCRIPTS is not set, and the directory ./patch-scripts is
40 present then the patch scripts will us ./patch-scripts/pc/,
41 ./patch-scripts/patches/ and ./patch-scripts/txt/.
42
43 Otherwise, the patch scripts use ./pc, ./patches and ./txt.
44
45 In this document, the symbol $P is used to describe the directory which
46 holds the pc/, patches/ and txt/ directories, as determined by the
47 above search.
48
49 It is expected that $P will always expand to a relative path.
50
51 Concepts
52 ========
53
54 All work occurs with a single directory tree.  All commands are invoked
55 within the root of that tree.  The scripts manage a "stack" of patches.
56
57 Each patch is a changeset against the base tree plus the preceding patches.
58
59 All patches are listed, in order, in the file ./series.  You manage the
60 series file.
61
62 Any currently-applied patches are described in the file
63 ./applied-patches.  The patch scripts manage this file.
64
65 Each patch affects a number of files in the tree.  These files are
66 listed in a "patch control" file.  These .pc files live in the
67 directory $P/pc/
68
69 Patches are placed in the directory $P/patches/
70
71 Documentation for the patches is placed in $P/txt/
72
73 So for a particular patch "my-first-patch" the following will exist:
74
75 - An entry "my-first-patch.patch" in ./series
76
77 - An entry "my-first-patch" in ./applied-patches (if it's currently applied)
78
79 - A file $P/pc/my-first-patch.pc which contains the names of the
80   files which my-first-patch modifies, adds or removes
81
82 - A file $P/txt/my-first-patch.txt which contains the patch's
83   changelog.
84
85 - A file $P/patches/my-first-patch.patch, which is the output of the
86   patch scripts.
87
88 Operation
89 =========
90
91 When a patch "my-patch" is applied with apatch, or with pushpatch
92 (which calls apatch), all the affected files (from $P/pc/my-patch.pc)
93 are copied to files with ~my-patch appended.  So if $P/pc/my-patch.pc
94 contained
95
96         kernel/sched.c
97         fs/inode.c
98
99 then apatch will copy those files into kernel/sched.c~my-patch and
100 fs/inode.c~my-patch.  It will then apply the patch to kernel/sched.c
101 and fs/inode.c
102
103 When a diff is regenerated by refpatch (which calls mpatch), the diff
104 is made between kernel/sched.c and kernel/sched.c~my-patch.  How do the
105 scripts know to use "~my-patch"?  Because my-patch is the current
106 topmost patch.  It's the last line in ./applied-patches.
107
108 In this way, the whole thing is stackable.  If you have four patches
109 applied, say "patch-1", "patch-2", "patch-3" and "patch-4", and if
110 patch-2 and patch-4 both touch kernel/sched.c then you will have:
111
112         kernel/sched.c~patch-2          Original copy, before patch-2
113         kernel/sched.c~patch-4          Copy before patch-4.  Contains changes
114                                         from patch-2
115         kernel/sched.c                  Current working copy.  Contains changes
116                                         from patch-4.
117
118 This means that your diff headers contain "~patch-name" in them, which
119 is convenient documentation.
120
121 Walkthrough
122 ===========
123
124 Let's start.
125
126 Go into /usr/src/linux (or wherever)
127
128         mkdir pc patches txt
129
130 Now let's generate a patch
131
132         fpatch my-patch kernel/sched.c
133
134 OK, we've copied kernel/sched.c to kernel/sched.c~my-patch.  We've
135 appended "my-patch" to ./applied-patches and we've put "kernel/sched.c"
136 into the patch control file, pc/my-patch.pc.
137
138         Now edit kernel/sched.c a bit.
139
140 Now we're ready to document the patch
141
142         Now write txt/my-patch.txt
143
144 Now generate the patch
145
146         refpatch
147
148 This will generate patches/my-patch.patch.  Take a look.
149
150 Now remove the patch
151
152         poppatch
153
154 applied-patches is now empty, and the patch is removed.
155
156 Now let's add a file to my-patch and then generate my-second-patch:
157
158         Add "my-patch.patch" to ./series (no blank lines in that file please)
159
160         pushpatch
161
162 OK, the patch is applied again.  Let's add another file
163
164         fpatch kernel/printk.c
165
166 Note that here we gave fpatch a single argument.  So rather than
167 opening a new patch, it adds kernel/printk.c to the existing topmost
168 patch.  That's my-patch.
169
170         Edit kernel/printk.c
171
172 Refresh my-patch (you end up running refpatch a lot)
173
174         refpatch
175
176 Now start a second patch:
177
178         fpatch my-second-patch kernel/sched.c
179
180 Now take a look at applied-patches.  Also do an `ls kernel/sched*'.
181
182         Edit kernel/sched.c, to make some changes for my-second-patch
183
184 Generate my-second-patch:
185
186         refpatch
187
188 Take a look in patches/my-second-patch.patch
189
190 Don't forget to add "my-second-patch.patch" to the series file.
191
192 And remove both patches:
193
194         poppatch
195         poppatch
196
197
198 That's pretty much it, really.
199
200
201 Command reference
202 =================
203
204 Generally, where any of these commands take a "patch-name", that can be
205 of the form txt/patch-name.txt, patch-name.pc, just patch-name or
206 whatever.  The scripts will strip off a leading "txt/", "patches/" or
207 "pc/" and any trailing extension.  This is so you can do
208
209         apatch patches/a<tab>
210
211 to conveniently use shell tabbing to select patch names.
212
213
214
215 added-by-patch
216
217   Some internal thing.
218
219 apatch [-f] patch-name
220
221   This is the low-level function which adds patches.  It does the
222   copying into ~-files and updates the applied-patches file.  It
223   applies the actual patch.
224
225   apatch will do a patch --dry-run first and will refuse to apply the
226   patch if the dryrun fails.
227
228   So when you are getting rejects you do this:
229
230         pushpatch               # This fails, due to rejects.  Drat.
231         apatch -f patch-name    # Force the patch
232   (or)  pushpatch -f            # Force the patch
233
234   OK, you've now applied patch-name, but you have rejects.  Go fix
235   those up and do
236
237         refpatch
238
239   And you're ready to move on.
240
241 combine-series output-file
242
243   It incrementally combinediffs all the patches in series to make a
244   complete patch for the series.  Requires combinediff frmo patchutils.
245
246   See http://cyberelk.net/tim/patchutils/ (Don't download the
247   "experimental" patchutils - it seems to only have half of the
248   commands in it.  Go for "stable")
249
250 cvs-take-patch
251
252   I forget.
253
254 export_patch
255
256   export the patches listed in ./series to a set of files which
257   are named in such a way that the sort order is the same as the
258   order of the series file. 
259
260   Usage:  export_patch directory [prefix]
261
262   Example:
263         
264         Suppose ./series contains
265         
266         mango.patch
267         orange.patch
268         banana.patch
269         apple.patch
270         pear.patch
271
272         export_patch ../mypatches fruit 
273         
274         The patches would be copied to
275
276         ../mypatches/p00001_fruit_mango.patch
277         ../mypatches/p00002_fruit_orange.patch
278         ../mypatches/p00003_fruit_banana.patch
279         ../mypatches/p00003_fruit_banana.patch
280         ../mypatches/p00003_fruit_banana.patch
281
282         Named in this way, someone may easily apply them:
283
284         cat mypatches/p*fruit* | patch -p1
285
286         If prefix is omitted, the patchnames will be transformed
287         such that "original.patch" becomes "pXXXXX_original.patch".
288
289 fpatch [patch-name] foo.c
290
291   If patch-name is given, fpatch will start a new patch which
292   modifies (or adds, or removes) the single file foo.c.  It updates
293   ./applied-patches and creates pc/patch-name.pc.  fpatch will copy
294   foo.c to foo.c~patch-name in preparation for edits of foo.c.
295
296   If patch-name is not given then fpatch will add foo.c to the
297   current topmost patch.  It will add "foo.c" to $P/pc/$(toppatch).pc. 
298   It will copy foo.c to foo.c~$(toppatch).
299
300 import_patch
301
302   Imports a set of patch files, creating $P/pc, $P/txt, $P/patches and
303   ./series as necessary.  It also creates $P/txt/*.txt by stripping 
304   off the top of the patches (and removes any diffstat output it finds, 
305   so that it can eat refpatch output and export_patch output.)  The 
306   imported patch names are appended to the series file.
307
308   In creating the $P/txt/*.txt files, mail headers are stripped with 
309   formail, preserving the "From:" and "Subject:" lines.  "DESC" and
310   "EDESC" markers are added if they are not already present, using the
311   "From:" and "Subject:" lines for the DESC portion, if they are present.
312   (See "patchdesc" command, below, for more on these markers.)
313
314   Also, it can rename the patch file as it is imported by stripping out
315   a pattern.  This is useful if, as often is the case, you have patch 
316   sets with filenames designed to help sort the patches into the correct 
317   order, such as "p001_xxx_funky_stuff.patch" you can have it automatically
318   renamed to funky_stuff.patch on import, and let the series file manage
319   the ordering.
320
321   Import_patch will uncompress patches (*.Z, *.bz2, *.gz) as necessary.
322
323   Usage:
324
325   import_patch [-p pattern] patchfile ...
326
327   Example:
328
329         % ls ../fruit/p*patch
330         ../fruit/p00001_northern_apple.patch
331         ../fruit/p00001_tropical_mango.patch
332         ../fruit/p00002_northern_pear.patch
333         ../fruit/p00002_tropical_orange.patch
334         ../fruit/p00003_tropical_banana.patch
335         % import_patch -p 'p[0-9]*_tropical_' ../fruit/p*tropical*
336         Recreated pc/mango.pc
337         Recreated pc/orange.pc
338         Recreated pc/banana.pc
339         % import_patch -p 'p[0-9]*_northern_' ../fruit/p*northern*
340         Recreated pc/apple.pc
341         Recreated pc/pear.pc
342
343   Then you can "pushpatch; refpatch" 5 times.
344
345 inpatch
346
347   List the names of ths files which are affected by the current
348   topmost patch.
349
350   This is basically
351
352         cat pc/$(toppatch).pc
353
354 mpatch
355
356   A low-level thing to generate patches
357
358 new-kernel
359
360   Some thing I use for importing a new kernel from kernel.org
361
362 p0-2-p1
363
364   Internal thing to convert patch -p0 form into patch -p1
365
366 patchdesc
367
368   Generates a single-line description of a patch.
369
370   The txt/my-patch.txt files have the following format:
371
372   <start of file>
373   DESC
374   some short description
375   EDESC
376
377   The long description
378   <end of file>
379
380   I use
381
382         patchdesc $(cat series)
383
384   to generate short-form summaries of the patch series.
385
386 patchfns
387
388   Internal utilities
389
390 pcpatch
391
392   Standalone tool to generate a .pc file from a patch.
393
394   Say someone sends you "his-patch.diff".  What you do is:
395
396         cp ~/his-patch.diff patches/his-patch.patch
397         pcpatch his-patch
398
399   This generates $P/pc/his-patch.pc and you're all set.  Add
400   "his-patch.patch" to ./series in the right place and start pushing.
401
402 p_diff
403
404   I forget
405
406 poppatch
407
408   Remove one or more patches from the current stack.  This command
409   does *not* use the series file.  It works purely against
410   applied-patches.
411
412   Usage:
413
414         poppatch
415                 Remove the topmost patch
416         poppatch 10
417                 Remove ten patches
418         poppatch some-patch-name[.patch]
419                 Remove patches until "some-patch-name" is top patch
420
421 pstatus
422
423         Shows status of patches
424
425   Usage:
426         pstatus [patchfile ...]
427         
428         One line per patch is output showing:
429         1: Patch number in the series file
430         2: Whether the patch is currently applied
431         3: Name of patch
432         4: Status of the patch (needs pcpatch, changelog, refpatch)
433
434         If no patchfiles are specified, $P/patches/*.patch
435         are assumed.
436
437   Caveats:
438         A patch set which contains separate patches to add a file
439         and modify that same file may give spurious "Needs refpatch"
440         status for the patch which adds the file or the topmost patch.
441
442 ptkdiff
443
444   Two modes:
445
446         ptkdiff -
447
448                Run tkdiff against all the file affected
449                by $(toppatch).  The diff is only for the changes made
450                by the top patch! ie: it's between "filename" and
451                "filename~toppatch-name".
452
453         ptkdiff filename
454
455                Just run tkdiff against that file,
456                showing the changes which are due to toppatch.
457
458 pushpatch [-f]
459
460   Apply the next patch, from the series file.
461
462   This consults ./applied-patches to find out the top patch, then
463   consults ./series to find the next patch.  And pushes it.
464
465     pushpatch
466
467       Apply the next patch
468
469     pushpatch 10
470  
471       Apply the next ten patches
472
473     pushpatch some-patch-name
474
475       Keep pushing patches until "some-patch-name" is toppatch
476
477     pushpatch -f
478
479       Push the next patch, ignoring rejects.
480
481 refpatch
482
483     regnerates the topmost patch.  Reads all the affected files
484     from pc/$(toppatch).pc and diffs them against their tilde-files.
485
486     Also pastes into the patch your patch documentation and
487     generates a diffstat summary.
488
489 removed-by-patch
490
491   Some thing.
492
493 rename-patch
494
495   CVS rename for patches.
496
497 rolled-up-patch
498
499   Bit of a hack.  Is designed to generate a rolled-up diff of all
500   currently-applied patches.  But it requires a ../linux-2.x.y tree to
501   diff against.  Needs to be redone.
502
503 rpatch
504
505   Internal command
506
507 split-patch
508
509   Some thing someone write to split patches up.  I don't use it.
510
511 tag-series
512
513   Assuming you keep pc/*, patches/* and txt/* under CVS revision
514   control, tag-series allows you to tag a patchset's individual
515   components.  I use
516
517         tag-series s2_5_44-mm3 pc/2.5.44-mm3-series
518
519   which will attach the cvs tag "s2_5_44-mm3" to every .pc, .patch
520   and .txt file which is mentioned in the series file
521   "pc/2.5.44-mm3-series".
522
523   It will also tag pc/2.5.44-mm3-series, which is a bit redundant
524   given that I use a different series file for each patchset release..
525
526
527 toppatch
528
529   Print the name of the topmost patch.  From ./applied-patches
530
531 touched-by-patch patch-filename
532
533   List the names of files which are affected by a diff.
534
535 unitdiff.py
536
537   Rasmus Andersen's script to convert a diff into minimum-context
538   form.  This form has a better chance of applying if you're getting
539   nasty rejects.  But patch can and will make mistakes when fed
540   small-context input.
541
542
543 Work Practices
544 ==============
545
546 I keep the kernel tree, the $P/pc/, $P/patches/ and $P/txt/ contents under
547 CVS control.  This is important...
548
549 I have several "series" files.  I keep these in $P/pc/foo-series and use
550
551         ln -s pc/foo-series series
552
553 when I'm working on foo.
554
555 If someone sends me a patch I'll do:
556
557         cp ~/whatever patches/his-patch.patch
558         pcpatch his-patch
559         apatch his-patch
560
561   If apatch fails then run `apatch -f his-patch' and fix the rejects.
562
563         refpatch
564
565   to clean up any fuzz.
566
567         poppatch
568         cvs add pc/his-patch.pc patches/his-patch.patch
569         cvs commit pc patches
570
571   Now edit ./series and place "his-patch.patch" in the appropriate place.
572
573
574 If you're working on a particular patch (say, "dud-patch") and you
575 balls something up, just run:
576
577         refpatch        # Generate the crap patch
578         poppatch        # Remove it all
579         rm patches/dud-patch.patch
580         cvs up patches/dud-patch.patch
581
582 and all is well.
583
584
585 Getting updates from Linus
586 ==========================
587
588 What I do is to grab the latest -bk diff from
589 http://www.kernel.org/pub/linux/kernel/people/dwmw2/bk-2.5/
590 and do:
591
592         gzip -d < cs<tab> > patches/linus.patch
593         pcpatch linus
594         apatch linus | grep diff
595
596                Now fix up all the files which got deleted,
597                because there's something wrong with bitkeeper diffs:
598
599         cvs up -ko <missing files from the above diff>
600
601         apatch linus
602         $EDITOR linus/linus.txt
603         
604                 Add the changeset number to txt/linus.txt
605
606         refpatch
607         poppatch
608
609   Now add "linus.patch" as the first entry in your ./series file and
610   start pushing your other patches on top of that.
611
612 BUGS
613 ====
614
615 Tons and tons.  The scripts are fragile, the error handling is ungraceful and
616 if you do something silly you can end up in a pickle.
617
618 Generally the scripts are very careful to not wreck your files or your
619 patches.  But they can get the ./applied-patches and ~-files into an
620 awkward state.
621
622 Usually you can sort it out by copying the ~-files back onto the originals
623 and removing the last line from ./applied-patches.  Or do a "refpatch ;
624 poppatch ; rm patches/troublesome-patch.patch ; cvs up patches".
625
626 If it's really bad, just blow away the entire tree and do a new CVS checkout.
627
628
629 Working on non-kernel projects
630 ==============================
631
632 Well it's the same thing.  Say you've downloaded a copy of util-linux
633 and you want to make a change:
634
635         cd /usr/src
636         tar xvfz ~/util-linux.tar.gz
637         cd util-linux
638         mkdir pc patches txt
639         fpatch my-patch sys-utils/rdev.c
640         fpatch sys-utils/ipcs.8
641         <edit, edit>
642         refpatch
643         <ship patches/my-patch.patch>
644
645 How to balls things up
646 ======================
647
648 Well here's one way.  Suppose you have 20 patches applied, and three of
649 them (say, "p1", "p6" and "p11") all modify "foo.c".
650
651 Now you go and change foo.c.
652
653 Well, to which patch does that change belong?  You need to decide. 
654 Let's say you decide "p6".
655
656 If you run `refpatch' when "p11" is toppatch then you lose.  The diff
657 went into p11.
658
659 What you can do is:
660
661 1:
662         poppatch p6
663         <edit>
664         refpatch
665         pushpatch p11
666         <test>
667
668   (See why ccache is looking good?)
669
670 or
671
672 2:
673         <edit>
674         <test>
675         poppatch p6     <hope like hell that the other patches remove cleanly>
676         refpatch
677
678
679 Another good way of ballsing up is to cheat.  Say "oh I just want to make
680 this one-line change".  And "oh, and this one".
681
682 Now you're getting in a mess.  It's much, much better to just use the system:
683
684         fpatch junk file1
685         fpatch file2
686         <edit>
687         <play>
688         refpatch
689         poppatch
690         rm pc/junk.pc patches/junk.patch
691
692 Merging with -mm kernels
693 ========================
694
695 Haven't tried this, but it should work:
696
697 - Grab all the patches from broken-out/, place them in your $P/patches/
698
699 - Copy my series file into ./series (or $P/pc/akpm-series and symlink it)
700
701 - pushpatch 99
702
703 And you're off and running.  The nice thing about this is that you can
704 send me incremental diffs to diffs which I already have.
705
706 Or whatever.  I'm fairly handy with diffs nowadays.  Rejects are
707 expected.  I just prefer to have "one concept per diff".
708