Mercurial > hgbook
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: |