hgbook

diff en/mq-collab.tex @ 106:9cbc5d0db542

Finish off advanced MQ chapter (maybe).
author Bryan O'Sullivan <bos@serpentine.com>
date Mon Oct 23 15:43:04 2006 -0700 (2006-10-23)
parents ecacb6b4c9fd
children a0d7e11db169
line diff
     1.1 --- a/en/mq-collab.tex	Sat Oct 21 11:05:51 2006 -0700
     1.2 +++ b/en/mq-collab.tex	Mon Oct 23 15:43:04 2006 -0700
     1.3 @@ -154,15 +154,12 @@
     1.4  \interaction{mq.guards.qselect.qpush}
     1.5  
     1.6  A guard cannot start with a ``\texttt{+}'' or ``\texttt{-}''
     1.7 -character.  The name of a guard must start with an alphabetic
     1.8 -character (upper or lower case) or an underscore.  The rest of the
     1.9 -guard's name can contain any of these characters, or a digit.  These
    1.10 -rules are similar to those used for variable naming in most popular
    1.11 -programming languages.  If you try to use a guard with an invalid
    1.12 -name, MQ will complain:
    1.13 -\interaction{mq.guards.qselect.error}
    1.14 +character.  The name of a guard must not contain white space, but most
    1.15 +othter characters are acceptable.  If you try to use a guard with an
    1.16 +invalid name, MQ will complain:
    1.17 +\interaction{mq.guards.qselect.error} 
    1.18  Changing the selected guards changes the patches that are applied.
    1.19 -\interaction{mq.guards.qselect.quux}
    1.20 +\interaction{mq.guards.qselect.quux} 
    1.21  You can see in the example below that negative guards take precedence
    1.22  over positive guards.
    1.23  \interaction{mq.guards.qselect.foobar}
    1.24 @@ -250,9 +247,132 @@
    1.25  a while.
    1.26  
    1.27  The ``backport'' and ``do not ship'' patches float at the end of the
    1.28 -\sfilename{series} file in part because they'll never be shipped
    1.29 -upstream.  Additionally, the backport patches must be applied on top
    1.30 -of all other patches.
    1.31 +\sfilename{series} file.  The backport patches must be applied on top
    1.32 +of all other patches, and the ``do not ship'' patches might as well
    1.33 +stay out of harm's way.
    1.34 +
    1.35 +\section{Maintaining the patch series}
    1.36 +
    1.37 +In my work, I use a number of guards to control which patches are to
    1.38 +be applied.
    1.39 +
    1.40 +\begin{itemize}
    1.41 +\item ``Accepted'' patches are guarded with \texttt{accepted}.  I
    1.42 +  enable this guard most of the time.  When I'm applying the patches
    1.43 +  on top of a tree where the patches are already present, I can turn
    1.44 +  this patch off, and the paptches that follow it will apply cleanly.
    1.45 +\item Patches that are ``finished'', but not yet submitted, have no
    1.46 +  guards.  If I'm applying the patch stack to a copy of the upstream
    1.47 +  tree, I don't need to enable any guards in order to get a reasonably
    1.48 +  safe source tree.
    1.49 +\item Those patches that need reworking before being resubmitted are
    1.50 +  guarded with \texttt{rework}.
    1.51 +\item For those patches that are still under development, I use
    1.52 +  \texttt{devel}.
    1.53 +\item A backport patch may have several guards, one for each version
    1.54 +  of the kernel to which it applies.  For example, a patch that
    1.55 +  backports a piece of code to~2.6.9 will have a~\texttt{2.6.9} guard.
    1.56 +\end{itemize}
    1.57 +This variety of guards gives me considerable flexibility in
    1.58 +qdetermining what kind of source tree I want to end up with.  For most
    1.59 +situations, the selection of appropriate guards is automated during
    1.60 +the build process, but I can manually tune the guards to use for less
    1.61 +common circumstances.
    1.62 +
    1.63 +\subsection{The art of writing backport patches}
    1.64 +
    1.65 +Using MQ, writing a backport patch is a simple process.  All such a
    1.66 +patch has to do is modify a piece of code that uses a kernel feature
    1.67 +not present in the older version of the kernel, so that the driver
    1.68 +continues to work correctly under that older version.
    1.69 +
    1.70 +A useful goal when writing a good backport patch is to make your code
    1.71 +look as if it was written for the older version of the kernel you're
    1.72 +targeting.  The less obtrusive the patch, the easier it will be to
    1.73 +understand and maintain.  If you're writing a collection of backport
    1.74 +patches to avoid the ``rat's nest'' effect of lots of
    1.75 +\texttt{\#ifdef}s (hunks of source code that are only used
    1.76 +conditionally) in your code, don't introduce version-dependent
    1.77 +\texttt{\#ifdef}s into the patches.  Instead, write several patches,
    1.78 +each of which makes unconditional changes, and control their
    1.79 +application using guards.
    1.80 +
    1.81 +There are two reasons to divide backport patches into a distinct
    1.82 +group, away from the ``regular'' patches whose effects they modify.
    1.83 +The first is that intermingling the two makes it more difficult to use
    1.84 +a tool like the \hgext{patchbomb} extension to automate the process of
    1.85 +submitting the patches to an upstream maintainer.  The second is that
    1.86 +a backport patch could perturb the context in which a subsequent
    1.87 +regular patch is applied, making it impossible to apply the regular
    1.88 +patch cleanly \emph{without} the earlier backport patch already being
    1.89 +applied.
    1.90 +
    1.91 +\section{Useful tips for developing with MQ}
    1.92 +
    1.93 +\subsection{Organising patches in directories}
    1.94 +
    1.95 +If you're working on a substantial project with MQ, it's not difficult
    1.96 +to accumulate a large number of patches.  For example, I have one
    1.97 +patch repository that contains over 250 patches.
    1.98 +
    1.99 +If you can group these patches into separate logical categories, you
   1.100 +can if you like store them in different directories; MQ has no
   1.101 +problems with patch names that contain path separators.
   1.102 +
   1.103 +\subsection{Viewing the history of a patch}
   1.104 +\label{mq-collab:tips:interdiff}
   1.105 +
   1.106 +If you're developing a set of patches over a long time, it's a good
   1.107 +idea to maintain them in a repository, as discussed in
   1.108 +section~\ref{sec:mq:repo}.  If you do so, you'll quickly discover that
   1.109 +using the \hgcmd{diff} command to look at the history of changes to a
   1.110 +patch is unworkable.  This is in part because you're looking at the
   1.111 +second derivative of the real code (a diff of a diff), but also
   1.112 +because MQ adds noise to the process by modifying time stamps and
   1.113 +directory names when it updates a patch.
   1.114 +
   1.115 +However, you can use the \hgext{extdiff} extension, which is bundled
   1.116 +with Mercurial, to turn a diff of two versions of a patch into
   1.117 +something readable.  To do this, you will need a third-party package
   1.118 +called \package{patchutils}~\cite{web:patchutils}.  This provides a
   1.119 +command named \command{interdiff}, which shows the differences between
   1.120 +two diffs as a diff.  Used on two versions of the same diff, it
   1.121 +generates a diff that represents the diff from the first to the second
   1.122 +version.
   1.123 +
   1.124 +You can enable the \hgext{extdiff} extension in the usual way, by
   1.125 +adding a line to the \rcsection{extensions} section of your \hgrc.
   1.126 +\begin{codesample2}
   1.127 +  [extensions]
   1.128 +  extdiff =
   1.129 +\end{codesample2}
   1.130 +The \command{interdiff} command expects to be passed the names of two
   1.131 +files, but the \hgext{extdiff} extension passes the program it runs a
   1.132 +pair of directories, each of which can contain an arbitrary number of
   1.133 +files.  We thus need a small program that will run \command{interdiff}
   1.134 +on each pair of files in these two directories.  This program is
   1.135 +available as \sfilename{hg-interdiff} in the \dirname{examples}
   1.136 +directory of the source code repository that accompanies this book.
   1.137 +\excode{hg-interdiff}
   1.138 +
   1.139 +With the \sfilename{hg-interdiff} program in your shell's search path,
   1.140 +you can run it as follows, from inside an MQ patch directory:
   1.141 +\begin{codesample2}
   1.142 +  hg extdiff -p hg-interdiff -r A:B my-change.patch
   1.143 +\end{codesample2}
   1.144 +Since you'll probably want to use this long-winded command a lot, you
   1.145 +can get \hgext{hgext} to make it available as a normal Mercurial
   1.146 +command, again by editing your \hgrc.
   1.147 +\begin{codesample2}
   1.148 +  [extdiff]
   1.149 +  cmd.interdiff = hg-interdiff
   1.150 +\end{codesample2}
   1.151 +This directs \hgext{hgext} to make an \texttt{interdiff} command
   1.152 +available, so you can now shorten the previous invocation of
   1.153 +\hgcmd{extdiff} to something a little more wieldy.
   1.154 +\begin{codesample2}
   1.155 +  hg interdiff -r A:B my-change.patch
   1.156 +\end{codesample2}
   1.157  
   1.158  %%% Local Variables: 
   1.159  %%% mode: latex