?? main.tex
字號:
%\documentclass[a4paper]{article}\documentclass{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 GPL licensed 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黱bacher, 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 packagesthat consist of a base software package on top of which a number ofpatches are applied, this document introduces the script collection\textit{quilt,} which was specifically written to help deal withmultiple 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 sourceworld consisted of a file with the official version of the software,plus a patch file with the additional changes needed to adapt thepackage to specific needs. The official software package was usuallycontained in a \textsf{package.tar.gz} file, while the patch was foundin \textsf{package.diff.} Instead of modifying the officialpackage sources, local changes were kept separate. When building thesoftware package, the tar archive was extracted, and the patch wasapplied.Over time, the patch file ended up containing several independentchanges. Of those changes, some were integrated into later versions ofthe software, while other add-ons or adaptations remain external. Whenevera new official version was integrated, the patch needed to be revised:changes that were already integrated in the official version needed tobe 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 ofpatches is applied on top of each other. Each patch usually consists ofa logically related set of changes. When some patches get integratedupstream, those patches can simply be removed from the vendor specificpackage. The remaining patches frequently continue to apply cleanly.Some of the remaining patches may have to be maintained across a rangeof upstream versions because they are too specific for the upstreamsoftware package, etc. These patches often get out of sync, and need tobe updated.For the majority of packages, the number of patches remains relativelylow, so maintaining those patches without tools is feasible. A number ofpackages have dozens of patches, however. At the extreme end is thekernel source package (kernel-source-\textit{2.4.x}) with more than1\,000 patches. The difficulty of managing such a vast number ofpatches without tools can easily be imagined.This document discusses different strategies of dealing with large setsof patches. Patches are usually generated by the \prog{diff} utility,and applied with the \prog{patch} utility. Different patch file formats aredefined as part of the specification of the \prog{diff} utility inPOSIX.1~\cite{posix-2001-diff}. The most commonly used format today,\textit{unified diff,} is not covered by POSIX.1, however. A gooddescription of patch file formats is found in the \prog{GNU diff} infopages~\cite{info-diff}.The question we try to answer in this document is how patches are best keptup to date in face of changes both to the upstream software package, andto the patches that precede them. After looking at some existingapproaches, 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 precedingpatches.%\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 beupdated) is applied to only one of these source trees. This source treeis then modified until it reflects the desired result. The new version ofthe 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 bedesired. Several people have independently written scripts thatautomate and improve upon this process.A version control system like \prog{CVS} or \prog{RCS} may be areasonable alternative in some cases. The version control system isbrought in the state of the working tree with a number of patchesapplied. Then the next patch is applied. After the working tree isupdated as required, a diff between the repository copy and the workingtree is created (with \prog{cvs diff}, etc). In this scenario theversion control system is used to store and compare against the oldrepository version only. The full version control overhead is paid,while only a small fraction of its functionality is needed. Switchingbetween different patches is not simplified.% TODO: Mention some approaches here; RCS and CVS ...One of the most advanced approaches is Andrew Morton's patch managementscripts~\cite{akpm02}. The author of this document found that none ofthe available solutions would scale up to the specific requirements ofthe SUSE kernel-source package, and started to improve Andrew Morton'sscripts 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}\label{sec:basic}The remainder of this document discusses the script collection\textit{quilt.}With quilt, all work occurs within a single directory tree. Sinceversion 0.30, commands can be invoked from anywhere within the sourcetree. Commands are of the form ``\quilt{cmd},'' similar to CVScommands. They can be abbreviated as long as the specified part of thecommand is unique. All commands print some help text with ``\quilt{cmd-h}.''Quilt manages a stack of patches. Patches are applied incrementally ontop of the base tree plus all preceding patches. They can be pushedon top of the stack (\quilt{push}), and popped off the stack(\quilt{pop}). Commands are available for querying the contents of theseries file (\quilt{series}, see below), the contents of the stack(\quilt{applied}, \quilt{previous}, \quilt{top}), and the patches thatare not applied at a particular moment (\quilt{next}, \quilt{unapplied}).By default, most commands apply to the topmost patch on the stack.When files in the working directory are changed, those changes becomepart of the working state of the topmost patch, provided that thosefiles are part of the patch. Files that are not part of a patch must beadded before modifying them so that quilt is aware of the originalversions of the files. The \quilt{refresh} command regenerates a patch.After the refresh, the patch and the working state are the same.Patch files are located in the \textsf{patches} sub-directory of thesource 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 thatdefines the order in which patches are applied. Unless there are meansby which series files can be generated automatically (seeSection~\ref{sec:rpm}), they are usually provided along with a set ofpatches. 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 ahash character (\texttt{\#}) are ignored. When quilt adds, removes, orrenames patches, it automatically updates the series file. Users ofquilt can modify series files while some patches are applied, as long asthe applied patches remain in their original order.Different series files can be used to assemble patches in different ways,corresponding for example to different development branches.\begin{figure}\begin{center}\begin{minipage}{6cm}\begin{small}\begin{Verbatim}work/ -+- ... |- patches/ -+- series | |- patch2.diff | |- patch1.diff | +- ... +- .pc/ -+- applied-patches |- patch1.diff/ -+- ... |- patch2.diff/ -+- ... +- ...\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 allfiles 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 the list ofcurrently applied patches (\textsf{.pc/applied-patches}). Later when a patch is regenerated(\quilt{refresh}), the backup copies in \textsf{.pc/\textit{patch}} arecompared with the current versions of the files in the source treeusing \prog{GNU diff}.Documentation related to a patch can be put at the beginning of a patchfile. Quilt is careful to preserve all text that precedes the actualpatch when doing a refresh.The series file is looked up in the root of the source tree, in thepatches directory, and in the \textsf{.pc} directory. The first seriesfile that is found is used. This may also be a symbolic link, or a filewith multiple hard links. Usually, only one series file is used for aset of patches, so the \textsf{patches} sub-directory is a convenient
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -