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