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