summaryrefslogtreecommitdiffstats
path: root/doc/main.tex
blob: 71e2e2ffd63b5acf1a02baed7c666f11e5ae2e6c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
%\documentclass[a4paper]{article}
\documentclass[letter]{article}
\usepackage{graphicx}
\usepackage{subfigure}
\usepackage{fancyvrb}
%\usepackage{times}
\usepackage[latin1]{inputenc}
\usepackage{url}

%\usepackage{lineno}
%\linenumbers
%\renewcommand{\baselinestretch}{1.5}

% Change url font to textsf (and check what breaks in PDF/HTML/...)

\fvset{xleftmargin=3em,commandchars=\\\{\}}

\newcommand{\quilt}[1]{\textsf{quilt #1}}
\newcommand{\sh}[1]{\textsl{#1}}
\newcommand{\prog}[1]{\textit{#1}}

\title{How To Survive With Many Patches\\
{\Large or}\\
Introduction to Quilt\footnote{
	Quilt is a non-GNU project hosted on GNU Savannah.  Some ideas
	for this document were taken from \textit{docco.txt} in
	Andrew Morton's patch management scripts package~\cite{akpm02}.
	The text in the examples was taken from \textit{A Midsummer
	Night's Dream} by William Shakespeare.
}}
\author{Andreas Grünbacher, SuSE Labs \\
%\em{SUSE Labs, SUSE LINUX AG} \\
{\normalsize agruen@suse.de}
}
%\date{}

\begin{document}

\maketitle

\thispagestyle{empty}

\begin{abstract}
After looking at different strategies for dealing with software packages
that consist of a base software package on top of which a number of
patches are applied, this document introduces the script collection
\textit{quilt,} which was specifically written to help deal with
multiple patches and common patch management tasks.
\end{abstract}

\section{Introduction}

% Prerequisites: UNIX, patches, using GNU diff and GNU patch.
% Why patches in the first place?

In the old days, vendor specific software packages in the open source
world consisted of a file with the official version of the software,
plus a patch file with the additional changes needed to adapt the
package to specific needs. The official software package was usually
contained in a \textsf{package.tar.gz} file, while the patch was found
in \textsf{package.diff.} Instead of modifying the official
package sources, local changes were kept separate. When building the
software package, the tar archive was extracted, and the patch was
applied.

Over time, the patch file ended up containing several independent
changes. Of those changes, some were integrated into later versions of
the software, while otheradd-ons or adaptations remain external. Whenever
a new official version was integrated, the patch needed to be revised:
changes that were already integrated in the official version needed to
be split from changes that were not.

A big improvement was to allow multiple patches in a vendor package,
and this is also how patches are handled today: a number of
patches is applied on top of each other. Each patch usually consists of
a logically related set of changes. When some patches get integrated
upstream, those patches can simply be removed from the vendor specific
package. The remaining patches frequently continue to apply cleanly.
Some of the remaining patches may have to be maintained across a range
of upstream versions because they are too specific for the upstream
software package, etc. These patches often get out of sync, and need to
be updated.

For the majority of packages, the number of patches remains relatively
low, so maintaining those patches without tools is feasible. A number of
packages have dozens of patches, however. At the extreme end is the
kernel source package (kernel-source-\textit{2.4.x}) with more than
1\,000 patches.  The difficulty of managing such a vast number of
patches without tools can easily be imagined.

This document discusses different strategies of dealing with large sets
of patches. Patches are usually generated by the \prog{diff} utility,
and applied with the \prog{patch} utility.  Different patch file formats are
defined as part of the specification of the \prog{diff} utility in
POSIX.1~\cite{posix-2001-diff}.  The most commonly used format today,
\textit{unified diff,} is not covered by POSIX.1, however.  A good
description of patch file formats is found in the \prog{GNU diff} info
pages~\cite{info-diff}.

The question we try to answer in this document is how patches are best kept
up to date in face of changes both to the upstream software package, and
to the patches that precede them.  After looking at some existing
approaches, a collection of patch management scripts known as
\textit{quilt} is described~\cite{quilt}, starting with basic concepts,
and progressing towards more advanced tasks.

% - quilt
% (wet people's mouths about the features)

% How exactly does this relate to many patches?

\section{Existing Approaches}
\label{sec:existing}

The minimal solution for updating a patch is to apply all preceding
patches.
%\footnote{ In the kernel CVS, we have a a script called
%\textit{sequence-patch} that simply applies all patches up to a
%specified patch.  }
Then, a copy of the resulting source tree is created.\footnote{
	The two copies can also be hard-linked with each other, which
	significantly speeds up both the copying and the final
	``diffing''. If hard links are used, care must be taken that the
	tools used to update one copy of the source tree will create new
	files, and will not overwrite shared files. Editors like
	\prog{emacs} and \prog{vi}, and utilities like \prog{patch},
	support this.
} The next patch in the sequence of patches (which is the one to be
updated) is applied to only one of these source trees. This source tree
is the modified until it reflects the desired result. The new version of
the patch is distilled by comparing the two source trees with
\prog{diff}, and writing the result into a file.

This simple approach is rather error prone, and leaves much to be
desired. Several people have independently written scripts that
automate and improve upon this process.

A version control system like \prog{CVS} or \prog{RCS} may be a
reasonable alternative in some cases. The version control system is
brought in the state of the working tree with a number of patches
applied. Then the next patch is applied. After the working tree is
updated as required, a diff between the repository copy and the working
tree is created (with \prog{cvs diff}, etc). In this scenario the
version control system is used to store and compare against the old
repository version only. The full version control overhead is paid,
while only a small fraction of its functionality is needed. Switching
between different patches is not simplified.

% TODO: Mention some approaches here; RCS and CVS ...

One of the most advanced approaches is Andrew Morton's patch management
scripts~\cite{akpm02}.  The author of this document found that none of
the available solutions would scale up to the specific requirements of
the SUSE kernel-source package, and started to improve Andrew Morton's
scripts until they became what they are now~\cite{quilt}.

% - Re and Rd scripts (Czech scripts using RCS, replaces the
%   now-obsolete rpmpatch that supports one .dif only).
% - Werner's scripts

% What couldn't be done:
% - Patches in sub-directories
% - Many patches
% - Retaining documentation (akpm's scripts do part of this)

% Actually merging rejects is not handled; use tools like:
% - wiggle
% - Other merge tools (e.g., graphical ones)

\section{Quilt: Basic Concepts and Operation}

The remainder of this document discusses the script collection
\textit{quilt.}

With quilt, all work occurs within a single directory tree. Commands are
invoked in the root of that tree.  Commands are of the form
``\quilt{cmd},'' similar to CVS commands. They can be abbreviated as
long as the specified part of the command is unique. All commands print
some help text with ``\quilt{cmd -h}.''

Quilt manages a stack of patches. Patches are applied incrementally on
top of the base tree plus all preceding patches. They can be pushed
on top of the stack (\quilt{push}), and popped off the stack
(\quilt{pop}).  Commands are available for querying the contents of the
series file (\quilt{series}, see below), the contents of the stack
(\quilt{applied}, \quilt{previous}, \quilt{top}), and the patches that
are not applied at a particular moment (\quilt{next}, \quilt{unapplied}).
By default, most commands apply to the topmost patch on the stack.

Patch files are located in the \textsf{patches} sub-directory of the
source tree (see Figure~\ref{fig:dir-layout}). The \textsf{QUILT\_PATCHES}
environment variable can be used to override this location. The
\textsf{patches} directory may contain sub-directories.
\textsf{patches} may also be a symbolic link instead of a directory.

A file called \textsf{series} contains a list of patch file names that
defines the order in which patches are applied. Unless there are means
by which series files can be generated automatically (see
Section~\ref{sec:rpm}), they are usually provided along with a set of
patches. In \textsf{series}, each patch file name is on a separate line.
Patch files are identified by pathnames that are relative to the
\textsf{patches} directory; patches may be in sub-directories below the
\textsf{patches} directory.  Lines in the series file that start with a
hash character (\texttt{\#}) are ignored.  When quilt adds, removes, or
renames patches, it automatically updates the series file.  Users of
quilt can modify series files while some patches are applied, as long as
the applied patches remain in their original order.

There is no notion of different development branches, but different
series files can be used to assemble patches in different ways.

\begin{figure}
\begin{center}
\begin{minipage}{6cm}
\begin{small}
\begin{Verbatim}
work/ -+- ...
       |- patches/ -+- series
       |            |- patch2.diff
       |            |- patch1.diff
       |            +- ...
       +- .pc/ -+- applied-patches
                |- patch1/ -+- ...
                |- patch2/ -+- ...
                +- ...
\end{Verbatim}
\end{small}
\end{minipage}
\caption{Quilt files in a source tree.}
\label{fig:dir-layout}
\end{center}
\end{figure}

Before a patch is applied (or ``pushed on the stack''), copies of all
files the patch modifies are saved to the \textsf{.pc/\textit{patch}}
directory.\footnote{
	The patch name with extensions stripped is used as the name of
	the sub-directory below the \textsf{.pc} directory.  \prog{GNU patch},
	which quilt uses internally to apply patches, creates backup
	files and applies the patch in one step.
} The patch is added to \textsf{.pc/applied-patches}, the list of
currently applied patches.  Later when a patch is regenerated
(\quilt{refresh}), the backup copies in \textsf{.pc/\textit{patch}} are
compared with the current versions of the files in the source tree
using \prog{GNU diff}.

Documentation related to a patch can be put at the beginning of a patch
file.  Quilt is careful to preserve all text that precedes the actual
patch when doing a refresh. (This is limited to patches in unified
format; see~\cite{info-diff}).

The series file is looked up in the root of the source tree, in the
patches directory, and in the \textsf{.pc} directory.  The first series
file that is found is used. This may also be a symbolic link, or a file
with multiple hard links.  Usually, only one series file is used for a
set of patches, so the \textsf{patches} sub-directory is a convenient
location.

The \textsf{.pc} directory and its sub-directories cannot be relocated,
but \textsf{.pc} may be a symbolic link. While patches are applied to
the source tree, the \textsf{.pc} directory is essential for many
operations, including taking patches off the stack (\quilt{pop}), and
refreshing patches (\quilt{refresh}). Files in the \textsf{.pc}
directory are automatically removed when they are no longer needed, so
usually there is no need to clean up manually.

\section{An Example}
\label{sec:basic}

This section demonstrates how new patches are created and updated, and
how conflicts are resolved. Let's start with a short text file:

\begin{small}
\begin{Verbatim}
Yet mark'd I where the bolt of Cupid fell:
It fell upon a little western flower,
Before milk-white, now purple with love's wound,
And girls call it love-in-idleness.
\end{Verbatim}
\end{small}

New patches are created with \quilt{new}. A new patch automatically
becomes the topmost patch on the stack. Files must be added to a patch
with \quilt{add} before they are modified. Note that this is slightly
different from the CVS style of interaction: with CVS, files are in the
repository, and adding them before committing (but after modifying them)
is enough.  Files are usually added and immediately modified. The
command \quilt{edit} adds a file and loads it into the default editor.
(The environment variable \textsf{EDITOR} specifies which is the default
editor.  If \textsf{EDITOR} is not set, \prog{vi} is used.)

\begin{small}
\begin{Verbatim}
\sh{$ quilt new flower.diff}
Patch flower is now on top
\sh{$ quilt edit Oberon.txt}
File Oberon.txt added to patch flower
\end{Verbatim}
\end{small}

Let's assume that the following lines were added to \textsf{Oberon.txt}
during editing:

\begin{small}
\begin{Verbatim}
The juice of it on sleeping eye-lids laid
Will make a man or woman madly dote
Upon the next live creature that it sees.
\end{Verbatim}
\end{small}

The actual patch file is created (and later updated) with
\quilt{refresh}. The result is as follows:\footnote{
	Timestamps in patches are omitted from the output in the examples.
}

\begin{small}
\begin{Verbatim}
\sh{$ quilt refresh}
\sh{$ cat patches/flower.diff}
Index: example1/Oberon.txt
===================================================================
--- example1.orig/Oberon.txt
+++ example1/Oberon.txt
@@ -2,3 +2,6 @@
 It fell upon a little western flower,
 Before milk-white, now purple with love's wound,
 And girls call it love-in-idleness.
+The juice of it on sleeping eye-lids laid
+Will make a man or woman madly dote
+Upon the next live creature that it sees.
\end{Verbatim}
\end{small}

Now let's assume that a line in the text has been overlooked, and must
be inserted. The file \textsf{Oberon.txt} is already part of the patch
\textsf{flower.diff}, so it can immediately be modified in an editor.
Alternatively, \quilt{edit} can be used; it simply opens up the default
editor if the file is already part of the patch.

After the line is added, we use \quilt{diff -z} to see a diff of the
changes we made:

\begin{small}
\begin{Verbatim}
\sh{$ quilt diff -z}
Index: example1/Oberon.txt
===================================================================
--- example1.orig/Oberon.txt
+++ example1/Oberon.txt
@@ -2,6 +2,7 @@
 It fell upon a little western flower,
 Before milk-white, now purple with love's wound,
 And girls call it love-in-idleness.
+Fetch me that flower; the herb I shew'd thee once:
 The juice of it on sleeping eye-lids laid
 Will make a man or woman madly dote
 Upon the next live creature that it sees.
\end{Verbatim}
\end{small}

A diff of the topmost patch can be generated with \quilt{diff} without
arguments. This does not modify the actual patch file.  The changes are
only added to the patch file by updating it with \quilt{refresh}. Then
we remove the patch from the stack with \quilt{pop}:

\begin{small}
\begin{Verbatim}
\sh{$ quilt refresh}
Refreshed patch flower
\sh{$ quilt pop}
Removing flower
Restoring Oberon.txt

No patches applied
\end{Verbatim}
\end{small}

Next, let's assume that \textsf{Oberon.txt} was modified ``upstream'':
The word \textit{girl} did not fit very well, and so it was replaced
with \textit{maiden.} \textsf{Oberon.txt} now contains:

\begin{small}
\begin{Verbatim}
Yet mark'd I where the bolt of Cupid fell:
It fell upon a little western flower,
Before milk-white, now purple with love's wound,
And maidens call it love-in-idleness.
\end{Verbatim}
\end{small}

This causes \textsf{flower.diff} to no longer apply cleanly.  When we
try to push \textsf{flower.diff} on the stack with \quilt{push}, we get
the following result:

\begin{small}
\begin{Verbatim}
\sh{$ quilt push}
Applying flower
patching file Oberon.txt
Hunk #1 FAILED at 2.
1 out of 1 hunk FAILED -- rejects in file Oberon.txt
Patch flower does not apply (enforce with -f)
\end{Verbatim}
\end{small}

Quilt does not automatically apply patches that have rejects. Patches
that do not apply cleanly can be ``force-applied'' with \quilt{push -f},
which leaves reject files in the source tree for each file that has
conflicts. Those conflicts must be resolved manually, after which the
patch can be updated (\quilt{refresh}). Quilt remembers when a patch has
been force-applied. It refuses to push further patches on top of such
patches, and it does not remove them from the stack.  A force-applied
patch may be ``force-removed'' from the stack with \quilt{pop -f},
however.  Here is what happens when force-applying \textsf{flower.diff}:

\begin{small}
\begin{Verbatim}
\sh{$ quilt push -f}
Applying flower
patching file Oberon.txt
Hunk #1 FAILED at 2.
1 out of 1 hunk FAILED -- saving rejects to file Oberon.txt.rej
Applied flower (forced; needs refresh)
\end{Verbatim}
\end{small}

After re-adding the line of verse from \textsf{flower.diff} to
\textsf{Oberon.txt}, we update the patch with \quilt{refresh}.

\begin{small}
\begin{Verbatim}
\sh{$ quilt edit Oberon.txt}
\sh{$ quilt refresh}
Refreshed patch flower
\end{Verbatim}
\end{small}

Our final version of \textsf{Oberon.txt} contains:

\begin{small}
\begin{Verbatim}
Yet mark'd I where the bolt of Cupid fell:
It fell upon a little western flower,
Before milk-white, now purple with love's wound,
And maidens call it love-in-idleness.
Fetch me that flower; the herb I shew'd thee once:
The juice of it on sleeping eye-lids laid
Will make a man or woman madly dote
Upon the next live creature that it sees.
\end{Verbatim}
\end{small}

\section{Further Commands and Concepts}

This section introduces a few more basic commands, and then describes
additional concepts that may not be immediately obvious.  We do not
describe all of the features of quilt here since many quilt commands are
quite intuitive; furthermore, help text that describes the available
options for each command is available via \quilt{\textit{cmd} -h}.

The \quilt{top} command shows the name of the topmost patch.  The
\quilt{files} command shows which files a patch contains.  The
\quilt{patches} command shows which patches modify a specified file.
With our previous example, we get the following results:

\begin{small}
\begin{Verbatim}
\sh{$ quilt top}
flower
\sh{$ quilt files}
Oberon.txt
\sh{$ quilt patches Oberon.txt}
flower
\end{Verbatim}
\end{small}

The \quilt{push} and \quilt{pop} commands optionally take a number or
a patch name as argument. If a number is given, the specified number of
patches is added (\quilt{push}) or removed (\quilt{pop}). If a patch
name is given, patches are added (\quilt{push}) or removed (\quilt{pop})
until the specified patch is on top of the stack. With the \textsf{-a}
option, all patches in the series file are added (\quilt{push}), or all
applied patches are removed from the stack (\quilt{pop}).

\subsection{Patch Strip Levels}

Quilt assumes that patches are applied with a strip level of one (the
\textsf{-p1} option of \prog{GNU patch}) by default: the topmost directory
level of file names in patches is stripped off. Quilt remembers the
strip level of each patch in the \textsf{series} file. When generating a
diff (\quilt{diff}) or updating a patch (\quilt{refresh}), a different
strip level can be specified, and the series file will be updated
accordingly. Quilt can apply patches with an arbitrary strip level, and
produces patches with a strip level of zero or one. With a strip level
of one, the name of the directory that contains the working tree is used
as the additional path component. (So in our example,
\textsf{Oberon.txt} is contained in directory \textsf{example1}.) 

\subsection{Importing Patches}

The \quilt{import} command automates the importing of patches into the
quilt system. The command copies a patch into the \textsf{patches}
directory and adds it to the \textsf{series} file. For patch strip
levels other than one, the strip level is added after the patch file
name. (An entry for \textsf{a.diff} with strip level zero might read
``{\small \verb|a.diff -p0|}''.)

Another common operation is to incorporate a fix or similar that comes
as a patch into the topmost patch. While there is no specific command
for this, the desired result can be achieved by first adding all the
files that the fix modifies into the patch, and then apply the patch to
the working tree. The following commands achieve this for a patch with
a strip level of one:\footnote{
	\prog{lsdiff} is part of the \textit{patchutils} package, and
	generates a list of files a patch modifies.
}

\begin{small}
\begin{Verbatim}
\sh{$ quilt add `lsdiff --strip 1 patch.diff`}
\sh{$ patch -p1 < patch.diff}
\end{Verbatim}
\end{small}

\subsection{Forking}
\label{sec:forking}

There are situations in which updating a patch in-place is not ideal:
the same patch may be used in more than one series file. It may also
serve as convenient documentation to retain old versions of patches, and
create new ones under different names. This can be done by hand by
creating a copy of a patch (which must not be applied), and updating the
patch name in the series file.

The \quilt{fork} command simplifies this: it creates a copy of the
next patch in the series (the one that \quilt{next} reports), and
updates the series file. Unless a patch name is explicitly specified,
\quilt{fork} will generate the following sequence of patch names:
\textsf{patch.diff}, \textsf{patch-2.diff}, \textsf{patch-3.diff}, \dots

\subsection{Advanced Diffing}

Quilt allows us to diff and refresh patches that are applied, but are not
on top of the stack (\quilt{diff -P \textit{patch}} and \quilt{refresh
\textit{patch}}). This is useful in several cases, for example, when
%\begin{itemize}
%
%\item When the topmost patch has been modified but the changes are not
%yet completed, refreshing the patch would leave a patch file that is in
%an inconsistent state. Without that, the patch cannot be removed from
%the stack, or else the changes would be lost.
%
%\item Popping patches and then pushing them again results in modified
%time stamps. This may trigger time consuming recompiles.
%
%\item It is simply convenient to be able to fix small bugs in patches
%further down in the stack without much ado.
%
%\end{itemize}
%
patches applied higher on the stack modify some of the files that this
patch modifies. We can picture this as a shadow which the patches higher
on the stack throw on the files they modify.  When refreshing a patch,
changes to files that are not shadowed (and thus were last modified by
the patch that is being refreshed) are taken into account. The
modifications that the patch contains for shadowed files will not be
updated.

The \quilt{diff} command allows us to merge multiple patches into one by
optionally specifying the range of patches to include (see \quilt{diff
-h}). The combined patch will only modify each file contained in these
patches once. The result of applying the combined patch is the same as
applying all the patches in the specified range in sequence.

Sometimes it is convenient to use a tool other than \prog{GNU diff} for
comparing files (for example, a graphical diff replacement like
\prog{tkdiff}). Quilt will not use tools other than \prog{GNU diff} when
updating patches (\quilt{refresh}), but \quilt{diff} can be passed the
\textsf{-{}-diff=\textit{utility}} argument. With this argument, the
specified utility is invoked for each file that is being modified with
the original file and new file as arguments. For new files, the first
argument will be \textsf{/dev/null}.  For removed files, the second
argument will be \textsf{/dev/null}.

When \quilt{diff} is passed a list of file names, the diff will be
limited to those files. With the \textsf{-R} parameter, the original and
new files are swapped, which results in a reverse diff.

Sometimes it is useful to create a diff between an arbitrary state of
the working tree and the current version. This can be used to create a
diff between different versions of a patch (see
Section~\ref{sec:forking}), etc. To this end, quilt allows us to take a
snapshot of the working directory (\quilt{snapshot}). Later, a diff
against this state of the working tree can be created with \quilt{diff
-{}-snapshot}.

Currently, only a single snapshot is supported. It is stored in the
\textsf{.pc/.snap} directory.  To recover the disk space the snapshot
occupies, it can be removed with \quilt{snapshot -d}, or by removing the
\textsf{.pc/.snap} directory manually.

\subsection{Working with RPM Packages}
\label{sec:rpm}

Several Linux distributions are based on the RPM Package
Manager~\cite{max-rpm}. RPM packages consist of a spec that defines how
packages are built, and a number of additional files like tar archives,
patches, etc.  Most RPM packages contain an official software package
plus a number of patches. Before these patches can be manipulated with
quilt, a series file must be created that lists the patches along with
their strip levels.

The \quilt{setup} command automates this for most RPM packages. When
given a spec file as its argument, it performs the \textsf{\%prep}
section of the spec file, which is supposed to extract the official
software package, and apply the patches. In this run, quilt remembers
the tar archives and the patches that are applied, and creates a series
file.  Based on that series file, \quilt{setup} extracts the archives,
and copies the patches into the \textsf{patches} sub-directory. Some
meta-information like the archive names are stored as comments in the
series file. \quilt{setup} also accepts a series file as argument (which
must contain some meta-information), and sets up the working tree from
the series file in this case.

\section{Pitfalls and Known Problems}

As mentioned earlier, files must be added to patches before they can be
modified. If this step is overlooked, one of the following problems will
occur: If the file is included in a patch further below on the stack,
the changes will appear in that patch when it is refreshed, and for that
patch the \quilt{pop} command will fail before it is refreshed.  If the
file is not included in any applied patch, the original file in the
working tree is modified.

Patch files may modify the same file more than once. \prog{GNU patch}
has a bug that corrupts backup files in this case. A fix is available,
and will be integrated in a later version of \textit{GNU patch}.  The fix has
already been integrated into the SUSE version of \textit{GNU patch}.

There are some packages that assume that it's a good idea to remove all
empty files throughout a working tree, including the \textsf{.pc}
directory. The \textit{make clean} target in the linux kernel sources
is an example. Quilt uses zero-length files in \textsf{.pc} to mark
files added by patches, so such packages may corrupt the \textsf{.pc}
directory. A workaround is to create a symbolic link \textsf{.pc} in the
working tree that points to a directory outside.

It may happen that the files in the \textsf{patches} directory gets out of
sync with the working tree (e.g., they may accidentally get updated by
CVS or similar). Files in the \textsf{.pc} directory may also become
inconsistent, particularly if files are not added before modifying them
(\quilt{add} / \quilt{edit}). If this happens, it may be possible to
repair the source tree, but often the best solution is to start over
with a scratch working directory and the \textsf{patches} sub-directory.
There is no need to keep any files from the \textsf{.pc} directory in
this case.

% - Patches cannot automatically be reverse applied (?)
% - Does not auto-detect is a patch has been cleanly integrated
% - Speed

% - Push a patch that is not in the series file (after changing
%   applied-patches to include the full patch name)?

% - Other back-ends (RCS etc.)

% - Pop and push modify file timestamps, which causes recompiles.
%   Ccache ameliorates this.

% - patchutils: Very useful: lsdiff, filterdiff, etc.

\section{Summary}

We have shown how the script collection \textit{quilt} solves various
problems that occur when dealing with patches to software packages.
Quilt is an obvious improvement over directly using the underlying tools
(\prog{GNU patch}, \prog{GNU diff}, etc.), and offers many features not
available with competing solutions. Join the club!

The quilt project homepage is
\url{http://savannah.nongnu.org/projects/quilt/}. There is a development
mailing list at \url{http://mail.nongnu.org/mailman/listinfo/quilt-dev}.
Additional features that fit into quilt's mode of operation are always
welcome, of course.

\begin{thebibliography}{XX}

\bibitem{akpm02}
Andrew Morton: Patch Management Scripts,
\url{http://lwn.net/Articles/13518/} and
\url{http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.9}.

\bibitem{quilt}
Andreas Grünbacher et al.: Patchwork Quilt,
\url{http://savannah.nongnu.org/projects/quilt}.

\bibitem{posix-2001-diff}
IEEE Std. 1003.1-2001: Standard for Information Technology, Portable
Operating System Interface (POSIX), Shell and Utilities, diff
command, pp.~317. Online version available from the The Austin Common
Standards Revision Group, \url{http://www.opengroup.org/austin/}.

\bibitem{info-diff}
\textit{GNU diff} info pages (\textsf{info Diff}), section \textit{Output
Formats.}

\bibitem{max-rpm}
Edward C. Bailey: Maximum RPM: Taking the Red Hat Package Manager to the
Limit, \url{http://www.rpm.org/max-rpm/}.

\end{thebibliography}

% Add a "quick-reference card"?

\end{document}