Mercurial > hgbook
comparison ja/hook.tex @ 838:d1f676a6a4b3 default tip
update mq chapter.
propagate ef53d025f410.
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Thu, 03 Dec 2009 01:26:08 +0900 |
parents | 8a3041e6f3cb |
children |
comparison
equal
deleted
inserted
replaced
837:b775f963b18c | 838:d1f676a6a4b3 |
---|---|
287 | 287 |
288 $BB?$/$N%f!<%6$,(Bpull$B$9$k%5!<%P$KC/$+$,%A%'%s%8%;%C%H$r(Bpush$B$7$?>l9g!$%5!<%P(B | 288 $BB?$/$N%f!<%6$,(Bpull$B$9$k%5!<%P$KC/$+$,%A%'%s%8%;%C%H$r(Bpush$B$7$?>l9g!$%5!<%P(B |
289 $B$O%A%'%s%8%;%C%H$r915WE*$K<u$1F~$l$kA0$K%A%'%C%/$r9T$$!$0lO"$N%F%9%H$r%Q(B | 289 $B$O%A%'%s%8%;%C%H$r915WE*$K<u$1F~$l$kA0$K%A%'%C%/$r9T$$!$0lO"$N%F%9%H$r%Q(B |
290 $B%9$G$-$J$1$l$P%j%8%'%/%H$r9T$&!%%f!<%6$,$3$N%U%#%k%?%5!<%P$+$i$N$_(Bpull$B$r(B | 290 $B%9$G$-$J$1$l$P%j%8%'%/%H$r9T$&!%%f!<%6$,$3$N%U%#%k%?%5!<%P$+$i$N$_(Bpull$B$r(B |
291 $B9T$&$N$G$"$l$P!$A4$F$NJQ99$O<+F0E*$KA4$F8!::$5$l$F$$$k$3$H$K$J$k!%(B | 291 $B9T$&$N$G$"$l$P!$A4$F$NJQ99$O<+F0E*$KA4$F8!::$5$l$F$$$k$3$H$K$J$k!%(B |
292 | |
293 %\section{Care with \texttt{pretxn} hooks in a shared-access repository} | |
294 \section{$B6&M-%"%/%;%9%j%]%8%H%j$G(B\texttt{pretxn}$B%U%C%/$r;H$&(B} | |
295 | |
296 %If you want to use hooks to do some automated work in a repository | |
297 %that a number of people have shared access to, you need to be careful | |
298 %in how you do this. | |
299 | |
300 $BJ#?t$N%f!<%6$,6&M-%"%/%;%9$r9T$&%j%]%8%H%j$G!$<+F02=$5$l$?:n6H$r9T$&$?$a(B | |
301 $B$K%U%C%/$r;HMQ$7$?$$$J$i!$$I$N$h$&$K9T$&$+Cm0U?<$/9M$($kI,MW$,$"$k!%(B | |
302 | |
303 %Mercurial only locks a repository when it is writing to the | |
304 %repository, and only the parts of Mercurial that write to the | |
305 %repository pay attention to locks. Write locks are necessary to | |
306 %prevent multiple simultaneous writers from scribbling on each other's | |
307 %work, corrupting the repository. | |
308 | |
309 Mercurial$B$O%j%]%8%H%j$K=q$-9~$_$r9T$&$H$-$K$@$1%j%]%8%H%j$r%m%C%/$9$k!%(B | |
310 $B$^$?(BMercurial$B$N=q$-9~$_$r9T$&ItJ,$N$_$,%m%C%/$r9MN8$9$k!%=q$-9~$_%m%C%/(B | |
311 $B$O!$J#?t$NF1;~=q$-9~$_$,B>$NJQ99$r>e=q$-$7!$%j%]%8%H%j$rGKB;$9$k$N$rKI$0!%(B | |
312 | |
313 %Because Mercurial is careful with the order in which it reads and | |
314 %writes data, it does not need to acquire a lock when it wants to read | |
315 %data from the repository. The parts of Mercurial that read from the | |
316 %repository never pay attention to locks. This lockless reading scheme | |
317 %greatly increases performance and concurrency. | |
318 | |
319 Mercurial$B$O%G!<%?$NFI$_=q$-$N=g=x$rCm0U?<$/9T$&$?$a!$%j%]%8%H%j$+$i$N%G!<(B | |
320 $B%?FI$_=P$7$N:]$K%m%C%/$r<hF@$9$kI,MW$,$J$$!%(B Mercurial$B$N%j%]%8%H%j$+$iFI(B | |
321 $B$_=P$7$r9T$&ItJ,$O!$%m%C%/$rA4$/5$$K$9$kI,MW$,$J$$!%$3$N%m%C%/$J$7FI$_=P(B | |
322 $B$7$K$h$C$F!$F1;~<B9T@-$H@-G=$rBgI}$K9b$a$F$$$k!%(B | |
323 | |
324 %With great performance comes a trade-off, though, one which has the | |
325 %potential to cause you trouble unless you're aware of it. To describe | |
326 %this requires a little detail about how Mercurial adds changesets to a | |
327 %repository and reads those changes. | |
328 | |
329 $B$7$+$7$J$,$i$3$N9b@-G=$O$=$l$rCN$i$J$1$l$PLdBj$r0z$-5/$3$9$"$k%H%l!<%I%*(B | |
330 $B%U$r$b$b$?$i$9!%$3$l$r@bL@$9$k$?$a$K!$(BMercurial$B$,$I$N$h$&$K%A%'%s%8%;%C%H(B | |
331 $B$r%j%]%8%H%j$KDI2C$7!$$=$l$i$rFI$_=P$9$+$N>\:Y$K?($l$J$1$l$P$J$i$J$$!%(B | |
332 | |
333 %When Mercurial \emph{writes} metadata, it writes it straight into the | |
334 %destination file. It writes file data first, then manifest data | |
335 %(which contains pointers to the new file data), then changelog data | |
336 %(which contains pointers to the new manifest data). Before the first | |
337 %write to each file, it stores a record of where the end of the file | |
338 %was in its transaction log. If the transaction must be rolled back, | |
339 %Mercurial simply truncates each file back to the size it was before the | |
340 %transaction began. | |
341 | |
342 Mercurial$B$O%a%?%G!<%?$r(B\emph{$B=q$-9~$`(B}$B$H$-!$D>@\L\E*$N%U%!%$%k$K=q$-9~$_(B | |
343 $B$9$k!%(BMercurial$B$O$^$:%U%!%$%k%G!<%?$r=q$-9~$_!$<!$$$G!J?7$7$$%U%!%$%k%G!<(B | |
344 $B%?$N>l=j$r<($9%]%$%s%?$r4^$`!K%^%K%U%'%9%H%G!<%?$r=q$-9~$`!%$=$7$F!J?7$7(B | |
345 $B$$%^%K%U%'%9%H%G!<%?$N>l=j$r<($9%]%$%s%?$r4^$`!K%A%'%s%8%m%0%G!<%?$r=q$-(B | |
346 $B9~$`!%3F!9$N%U%!%$%k$X$N:G=i$N=q$-9~$_$NA0$K!$%U%!%$%k$NKvHx$N%l%3!<%I$r(B | |
347 $B%H%i%s%6%/%7%g%s%m%0$KJ]B8$9$k!%%H%i%s%6%/%7%g%s$,%m!<%k%P%C%/$5$l$k>l9g(B | |
348 $B$O!$(BMercurial$B$O3F!9$N%U%!%$%k$r%H%i%s%6%/%7%g%s$,;O$^$kA0$N%5%$%:$K@Z$j5M(B | |
349 $B$a$k!%(B | |
350 | |
351 %When Mercurial \emph{reads} metadata, it reads the changelog first, | |
352 %then everything else. Since a reader will only access parts of the | |
353 %manifest or file metadata that it can see in the changelog, it can | |
354 %never see partially written data. | |
355 | |
356 Mercurial$B$O%a%?%G!<%?$r(B\emph{$BFI$`(B}$B;~$K$^$:%A%'%s%8%m%0$rFI$_!$<!$$$G;D$j(B | |
357 $B$NItJ,$rFI$`!%%j!<%@$O%A%'%s%8%m%0$K8=$l$k%^%K%U%'%9%H$N0lIt$^$?$O%U%!%$(B | |
358 $B%k%a%?%G!<%?$N0lIt$K$N$_%"%/%;%9$9$k$?$a!$ItJ,E*$K=q$+$l$?%G!<%?$r8+$k$3(B | |
359 $B$H$O$G$-$J$$!%(B | |
360 | |
361 %Some controlling hooks (\hook{pretxncommit} and | |
362 %\hook{pretxnchangegroup}) run when a transaction is almost complete. | |
363 %All of the metadata has been written, but Mercurial can still roll the | |
364 %transaction back and cause the newly-written data to disappear. | |
365 | |
366 $B$$$/$D$+$N@)8f%U%C%/!J(B\hook{pretxncommit}$B$H(B\hook{pretxnchangegroup}$B!K$O%H(B | |
367 $B%i%s%6%/%7%g%s$,$[$\40N;$7$?;~$K<B9T$5$l$k!%$9$Y$F$N%a%?%G!<%?$,=q$-9~$^(B | |
368 $B$l$k$,!$$3$N;~E@$G$b(BMercurial$B$O%H%i%s%6%/%7%g%s$r85$KLa$9$3$H$,$G$-!$$=$N(B | |
369 $B>l9g$O?7$7$/=q$+$l$?%G!<%?$O>C<:$9$k!%(B | |
370 | |
371 %If one of these hooks runs for long, it opens a window of time during | |
372 %which a reader can see the metadata for changesets that are not yet | |
373 %permanent, and should not be thought of as ``really there''. The | |
374 %longer the hook runs, the longer that window is open. | |
375 | |
376 $B$3$l$i$N%U%C%/$N$&$A(B1$B$D$,D9;~4V$K$o$?$C$F<B9T$5$l$F$$$k$H!$%j!<%@$,%A%'%s(B | |
377 $B%8%;%C%H$N%a%?%G!<%?$rFI$`$3$H$N$G$-$k%?%$%`%&%#%s%I%&$,3+$/!%$3$N%A%'%s(B | |
378 $B%8%;%C%H$O$^$@1JB3E*$J$b$N$K$J$C$F$*$i$:!$=>$C$F<B:_$9$k$H9M$($k$Y$-$G$O(B | |
379 $B$J$$$b$N$G$"$k!%%U%C%/$,<B9T$5$l$F$$$k;~4V$,D9$/$J$l$P$J$k$[$I!$%?%$%`%&%#(B | |
380 $B%s%I%&$,3+$/;~4V$bD9$/$J$k!%(B | |
381 | |
382 %\subsection{The problem illustrated} | |
383 \subsection{$BLdBj$N>\:Y(B} | |
384 | |
385 %In principle, a good use for the \hook{pretxnchangegroup} hook would | |
386 %be to automatically build and test incoming changes before they are | |
387 %accepted into a central repository. This could let you guarantee that | |
388 %nobody can push changes to this repository that ``break the build''. | |
389 %But if a client can pull changes while they're being tested, the | |
390 %usefulness of the test is zero; an unsuspecting someone can pull | |
391 %untested changes, potentially breaking their build. | |
392 | |
393 $B<BMQ$K$*$1$k(B\hook{pretxnchangegroup}$B%U%C%/$NNI$$;HMQK!$H$7$F$O!$E~Ce$7$?(B | |
394 $BJQ99$,Cf1{$N%j%]%8%H%j$K<h$j9~$^$l$kA0$K<+F0$G%S%k%I$H%F%9%H$r9T$&$3$H$,(B | |
395 $B9M$($i$l$k!%$3$l$K$h$j!$%S%k%I$rK8$2$kJQ99$OC/$b%j%]%8%H%j$K(Bpush$B$G$-$J$$(B | |
396 $B$3$H$,3N<B$K$J$k!%%/%i%$%"%s%H$,%F%9%HCf$KJQ99$r(Bpull$B$9$k$3$H$,$G$-$l$P!$(B | |
397 $B$3$N%F%9%H$NM-MQ@-$O%<%m$K$J$C$F$7$^$&!%5?$$$r;}$?$:$KC/$+$,%F%9%H$5$l$F(B | |
398 $B$$$J$$JQ99$r(Bpull$B$G$-$k$N$G$"$l$P!$H`$i$N%S%k%I$O<:GT$9$k2DG=@-$,$"$k!%(B | |
399 | |
400 %The safest technological answer to this challenge is to set up such a | |
401 %``gatekeeper'' repository as \emph{unidirectional}. Let it take | |
402 %changes pushed in from the outside, but do not allow anyone to pull | |
403 %changes from it (use the \hook{preoutgoing} hook to lock it down). | |
404 %Configure a \hook{changegroup} hook so that if a build or test | |
405 %succeeds, the hook will push the new changes out to another repository | |
406 %that people \emph{can} pull from. | |
407 | |
408 $B$3$NLdBj$X$N5;=QE*$K:G$b0BA4$J2sEz$O!$(B``$BLgHV(B''$B%j%]%8%H%j$r(B\emph{$B0lJ}8~(B}$B$K(B | |
409 $B@_Dj$9$k$3$H$G$"$k!%%j%]%8%H%j$r30It$+$i(Bpush$B$5$l$?JQ99$r<u$1<h$k$,!$C/$b(B | |
410 pull$B$G$-$J$$$h$&$K@_Dj$9$k!J(B\hook{preoutgoing}$B%U%C%/$r;H$C$F%j%]%8%H%j$r(B | |
411 $B%m%C%/$9$k!K!%(B\hook{changegroup}$B%U%C%/$r@_Dj$7!$%S%k%I$d%F%9%H$,@.8y$7$?(B | |
412 $B$H$-$K8B$C$F!$%U%C%/$,?7$?$JJQ99$r%f!<%6$N(Bpull\emph{$B$G$-$k(B}$BJL$N%j%]%8%H(B | |
413 $B%j$K(Bpush$B$9$k$h$&$K$9$k!%(B | |
414 | |
415 %In practice, putting a centralised bottleneck like this in place is | |
416 %not often a good idea, and transaction visibility has nothing to do | |
417 %with the problem. As the size of a project---and the time it takes to | |
418 %build and test---grows, you rapidly run into a wall with this ``try | |
419 %before you buy'' approach, where you have more changesets to test than | |
420 %time in which to deal with them. The inevitable result is frustration | |
421 %on the part of all involved. | |
422 | |
423 $B<B:]>e$O!$$3$N$h$&$K=8Cf$7$?%\%H%k%M%C%/$rCV$/$3$H$ONI$$9M$($H$O8@$($:!$(B | |
424 $B%H%i%s%6%/%7%g%s$N2D;k@-$OA4$/$J$$!%%W%m%8%'%/%H$N%5%$%:$*$h$S%S%k%I$H%F(B | |
425 $B%9%H$KMW$9$k;~4V$,A}2C$9$k$K=>$C$F!$$3$N$h$&$J(B``$B;vA0$K;n$9(B''$B<jK!$OJI$KFM(B | |
426 $B$-Ev$?$k!%%F%9%H$K;H$($k;~4V$G;+$-@Z$l$J$$$[$I$N%A%'%s%8%;%C%H$r;n$5$J$1(B | |
427 $B$l$P$J$i$J$/$J$k$+$i$G$"$k!%%U%i%9%H%l!<%7%g%s$,Cy$k$N$OHr$1$i$l$J$$$@$m(B | |
428 $B$&!%(B | |
429 | |
430 %An approach that scales better is to get people to build and test | |
431 %before they push, then run automated builds and tests centrally | |
432 %\emph{after} a push, to be sure all is well. The advantage of this | |
433 %approach is that it does not impose a limit on the rate at which the | |
434 %repository can accept changes. | |
435 | |
436 $B$h$j%9%1!<%k$9$k<jK!$O!$3+H/<T$K(Bpush$BA0$N%S%k%I$H%F%9%H$r$5$;$k$3$H$G$"(B | |
437 $B$k!%Cf1{$G<+F0$K$h$k%S%k%I$H%F%9%H$r9T$&$N$O!$(Bpush\emph{$B8e(B}$B$K!$A4$F$KLdBj(B | |
438 $B$,$J$$$3$H$r3NG'$9$k$?$a$K9T$&!%$3$N%"%W%m!<%A$NMxE@$O%j%]%8%H%j$,JQ99$r(B | |
439 $B<u$1F~$l$k%Z!<%9$K2?$b@)8B$r2]$5$J$$$3$H$G$"$k!%(B | |
440 | 292 |
441 %\section{A short tutorial on using hooks} | 293 %\section{A short tutorial on using hooks} |
442 \section{$B%U%C%/$N;HMQK!(B} | 294 \section{$B%U%C%/$N;HMQK!(B} |
443 \label{sec:hook:simple} | 295 \label{sec:hook:simple} |
444 | 296 |