hgbook
diff en/ch09-hook.xml @ 686:e9154b3daa94
Repurpose appendix A.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Sun Apr 26 23:16:56 2009 -0700 (2009-04-26) |
parents | b338f5490029 |
children | 88828b784971 |
line diff
1.1 --- a/en/ch09-hook.xml Thu Apr 09 22:52:16 2009 -0700 1.2 +++ b/en/ch09-hook.xml Sun Apr 26 23:16:56 2009 -0700 1.3 @@ -147,8 +147,8 @@ 1.4 incoming</command>), remember that it is the other 1.5 repository's hooks you should be checking, not your own. 1.6 </para> 1.7 - 1.8 - </sect2> 1.9 + </sect2> 1.10 + 1.11 <sect2> 1.12 <title>Hooks do not propagate</title> 1.13 1.14 @@ -178,8 +178,8 @@ 1.15 filesystem, and use a site-wide <filename role="special">~/.hgrc</filename> file to define hooks that all users will 1.16 see. However, this too has its limits; see below. 1.17 </para> 1.18 - 1.19 - </sect2> 1.20 + </sect2> 1.21 + 1.22 <sect2> 1.23 <title>Hooks can be overridden</title> 1.24 1.25 @@ -193,8 +193,8 @@ 1.26 hooks, you should thus understand that your users can disable 1.27 or override those hooks. 1.28 </para> 1.29 - 1.30 - </sect2> 1.31 + </sect2> 1.32 + 1.33 <sect2> 1.34 <title>Ensuring that critical hooks are run</title> 1.35 1.36 @@ -232,116 +232,7 @@ 1.37 1.38 </sect2> 1.39 </sect1> 1.40 - <sect1> 1.41 - <title>Care with <literal>pretxn</literal> hooks in a 1.42 - shared-access repository</title> 1.43 - 1.44 - <para id="x_206">If you want to use hooks to do some automated work in a 1.45 - repository that a number of people have shared access to, you 1.46 - need to be careful in how you do this. 1.47 - </para> 1.48 - 1.49 - <para id="x_207">Mercurial only locks a repository when it is writing to the 1.50 - repository, and only the parts of Mercurial that write to the 1.51 - repository pay attention to locks. Write locks are necessary to 1.52 - prevent multiple simultaneous writers from scribbling on each 1.53 - other's work, corrupting the repository. 1.54 - </para> 1.55 - 1.56 - <para id="x_208">Because Mercurial is careful with the order in which it 1.57 - reads and writes data, it does not need to acquire a lock when 1.58 - it wants to read data from the repository. The parts of 1.59 - Mercurial that read from the repository never pay attention to 1.60 - locks. This lockless reading scheme greatly increases 1.61 - performance and concurrency. 1.62 - </para> 1.63 - 1.64 - <para id="x_209">With great performance comes a trade-off, though, one which 1.65 - has the potential to cause you trouble unless you're aware of 1.66 - it. To describe this requires a little detail about how 1.67 - Mercurial adds changesets to a repository and reads those 1.68 - changes. 1.69 - </para> 1.70 - 1.71 - <para id="x_20a">When Mercurial <emphasis>writes</emphasis> metadata, it 1.72 - writes it straight into the destination file. It writes file 1.73 - data first, then manifest data (which contains pointers to the 1.74 - new file data), then changelog data (which contains pointers to 1.75 - the new manifest data). Before the first write to each file, it 1.76 - stores a record of where the end of the file was in its 1.77 - transaction log. If the transaction must be rolled back, 1.78 - Mercurial simply truncates each file back to the size it was 1.79 - before the transaction began. 1.80 - </para> 1.81 - 1.82 - <para id="x_20b">When Mercurial <emphasis>reads</emphasis> metadata, it reads 1.83 - the changelog first, then everything else. Since a reader will 1.84 - only access parts of the manifest or file metadata that it can 1.85 - see in the changelog, it can never see partially written data. 1.86 - </para> 1.87 - 1.88 - <para id="x_20c">Some controlling hooks (<literal 1.89 - role="hook">pretxncommit</literal> and <literal 1.90 - role="hook">pretxnchangegroup</literal>) run when a 1.91 - transaction is almost complete. All of the metadata has been 1.92 - written, but Mercurial can still roll the transaction back and 1.93 - cause the newly-written data to disappear. 1.94 - </para> 1.95 - 1.96 - <para id="x_20d">If one of these hooks runs for long, it opens a window of 1.97 - time during which a reader can see the metadata for changesets 1.98 - that are not yet permanent, and should not be thought of as 1.99 - <quote>really there</quote>. The longer the hook runs, the 1.100 - longer that window is open. 1.101 - </para> 1.102 - 1.103 - <sect2> 1.104 - <title>The problem illustrated</title> 1.105 - 1.106 - <para id="x_20e">In principle, a good use for the <literal 1.107 - role="hook">pretxnchangegroup</literal> hook would be to 1.108 - automatically build and test incoming changes before they are 1.109 - accepted into a central repository. This could let you 1.110 - guarantee that nobody can push changes to this repository that 1.111 - <quote>break the build</quote>. But if a client can pull 1.112 - changes while they're being tested, the usefulness of the test 1.113 - is zero; an unsuspecting someone can pull untested changes, 1.114 - potentially breaking their build. 1.115 - </para> 1.116 - 1.117 - <para id="x_20f">The safest technological answer to this challenge is to 1.118 - set up such a <quote>gatekeeper</quote> repository as 1.119 - <emphasis>unidirectional</emphasis>. Let it take changes 1.120 - pushed in from the outside, but do not allow anyone to pull 1.121 - changes from it (use the <literal 1.122 - role="hook">preoutgoing</literal> hook to lock it down). 1.123 - Configure a <literal role="hook">changegroup</literal> hook so 1.124 - that if a build or test succeeds, the hook will push the new 1.125 - changes out to another repository that people 1.126 - <emphasis>can</emphasis> pull from. 1.127 - </para> 1.128 - 1.129 - <para id="x_210">In practice, putting a centralised bottleneck like this in 1.130 - place is not often a good idea, and transaction visibility has 1.131 - nothing to do with the problem. As the size of a 1.132 - project&emdash;and the time it takes to build and 1.133 - test&emdash;grows, you rapidly run into a wall with this 1.134 - <quote>try before you buy</quote> approach, where you have 1.135 - more changesets to test than time in which to deal with them. 1.136 - The inevitable result is frustration on the part of all 1.137 - involved. 1.138 - </para> 1.139 - 1.140 - <para id="x_211">An approach that scales better is to get people to build 1.141 - and test before they push, then run automated builds and tests 1.142 - centrally <emphasis>after</emphasis> a push, to be sure all is 1.143 - well. The advantage of this approach is that it does not 1.144 - impose a limit on the rate at which the repository can accept 1.145 - changes. 1.146 - </para> 1.147 - 1.148 - </sect2> 1.149 - </sect1> 1.150 + 1.151 <sect1 id="sec:hook:simple"> 1.152 <title>A short tutorial on using hooks</title> 1.153 1.154 @@ -509,8 +400,8 @@ 1.155 <literal>foo</literal>, while the environment variable for an 1.156 external hook will be named <literal>HG_FOO</literal>. 1.157 </para> 1.158 - 1.159 - </sect2> 1.160 + </sect2> 1.161 + 1.162 <sect2> 1.163 <title>Hook return values and activity control</title> 1.164 1.165 @@ -526,8 +417,8 @@ 1.166 zero/false means <quote>allow</quote>, while 1.167 non-zero/true/exception means <quote>deny</quote>. 1.168 </para> 1.169 - 1.170 - </sect2> 1.171 + </sect2> 1.172 + 1.173 <sect2> 1.174 <title>Writing an external hook</title> 1.175 1.176 @@ -555,8 +446,8 @@ 1.177 should not rely on environment variables being set to the 1.178 values you have in your environment when testing the hook. 1.179 </para> 1.180 - 1.181 - </sect2> 1.182 + </sect2> 1.183 + 1.184 <sect2> 1.185 <title>Telling Mercurial to use an in-process hook</title> 1.186 1.187 @@ -585,8 +476,8 @@ 1.188 for the callable object named <literal>myhook</literal>, and 1.189 calls it. 1.190 </para> 1.191 - 1.192 - </sect2> 1.193 + </sect2> 1.194 + 1.195 <sect2> 1.196 <title>Writing an in-process hook</title> 1.197 1.198 @@ -622,8 +513,8 @@ 1.199 </para> 1.200 1.201 &interaction.hook.msglen.go; 1.202 - 1.203 - </sect2> 1.204 + </sect2> 1.205 + 1.206 <sect2> 1.207 <title>Checking for trailing whitespace</title> 1.208 1.209 @@ -838,8 +729,8 @@ 1.210 forbidding pushes from specific users. 1.211 </para> 1.212 1.213 - </sect3> 1.214 - </sect2> 1.215 + </sect3> </sect2> 1.216 + 1.217 <sect2> 1.218 <title><literal 1.219 role="hg-ext">bugzilla</literal>&emdash;integration with 1.220 @@ -1144,8 +1035,8 @@ 1.221 a valid Bugzilla user name. 1.222 </para> 1.223 1.224 - </sect3> 1.225 - </sect2> 1.226 + </sect3> </sect2> 1.227 + 1.228 <sect2> 1.229 <title><literal role="hg-ext">notify</literal>&emdash;send email 1.230 notifications</title> 1.231 @@ -1344,8 +1235,8 @@ 1.232 APIs normally use. To convert a hash from hex to binary, use 1.233 the <literal>bin</literal> function. 1.234 </para> 1.235 - 1.236 - </sect2> 1.237 + </sect2> 1.238 + 1.239 <sect2> 1.240 <title>External hook execution</title> 1.241 1.242 @@ -1382,8 +1273,8 @@ 1.243 have succeeded. If it exits with a non-zero status, it is 1.244 considered to have failed. 1.245 </para> 1.246 - 1.247 - </sect2> 1.248 + </sect2> 1.249 + 1.250 <sect2> 1.251 <title>Finding out where changesets come from</title> 1.252 1.253 @@ -1425,8 +1316,8 @@ 1.254 being transferred to or from a bundle. 1.255 </para> 1.256 </listitem></itemizedlist> 1.257 - 1.258 </sect3> 1.259 + 1.260 <sect3 id="sec:hook:url"> 1.261 <title>Where changes are going&emdash;remote repository 1.262 URLs</title> 1.263 @@ -1462,7 +1353,6 @@ 1.264 discovered about the remote client. 1.265 </para> 1.266 </listitem></itemizedlist> 1.267 - 1.268 </sect3> 1.269 </sect2> 1.270 </sect1> 1.271 @@ -1520,8 +1410,8 @@ 1.272 role="hook">pretxnchangegroup</literal> (<xref 1.273 linkend="sec:hook:pretxnchangegroup"/>) 1.274 </para> 1.275 - 1.276 - </sect2> 1.277 + </sect2> 1.278 + 1.279 <sect2 id="sec:hook:commit"> 1.280 <title><literal role="hook">commit</literal>&emdash;after a new 1.281 changeset is created</title> 1.282 @@ -1553,8 +1443,8 @@ 1.283 role="hook">pretxncommit</literal> (<xref 1.284 linkend="sec:hook:pretxncommit"/>) 1.285 </para> 1.286 - 1.287 - </sect2> 1.288 + </sect2> 1.289 + 1.290 <sect2 id="sec:hook:incoming"> 1.291 <title><literal role="hook">incoming</literal>&emdash;after one 1.292 remote changeset is added</title> 1.293 @@ -1599,8 +1489,8 @@ 1.294 role="hook">pretxnchangegroup</literal> (<xref 1.295 linkend="sec:hook:pretxnchangegroup"/>) 1.296 </para> 1.297 - 1.298 - </sect2> 1.299 + </sect2> 1.300 + 1.301 <sect2 id="sec:hook:outgoing"> 1.302 <title><literal role="hook">outgoing</literal>&emdash;after 1.303 changesets are propagated</title> 1.304 @@ -1646,8 +1536,8 @@ 1.305 role="hook">preoutgoing</literal> (<xref 1.306 linkend="sec:hook:preoutgoing"/>) 1.307 </para> 1.308 - 1.309 - </sect2> 1.310 + </sect2> 1.311 + 1.312 <sect2 id="sec:hook:prechangegroup"> 1.313 <title><literal 1.314 role="hook">prechangegroup</literal>&emdash;before starting 1.315 @@ -1692,8 +1582,8 @@ 1.316 role="hook">pretxnchangegroup</literal> (<xref 1.317 linkend="sec:hook:pretxnchangegroup"/>) 1.318 </para> 1.319 - 1.320 - </sect2> 1.321 + </sect2> 1.322 + 1.323 <sect2 id="sec:hook:precommit"> 1.324 <title><literal role="hook">precommit</literal>&emdash;before 1.325 starting to commit a changeset</title> 1.326 @@ -1732,8 +1622,8 @@ 1.327 role="hook">pretxncommit</literal> (<xref 1.328 linkend="sec:hook:pretxncommit"/>) 1.329 </para> 1.330 - 1.331 - </sect2> 1.332 + </sect2> 1.333 + 1.334 <sect2 id="sec:hook:preoutgoing"> 1.335 <title><literal role="hook">preoutgoing</literal>&emdash;before 1.336 starting to propagate changesets</title> 1.337 @@ -1769,8 +1659,8 @@ 1.338 role="hook">outgoing</literal> (<xref 1.339 linkend="sec:hook:outgoing"/>) 1.340 </para> 1.341 - 1.342 - </sect2> 1.343 + </sect2> 1.344 + 1.345 <sect2 id="sec:hook:pretag"> 1.346 <title><literal role="hook">pretag</literal>&emdash;before 1.347 tagging a changeset</title> 1.348 @@ -1811,6 +1701,7 @@ 1.349 (<xref linkend="sec:hook:tag"/>) 1.350 </para> 1.351 </sect2> 1.352 + 1.353 <sect2 id="sec:hook:pretxnchangegroup"> 1.354 <title><literal 1.355 role="hook">pretxnchangegroup</literal>&emdash;before 1.356 @@ -1875,8 +1766,8 @@ 1.357 role="hook">prechangegroup</literal> (<xref 1.358 linkend="sec:hook:prechangegroup"/>) 1.359 </para> 1.360 - 1.361 - </sect2> 1.362 + </sect2> 1.363 + 1.364 <sect2 id="sec:hook:pretxncommit"> 1.365 <title><literal role="hook">pretxncommit</literal>&emdash;before 1.366 completing commit of new changeset</title> 1.367 @@ -1901,8 +1792,8 @@ 1.368 race conditions if you do not take steps to avoid them. 1.369 </para> 1.370 1.371 - <para id="x_2d2">Parameters to this hook: 1.372 - </para> 1.373 + <para id="x_2d2">Parameters to this hook:</para> 1.374 + 1.375 <itemizedlist> 1.376 <listitem><para id="x_2d3"><literal>node</literal>: A changeset ID. The 1.377 changeset ID of the newly committed changeset. 1.378 @@ -1923,8 +1814,8 @@ 1.379 role="hook">precommit</literal> (<xref 1.380 linkend="sec:hook:precommit"/>) 1.381 </para> 1.382 - 1.383 - </sect2> 1.384 + </sect2> 1.385 + 1.386 <sect2 id="sec:hook:preupdate"> 1.387 <title><literal role="hook">preupdate</literal>&emdash;before 1.388 updating or merging working directory</title> 1.389 @@ -1955,8 +1846,8 @@ 1.390 1.391 <para id="x_2db">See also: <literal role="hook">update</literal> 1.392 (<xref linkend="sec:hook:update"/>)</para> 1.393 - 1.394 - </sect2> 1.395 + </sect2> 1.396 + 1.397 <sect2 id="sec:hook:tag"> 1.398 <title><literal role="hook">tag</literal>&emdash;after tagging a 1.399 changeset</title> 1.400 @@ -1992,8 +1883,8 @@ 1.401 <para id="x_2e2">See also: <literal role="hook">pretag</literal> 1.402 (<xref linkend="sec:hook:pretag"/>) 1.403 </para> 1.404 - 1.405 - </sect2> 1.406 + </sect2> 1.407 + 1.408 <sect2 id="sec:hook:update"> 1.409 <title><literal role="hook">update</literal>&emdash;after 1.410 updating or merging working directory</title>