comparison ja/mq-collab.tex @ 350:5a5419eeab70

more mq-collab.tex
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 18 Aug 2008 11:21:45 +0900
parents 84ae26ab0ac3
children f3fa98815193
comparison
equal deleted inserted replaced
349:84ae26ab0ac3 350:5a5419eeab70
83 \end{itemize} 83 \end{itemize}
84 84
85 %\subsection{Tempting approaches that don't work well} 85 %\subsection{Tempting approaches that don't work well}
86 \subsection{$B$d$C$F$7$^$$$,$A$J4V0c$C$?J}K!(B} 86 \subsection{$B$d$C$F$7$^$$$,$A$J4V0c$C$?J}K!(B}
87 87
88 There are two ``standard'' ways to maintain a piece of software that 88 %There are two ``standard'' ways to maintain a piece of software that
89 has to target many different environments. 89 %has to target many different environments.
90 90
91 The first is to maintain a number of branches, each intended for a 91 $B$5$^$6$^$J4D6-$r%?!<%2%C%H$K$7$?%=%U%H%&%'%"$r4IM}$9$k(B2$B$D$NI8=`E*$JJ}K!(B
92 single target. The trouble with this approach is that you must 92 $B$,$"$k!%(B
93 maintain iron discipline in the flow of changes between repositories. 93
94 A new feature or bug fix must start life in a ``pristine'' repository, 94 %The first is to maintain a number of branches, each intended for a
95 then percolate out to every backport repository. Backport changes are 95 %single target. The trouble with this approach is that you must
96 more limited in the branches they should propagate to; a backport 96 %maintain iron discipline in the flow of changes between repositories.
97 change that is applied to a branch where it doesn't belong will 97 %A new feature or bug fix must start life in a ``pristine'' repository,
98 probably stop the driver from compiling. 98 %then percolate out to every backport repository. Backport changes are
99 99 %more limited in the branches they should propagate to; a backport
100 The second is to maintain a single source tree filled with conditional 100 %change that is applied to a branch where it doesn't belong will
101 statements that turn chunks of code on or off depending on the 101 %probably stop the driver from compiling.
102 intended target. Because these ``ifdefs'' are not allowed in the 102
103 Linux kernel tree, a manual or automatic process must be followed to 103 $BBh(B1$B$NJ}K!$O!$C10l$N%?!<%2%C%H8~$1$NJ#?t$N%V%i%s%A$r0];}$9$k$3$H$G$"$k!%$3(B
104 strip them out and yield a clean tree. A code base maintained in this 104 $B$NJ}K!$NLdBjE@$O!$%j%]%8%H%j4V$G$NJQ99$NN.$l$K$D$$$F873J$J5,N'$r0];}$7$J(B
105 fashion rapidly becomes a rat's nest of conditional blocks that are 105 $B$1$l$P$J$i$J$$$3$H$G$"$k!%?75!G=$d%P%0=$@5$O!$$-$l$$$J>uBV$N%j%]%8%H%j$G(B
106 difficult to understand and maintain. 106 $B3+;O$7!$%P%C%/%]!<%H%j%]%8%H%j$K?;F)$9$kI,MW$,$"$k!%%P%C%/%]!<%HJQ99$OGH(B
107 107 $B5Z$9$Y$-%V%i%s%AFb$K8BDj$5$l$F$$$J$1$l$P$J$i$J$$!%I,MW$N$J$$%V%i%s%A$X$N(B
108 Neither of these approaches is well suited to a situation where you 108 $B%P%C%/%]!<%H$NGH5Z$O$*$=$i$/%I%i%$%P$r%3%s%Q%$%kITG=$K$7$F$7$^$&$@$m$&!%(B
109 don't ``own'' the canonical copy of a source tree. In the case of a 109
110 Linux driver that is distributed with the standard kernel, Linus's 110 %The second is to maintain a single source tree filled with conditional
111 tree contains the copy of the code that will be treated by the world 111 %statements that turn chunks of code on or off depending on the
112 as canonical. The upstream version of ``my'' driver can be modified 112 %intended target. Because these ``ifdefs'' are not allowed in the
113 by people I don't know, without me even finding out about it until 113 %Linux kernel tree, a manual or automatic process must be followed to
114 after the changes show up in Linus's tree. 114 %strip them out and yield a clean tree. A code base maintained in this
115 115 %fashion rapidly becomes a rat's nest of conditional blocks that are
116 These approaches have the added weakness of making it difficult to 116 %difficult to understand and maintain.
117 generate well-formed patches to submit upstream. 117
118 118 $BBh(B2$B$NJ}K!$O!$%A%c%s%/$d%3!<%I$r!$L\E*$H$9$k%?!<%2%C%HKh$K(Bon/off$B$9$k>r7oJ8(B
119 In principle, Mercurial Queues seems like a good candidate to manage a 119 $B$rDI2C$7$?C10l$N%=!<%9%D%j!<$r0];}$9$kJ}K!$G$"$k!%$3$l$i$N(B``ifdef''$B$O(B
120 development scenario such as the above. While this is indeed the 120 linux$B%+!<%M%k%D%j!<$G$O5v$5$l$F$$$J$$$?$a!$<jF0$^$?$O<+F0$G$3$l$i$N%3!<%I(B
121 case, MQ contains a few added features that make the job more 121 $B$r=|5n$7!$%/%j!<%s$J%D%j!<$r:n$k%W%m%;%9$,I,MW$K$J$k!%$3$N$h$&$J$d$jJ}$G(B
122 pleasant. 122 $B4IM}$5$l$?%3!<%I%Y!<%9$O$9$0$K>r7o@a$NAc7"$H2=$7!"M}2r$d4IM}$NK8$2$H$J$k!#(B
123
124 %Neither of these approaches is well suited to a situation where you
125 %don't ``own'' the canonical copy of a source tree. In the case of a
126
127 %Linux driver that is distributed with the standard kernel, Linus's
128 %tree contains the copy of the code that will be treated by the world
129 %as canonical. The upstream version of ``my'' driver can be modified
130 %by people I don't know, without me even finding out about it until
131 %after the changes show up in Linus's tree.
132
133 $B$"$J$?$,@5<0$J%=!<%9%D%j!<$r=jM-$7$F$$$k$N$G$J$1$l$P!"$3$l$i$N$d$jJ}$N$I(B
134 $B$A$i$b$=$0$o$J$$$@$m$&!#I8=`$N(Blinux$B%+!<%M%k$KF1:-$5$l$F$$$k%I%i%$%P$N>l(B
135 $B9g!$(BLinus$B$N%D%j!<$O@$3&Cf$G@5<0$J%3!<%I$H$7$F07$o$l$k%3%T!<$r4^$s$G$$$k!%(B
136 ``$B;d(B''$B$N%I%i%$%P$N>eN.HG$O!$CN$i$J$$?M$K$h$C$FJQ99$5$lF@$k$7!$<+J,$NJQ99(B
137 $B$,(BLinus$B$N%D%j!<$KF~$C$?$"$H$G$5$($bJQ99$5$lF@$k!%(B
138
139 %These approaches have the added weakness of making it difficult to
140 %generate well-formed patches to submit upstream.
141
142 $B$3$l$i$N%"%W%m!<%A$O!$$&$^$/=q$+$l$?%Q%C%A$r>eN.$XDs=P$9$k$3$H$r:$Fq$K$7(B
143 $B$F$7$^$&!%(B
144
145 %In principle, Mercurial Queues seems like a good candidate to manage a
146 %development scenario such as the above. While this is indeed the
147 %case, MQ contains a few added features that make the job more
148 %pleasant.
149
150 Mercurial Queues$B$O>e5-$N$h$&$J3+H/%7%J%j%*$r4IM}$9$k$h$$8uJd$N0l$D$G$"$k(B
151 $B$H$$$($k!%$3$N$h$&$J>l9g$N$?$a$K(BMQ$B$K$O:n6H$r$h$j2wE,$K$9$k$$$/$D$+$N5!G=(B
152 $B$,$"$k!%(B
123 153
124 %\section{Conditionally applying patches with guards} 154 %\section{Conditionally applying patches with guards}
125 \section{$B%,!<%I$r;H$C$?%Q%C%A$N>r7oE*$JE,MQ(B} 155 \section{$B%,!<%I$r;H$C$?%Q%C%A$N>r7oE*$JE,MQ(B}
126 156
127 Perhaps the best way to maintain sanity with so many targets is to be 157 %Perhaps the best way to maintain sanity with so many targets is to be
128 able to choose specific patches to apply for a given situation. MQ 158 %able to choose specific patches to apply for a given situation. MQ
129 provides a feature called ``guards'' (which originates with quilt's 159 %provides a feature called ``guards'' (which originates with quilt's
130 \texttt{guards} command) that does just this. To start off, let's 160 %\texttt{guards} command) that does just this. To start off, let's
131 create a simple repository for experimenting in. 161 %create a simple repository for experimenting in.
132 \interaction{mq.guards.init} 162 %\interaction{mq.guards.init}
133 This gives us a tiny repository that contains two patches that don't 163 %This gives us a tiny repository that contains two patches that don't
134 have any dependencies on each other, because they touch different files. 164 %have any dependencies on each other, because they touch different files.
165
166
167
135 168
136 The idea behind conditional application is that you can ``tag'' a 169 The idea behind conditional application is that you can ``tag'' a
137 patch with a \emph{guard}, which is simply a text string of your 170 patch with a \emph{guard}, which is simply a text string of your
138 choosing, then tell MQ to select specific guards to use when applying 171 choosing, then tell MQ to select specific guards to use when applying
139 patches. MQ will then either apply, or skip over, a guarded patch, 172 patches. MQ will then either apply, or skip over, a guarded patch,