comparison en/mq-collab.tex @ 105:ecacb6b4c9fd

Grouping patches in the series file.
author Bryan O'Sullivan <bos@serpentine.com>
date Sat, 21 Oct 2006 11:05:51 -0700
parents 32bf9a5f22c0
children 9cbc5d0db542
comparison
equal deleted inserted replaced
104:32bf9a5f22c0 105:ecacb6b4c9fd
3 While it's easy to pick up straightforward uses of Mercurial Queues, 3 While it's easy to pick up straightforward uses of Mercurial Queues,
4 use of a little discipline and some of MQ's less frequently used 4 use of a little discipline and some of MQ's less frequently used
5 capabilities makes it possible to work in complicated development 5 capabilities makes it possible to work in complicated development
6 environments. 6 environments.
7 7
8 In this chapter, I will discuss a technique I have developed to manage 8 In this chapter, I will use as an example a technique I have used to
9 the development of an Infiniband device driver for the Linux kernel. 9 manage the development of an Infiniband device driver for the Linux
10 The driver in question is large (at least as drivers go), with 25,000 10 kernel. The driver in question is large (at least as drivers go),
11 lines of code spread across 35 source files. It is maintained by a 11 with 25,000 lines of code spread across 35 source files. It is
12 small team of developers. 12 maintained by a small team of developers.
13 13
14 While much of the material in this chapter is specific to Linux, the 14 While much of the material in this chapter is specific to Linux, the
15 same principles apply to any code base for which you're not the 15 same principles apply to any code base for which you're not the
16 primary owner, and upon which you need to do a lot of development. 16 primary owner, and upon which you need to do a lot of development.
17 17
31 developers in the kernel community, who make ``drive-by'' 31 developers in the kernel community, who make ``drive-by''
32 modifications to the driver as they develop and refine kernel 32 modifications to the driver as they develop and refine kernel
33 subsystems. 33 subsystems.
34 \item We also maintain a number of ``backports'' to older versions of 34 \item We also maintain a number of ``backports'' to older versions of
35 the Linux kernel, to support the needs of customers who are running 35 the Linux kernel, to support the needs of customers who are running
36 older Linux distributions that do not incorporate our drivers. 36 older Linux distributions that do not incorporate our drivers. (To
37 \emph{backport} a piece of code is to modify it to work in an older
38 version of its target environment than the version it was developed
39 for.)
37 \item Finally, we make software releases on a schedule that is 40 \item Finally, we make software releases on a schedule that is
38 necessarily not aligned with those used by Linux distributors and 41 necessarily not aligned with those used by Linux distributors and
39 kernel developers, so that we can deliver new features to customers 42 kernel developers, so that we can deliver new features to customers
40 without forcing them to upgrade their entire kernels or 43 without forcing them to upgrade their entire kernels or
41 distributions. 44 distributions.
77 In principle, Mercurial Queues seems like a good candidate to manage a 80 In principle, Mercurial Queues seems like a good candidate to manage a
78 development scenario such as the above. While this is indeed the 81 development scenario such as the above. While this is indeed the
79 case, MQ contains a few added features that make the job more 82 case, MQ contains a few added features that make the job more
80 pleasant. 83 pleasant.
81 84
82 \section{Conditionally applying patches with guards} 85 \section{Conditionally applying patches with
86 guards}
83 87
84 Perhaps the best way to maintain sanity with so many targets is to be 88 Perhaps the best way to maintain sanity with so many targets is to be
85 able to choose specific patches to apply for a given situation. MQ 89 able to choose specific patches to apply for a given situation. MQ
86 provides a feature called ``guards'' (which originates with quilt's 90 provides a feature called ``guards'' (which originates with quilt's
87 \texttt{guards} command) that does just this. To start off, let's 91 \texttt{guards} command) that does just this. To start off, let's
148 We can see the effect the selected guards have when we run 152 We can see the effect the selected guards have when we run
149 \hgcmd{qpush}. 153 \hgcmd{qpush}.
150 \interaction{mq.guards.qselect.qpush} 154 \interaction{mq.guards.qselect.qpush}
151 155
152 A guard cannot start with a ``\texttt{+}'' or ``\texttt{-}'' 156 A guard cannot start with a ``\texttt{+}'' or ``\texttt{-}''
153 character. 157 character. The name of a guard must start with an alphabetic
158 character (upper or lower case) or an underscore. The rest of the
159 guard's name can contain any of these characters, or a digit. These
160 rules are similar to those used for variable naming in most popular
161 programming languages. If you try to use a guard with an invalid
162 name, MQ will complain:
154 \interaction{mq.guards.qselect.error} 163 \interaction{mq.guards.qselect.error}
155 Changing the selected guards changes the patches that are applied. 164 Changing the selected guards changes the patches that are applied.
156 \interaction{mq.guards.qselect.quux} 165 \interaction{mq.guards.qselect.quux}
157 You can see here that negative guards take precedence over positive 166 You can see in the example below that negative guards take precedence
158 guards. 167 over positive guards.
159 \interaction{mq.guards.qselect.foobar} 168 \interaction{mq.guards.qselect.foobar}
169
170 \section{MQ's rules for applying patches}
171
172 The rules that MQ uses when deciding whether to apply a patch
173 are as follows.
174 \begin{itemize}
175 \item A patch that has no guards is always applied.
176 \item If the patch has any negative guard that matches any currently
177 selected guard, the patch is skipped.
178 \item If the patch has any positive guard that matches any currently
179 selected guard, the patch is applied.
180 \item If the patch has positive or negative guards, but none matches
181 any currently selected guard, the patch is skipped.
182 \end{itemize}
183
184 \section{Trimming the work environment}
185
186 In working on the device driver I mentioned earlier, I don't apply the
187 patches to a normal Linux kernel tree. Instead, I use a repository
188 that contains only a snapshot of the source files and headers that are
189 relevant to Infiniband development. This repository is~1\% the size
190 of a kernel repository, so it's easier to work with.
191
192 I then choose a ``base'' version on top of which the patches are
193 applied. This is a snapshot of the Linux kernel tree as of a revision
194 of my choosing. When I take the snapshot, I record the changeset ID
195 from the kernel repository in the commit message. Since the snapshot
196 preserves the ``shape'' and content of the relevant parts of the
197 kernel tree, I can apply my patches on top of either my tiny
198 repository or a normal kernel tree.
199
200 Normally, the base tree atop which the patches apply should be a
201 snapshot of a very recent upstream tree. This best facilitates the
202 development of patches that can easily be submitted upstream with few
203 or no modifications.
204
205 \section{Dividing up the \sfilename{series} file}
206
207 I categorise the patches in the \sfilename{series} file into a number
208 of logical groups. Each section of like patches begins with a block
209 of comments that describes the purpose of the patches that follow.
210
211 The sequence of patch groups that I maintain follows. The ordering of
212 these groups is important; I'll describe why after I introduce the
213 groups.
214 \begin{itemize}
215 \item The ``accepted'' group. Patches that the development team has
216 submitted to the maintainer of the Infiniband subsystem, and which
217 he has accepted, but which are not present in the snapshot that the
218 tiny repository is based on. These are ``read only'' patches,
219 present only to transform the tree into a similar state as it is in
220 the upstream maintainer's repository.
221 \item The ``rework'' group. Patches that I have submitted, but that
222 the upstream maintainer has requested modifications to before he
223 will accept them.
224 \item The ``pending'' group. Patches that I have not yet submitted to
225 the upstream maintainer, but which we have finished working on.
226 These will be ``read only'' for a while. If the upstream maintainer
227 accepts them upon submission, I'll move them to the end of the
228 ``accepted'' group. If he requests that I modify any, I'll move
229 them to the beginning of the ``rework'' group.
230 \item The ``in progress'' group. Patches that are actively being
231 developed, and should not be submitted anywhere yet.
232 \item The ``backport'' group. Patches that adapt the source tree to
233 older versions of the kernel tree.
234 \item The ``do not ship'' group. Patches that for some reason should
235 never be submitted upstream. For example, one such patch might
236 change embedded driver identification strings to make it easier to
237 distinguish, in the field, between an out-of-tree version of the
238 driver and a version shipped by a distribution vendor.
239 \end{itemize}
240
241 Now to return to the reasons for ordering groups of patches in this
242 way. We would like the lowest patches in the stack to be as stable as
243 possible, so that we will not need to rework higher patches due to
244 changes in context. Putting patches that will never be changed first
245 in the \sfilename{series} file serves this purpose.
246
247 We would also like the patches that we know we'll need to modify to be
248 applied on top of a source tree that resembles the upstream tree as
249 closely as possible. This is why we keep accepted patches around for
250 a while.
251
252 The ``backport'' and ``do not ship'' patches float at the end of the
253 \sfilename{series} file in part because they'll never be shipped
254 upstream. Additionally, the backport patches must be applied on top
255 of all other patches.
160 256
161 %%% Local Variables: 257 %%% Local Variables:
162 %%% mode: latex 258 %%% mode: latex
163 %%% TeX-master: "00book" 259 %%% TeX-master: "00book"
164 %%% End: 260 %%% End: