diff options
author | Andreas Gruenbacher <agruen@suse.de> | 2003-11-12 00:38:05 +0000 |
---|---|---|
committer | Andreas Gruenbacher <agruen@suse.de> | 2003-11-12 00:38:05 +0000 |
commit | ec4863a5bc56100f2e4ce746d0efb34729376bb8 (patch) | |
tree | cf7a5fbf1c39111e5a5ddfef2ffefe1889b0d6a7 /doc/main.tex | |
parent | aa2e20e1d6d2eef546613da566276b93c856de15 (diff) | |
download | quilt-ec4863a5bc56100f2e4ce746d0efb34729376bb8.tar.gz |
- Add introductory paper to CVS repository.
- Remove obsolete documentation.
Diffstat (limited to 'doc/main.tex')
-rw-r--r-- | doc/main.tex | 716 |
1 files changed, 716 insertions, 0 deletions
diff --git a/doc/main.tex b/doc/main.tex new file mode 100644 index 0000000..71e2e2f --- /dev/null +++ b/doc/main.tex @@ -0,0 +1,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} |