view ja/hgext.tex @ 358:1348ce7d2d77

more hgext.tex
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 02 Sep 2008 19:03:38 +0900
parents ef197f25f11e
children 81116699a510
line wrap: on
line source

%\chapter{Adding functionality with extensions}
\chapter{$B3HD%$K$h$k5!G=$NDI2C(B}
\label{chap:hgext}

%While the core of Mercurial is quite complete from a functionality
%standpoint, it's deliberately shorn of fancy features.  This approach
%of preserving simplicity keeps the software easy to deal with for both
%maintainers and users.

$B5!G=$N4QE@$+$i8+$k$H(BMercurial$B$O$+$J$j40Hw$7$F$$$k$,!$GI<j$J5!G=$K$D$$$F$O(B
$B0U?^E*$KGS=|$7$F$$$k!%(BMercurial$B$N%a%s%F%J$H%f!<%6$NAPJ}$K$H$C$FC1=c$5$rJ](B
$B$D$?$a$K$3$N%"%W%m!<%A$r<h$C$F$$$k!%(B

%However, Mercurial doesn't box you in with an inflexible command set:
%you can add features to it as \emph{extensions} (sometimes known as
%\emph{plugins}).  We've already discussed a few of these extensions in
%earlier chapters.

$B$7$+$7$J$,$i!$(BMercurial$B$OM;DL$NMx$+$J$$%3%^%s%I%;%C%H$rDs6!$7$F$$$k$N$G$O(B
$B$J$$!%(B\emph{extensions}$B!J$"$k$$$O(B\emph{plugins}$B$H8F$P$l$k$3$H$b$"$k!K$K$h$C(B
$B$F5!G=$rDI2C$9$k$3$H$,$G$-$k!%$3$l$i$N$$$/$D$+$K$D$$$F$O!$0JA0$N>O$G8+$F(B
$B$$$k!%(B

\begin{itemize}
%\item Section~\ref{sec:tour-merge:fetch} covers the \hgext{fetch}
%  extension; this combines pulling new changes and merging them with
%  local changes into a single command, \hgxcmd{fetch}{fetch}.
\item $B%;%/%7%g%s(B\ref{sec:tour-merge:fetch}$B$O(B\hgext{fetch}$B%(%/%9%F%s%7%g%s(B
       $B$r%+%P!<$7$F$$$k!%$3$l$O?7$7$$JQ99$r(Bpull$B$7!$%m!<%+%k$JJQ99$H%^!<%8(B
       $B$rC10l$N%3%^%s%I(B\hgxcmd{fetch}{fetch}$B$G<B9T$9$k!%(B
%\item In chapter~\ref{chap:hook}, we covered several extensions that
%  are useful for hook-related functionality: \hgext{acl} adds access
%  control lists; \hgext{bugzilla} adds integration with the Bugzilla
%  bug tracking system; and \hgext{notify} sends notification emails on
%  new changes.
\item \ref{chap:hook}$B$G$O!$%U%C%/$K4XO"$7$?$$$/$D$+$N3HD%$K$D$$$F07$&!%(B
\hgext{acl}$B$O%"%/%;%9@)8f%j%9%H$rDI2C$9$k!%(B\hgext{bugzilla}$B$O(BBugzilla$B5!G=(B
$B$NE}9g5!G=$rDs6!$9$k!%(B\hgext{notify}$B$O!$?7$?$JJQ99$N:]$KDLCNEE;R%a!<%k$r(B
$BAw$k5!G=$rDs6!$9$k!%(B
%\item The Mercurial Queues patch management extension is so invaluable
%  that it merits two chapters and an appendix all to itself.
%  Chapter~\ref{chap:mq} covers the basics;
%  chapter~\ref{chap:mq-collab} discusses advanced topics; and
%  appendix~\ref{chap:mqref} goes into detail on each command.
\item Mercurial Queue$B$H$$$&%Q%C%A%^%M!<%8%a%s%H3HD%$O!$Hs>o$K=EMW$J$N$G(B2
      $B>O$HIUO?(B1$B>O$rHq$d$7$F@bL@$9$k!%(B
  Chapter~\ref{chap:mq}$B$O4pK\E*$J5!G=$r@bL@$9$k!%(B
  chapter~\ref{chap:mq-collab}$B$G$O9bEY$J5!G=$K$D$$$F@bL@$7!$(B
  appendix~\ref{chap:mqref}$B$G$O3F%3%^%s%I$N>\:Y$r@bL@$9$k!%(B
\end{itemize}

%In this chapter, we'll cover some of the other extensions that are
%available for Mercurial, and briefly touch on some of the machinery
%you'll need to know about if you want to write an extension of your
%own.
$B$3$N>O$G$O(BMercurial$B$GMxMQ2DG=$J$=$NB>$N3HD%$K$D$$$F<h$j07$$!$$^$?<+J,$G(B
Mercurial$B3HD%$r=q$/;~$KLrN)$DFbIt$N5!9=$K$D$$$F$b@bL@$9$k!%(B
\begin{itemize}
%\item In section~\ref{sec:hgext:inotify}, we'll discuss the
%  possibility of \emph{huge} performance improvements using the
%  \hgext{inotify} extension.
\item \ref{sec:hgext:inotify}$B@a$G$O(B\hgext{inotify}$B3HD%$rMQ$$$k$3$H$GF@$i(B
      $B$l$k(B\emph{$BBg$-$J(B}$B@-G=8~>e$K$D$$$F=R$Y$k!%(B
\end{itemize}

%\section{Improve performance with the \hgext{inotify} extension}
\section{\hgext{inotify}$B3HD%$K$h$k@-G=8~>e(B}
\label{sec:hgext:inotify}

%Are you interested in having some of the most common Mercurial
%operations run as much as a hundred times faster?  Read on!
Mercurial$B$N:G$bB?MQ$5$l$k%3%^%s%I$N$$$/$D$+$,?tI4G\B.$/$J$k$3$H$K6=L#$,$"(B
$B$k$J$i$P$<$RFI$s$GM_$7$$!*(B

%Mercurial has great performance under normal circumstances.  For
%example, when you run the \hgcmd{status} command, Mercurial has to
%scan almost every directory and file in your repository so that it can
%display file status.  Many other Mercurial commands need to do the
%same work behind the scenes; for example, the \hgcmd{diff} command
%uses the status machinery to avoid doing an expensive comparison
%operation on files that obviously haven't changed.

$BDL>o$N>r7o2<$G(BMercurial$B$O9b$$@-G=$r;}$C$F$$$k$,!$(B \hgcmd{status}$B%3%^%s%I(B
$B$r<B9T$7$?;~!$(BMercurial$B$O$[$\A4$F$N%G%#%l%/%H%j$H%U%!%$%k$r%9%-%c%s$9$k$3(B
$B$H$K$J$k!%B>$NB?$/$N(BMercurial$B%3%^%s%I$O!$$3$N$h$&$JA`:n$r0U<1$5$;$J$$$h$&(B
$B$K$J$C$F$$$k!%Nc$($P(B\hgcmd{diff}$B$O%9%F!<%?%95!9=$rMQ$$$F!$L@$i$+$KJQ99$5(B
$B$l$F$$$J$$%U%!%$%k$NHf3S$rHr$1$F$$$k!%(B

%Because obtaining file status is crucial to good performance, the
%authors of Mercurial have optimised this code to within an inch of its
%life.  However, there's no avoiding the fact that when you run
%\hgcmd{status}, Mercurial is going to have to perform at least one
%expensive system call for each managed file to determine whether it's
%changed since the last time Mercurial checked.  For a sufficiently
%large repository, this can take a long time.

$BNI$$@-G=$rF@$k$?$a$K$O!$%U%!%$%k%9%F!<%?%9$N<hF@$,=EMW$J4X?4;v$H$J$k$?(B
$B$a!$(BMercurial$B$N:n<T$?$A$O$3$l$r$.$j$.$j$N$H$3$m$^$G:GE,2=$7$F$$$k!%$7$+$7(B
\hgcmd{status}$B%3%^%s%I$G$O$3$l$rHr$1$k<jN)$F$,$J$$!%(B Mercurial$B$O!$4IM}$7(B
$B$F$$$k%U%!%$%k$,:G8e$K%A%'%C%/$7$?;~$+$iJQ99$5$l$F$$$k$+D4$Y$k$?$a$K!$>/(B
$B$J$/$H$b0l$D$N9b2A$J%7%9%F%`%3!<%k$r$9$kI,MW$,$"$k!%$"$kDxEY0J>eBg$-$J%j(B
$B%]%8%H%j$G$O!$$3$NA`:n$K$OD9$$;~4V$rMW$9$k!%(B

%To put a number on the magnitude of this effect, I created a
%repository containing 150,000 managed files.  I timed \hgcmd{status}
%as taking ten seconds to run, even when \emph{none} of those files had
%been modified.

$B$3$N1F6A$K$D$$$FD4$Y$k$?$a$K(B150,000$B$N%U%!%$%k$rMJ$9$k%j%]%8%H%j$r:n@.$7(B
$B$?!%(B\emph{$B$^$C$?$/(B}$BJQ99$,$J$$>l9g$G$b(B\hgcmd{status}$B%3%^%s%I$N<B9T$K$O(B10
$BIC$rMW$7$?!%(B

%Many modern operating systems contain a file notification facility.
%If a program signs up to an appropriate service, the operating system
%will notify it every time a file of interest is created, modified, or
%deleted.  On Linux systems, the kernel component that does this is
%called \texttt{inotify}.

$B6aG/$N%*%Z%l!<%F%#%s%0%7%9%F%`$O!$%U%!%$%kDLCN$N5!9=$rHw$($F$$$k!%%W%m%0(B
$B%i%`$,E,@Z$J%5!<%S%9$KEPO?$9$k$H!$%*%Z%l!<%F%#%s%0%7%9%F%`$OBP>]$H$J$k%U%!(B
$B%$%k$N:n@.!$JQ99!$:o=|$r%W%m%0%i%`$KDLCN$9$k!%(B Linux$B%7%9%F%`$G$O$3$l$r9T(B
$B$&%+!<%M%k%3%s%]!<%M%s%H$O(B\texttt{inotify}$B$H8F$P$l$k!%(B

%Mercurial's \hgext{inotify} extension talks to the kernel's
%\texttt{inotify} component to optimise \hgcmd{status} commands.  The
%extension has two components.  A daemon sits in the background and
%receives notifications from the \texttt{inotify} subsystem.  It also
%listens for connections from a regular Mercurial command.  The
%extension modifies Mercurial's behaviour so that instead of scanning
%the filesystem, it queries the daemon.  Since the daemon has perfect
%information about the state of the repository, it can respond with a
%result instantaneously, avoiding the need to scan every directory and
%file in the repository.

Mercurial$B$N(B\hgext{inotify}$B3HD%$O!$(B\hgcmd{status}$B%3%^%s%I$r:GE,2=$9$k$?$a(B
$B$K!$%+!<%M%k$N(B\texttt{inotify}$B%3%s%]!<%M%s%H$X%"%/%;%9$9$k!%$3$N3HD%$O(B2$B$D(B
$B$N%3%s%]!<%M%s%H$+$i$J$k!%(B \texttt{inotify}$B%5%V%7%9%F%`$+$iDLCN$r<u$1<h$k(B
$B$?$a$N%G!<%b%s$,%P%C%/%0%i%s%I$GF0:n$9$k!%$3$N%G!<%b%s$O(BMercurial$B$NB>$N%3(B
$B%^%s%I$+$i$N@\B3$b<u$1IU$1$k!%$3$N3HD%$O(BMercurial$B$N5sF0$rJQ99$7!$%U%!%$%k(B
$B%7%9%F%`$r%9%-%c%s$9$k$N$G$O$J$/!$%G!<%b%s$X$NLd$$9g$o$;$r9T$&$h$&$K$9(B
$B$k!%%G!<%b%s$O%j%]%8%H%j$N>uBV$r40A4$KGD0.$7$F$$$k$N$G!$D>$A$KLd$$9g$o$;(B
$B$KJVEz$9$k$3$H$,$G$-!$%j%]%8%H%j$N%G%#%l%/%H%j$H%U%!%$%k$N%9%-%c%s$rHr$1(B
$B$k$3$H$,$G$-$k!%(B

%Recall the ten seconds that I measured plain Mercurial as taking to
%run \hgcmd{status} on a 150,000 file repository.  With the
%\hgext{inotify} extension enabled, the time dropped to 0.1~seconds, a
%factor of \emph{one hundred} faster.

$B%W%l!<%s$J(BMercurial$B$G$O(B\hgcmd{status}$B%3%^%s%I$,(B150,000$B%U%!%$%k$N%j%]%8%H(B
$B%j$KBP$7$F(B10$BIC$rMW$7$F$$$?$3$H$r;W$$=P$7$FM_$7$$!#(B
\hgext{inotify}$B3HD%$r;H$C$?>l9g!"=jMW;~4V$O(B0.1$BIC$K2<$,$j!$(B\emph{100}$BG\B.(B
$B$/$J$C$F$$$k$3$H$,J,$+$k!%(B

%Before we continue, please pay attention to some caveats.
$B$5$i$K?J$`A0$K!$Cm0UE@$r5s$2$k!%(B
\begin{itemize}
%\item The \hgext{inotify} extension is Linux-specific.  Because it
%  interfaces directly to the Linux kernel's \texttt{inotify}
%  subsystem, it does not work on other operating systems.
 \item \hgext{inotify}$B3HD%$O(BLinux$BFCM-$N$b$N$G$"$k!%$3$N5!G=3HD%$O(BLinux$B$N(B
       \texttt{inotify}$B%5%V%7%9%F%`$KD>@\%"%/%;%9$9$k$?$a!$B>$N%*%Z%l!<(B
       $B%F%#%s%0%7%9%F%`$G$OF0:n$7$J$$!%(B

%\item It should work on any Linux distribution that was released after
%  early~2005.  Older distributions are likely to have a kernel that
%  lacks \texttt{inotify}, or a version of \texttt{glibc} that does not
%  have the necessary interfacing support.
 \item 2005$BG/=i$a0J9_$K%j%j!<%9$5$l$?$I$N$h$&$J(BLinux$B%G%#%9%H%j%S%e!<%7%g(B
       $B%s$G$bF0:n$9$k$O$:$@$,!$8E$$%G%#%9%H%j%S%e!<%7%g%s$G$O(B
       \texttt{inotify}$B$r7g$$$F$$$?$j!$I,MW$J%$%s%?!<%U%'!<%9%5%]!<%H$r(B
       \texttt{glibc}$B$,Ds6!$7$F$$$J$+$C$?$j$9$k2DG=@-$,$"$k!%(B

%\item Not all filesystems are suitable for use with the
%  \hgext{inotify} extension.  Network filesystems such as NFS are a
%  non-starter, for example, particularly if you're running Mercurial

%  on several systems, all mounting the same network filesystem.  The
%  kernel's \texttt{inotify} system has no way of knowing about changes
%  made on another system.  Most local filesystems (e.g.~ext3, XFS,
%  ReiserFS) should work fine.
 \item $BA4$F$N%U%!%$%k%7%9%F%`$,(B\hgext{inotify}$B3HD%$GMxMQ2DG=$J$o$1$G$O$J(B
       $B$$!%Nc$((B
$B$P(BMercurial$B$r$$$/$D$+$N%7%9%F%`$GF0:n$5$;$F$$$k>l9g!$F10l$N%M%C%H%o!<%/%U%!(B
$B%$%k%7%9%F%`$r3F!9$N%7%9%F%`$G%^%&%s%H$7$F$$$k$3$H$,B?$$$,!$(B NFS$B$J$I$N%M%C(B
$B%H%o!<%/%U%!%$%k%7%9%F%`$O9MN8$5$l$F$$$J$$!%(B
\end{itemize}

%The \hgext{inotify} extension is not yet shipped with Mercurial as of
%May~2007, so it's a little more involved to set up than other
%extensions.  But the performance improvement is worth it!

2007$BG/(B5$B7n$^$G$O(B\hgext{inotify}$B3HD%$O(BMercurial$B$KF1:-$5$l$F$$$J$+$C$?!%$=$N(B
$B$?$a!$%;%C%H%"%C%W$OB>$N3HD%$KHf$Y$F$d$dJ#;($@$,!$F@$i$l$k@-G=8~>e$O$K$O(B
$B$=$l$@$1$N2ACM$,$"$k!%(B

%The extension currently comes in two parts: a set of patches to the
%Mercurial source code, and a library of Python bindings to the
%\texttt{inotify} subsystem.

$B8=:_!$3HD%$O(B2$B$D$N%Q!<%H$KJ,$+$l$F$$$k!%(BMercurial$B%=!<%9%3!<%I$X$N%Q%C%A$H(B
\texttt{inotify}$B%5%V%7%9%F%`$X$N(BPython$B%P%$%s%G%#%s%0%i%$%V%i%j$G$"$k!%(B

\begin{note}
%  There are \emph{two} Python \texttt{inotify} binding libraries.  One
%  of them is called \texttt{pyinotify}, and is packaged by some Linux
%  distributions as \texttt{python-inotify}.  This is \emph{not} the
%  one you'll need, as it is too buggy and inefficient to be practical.

Python$B$N(B\texttt{inotify}$B%P%$%s%G%#%s%0%i%$%V%i%j$O(B\emph{2$B$D(B}$B$"$k!%(B1$B$D$O(B
\texttt{pyinotify}$B$G$"$j!$$$$/$D$+$N(BLinux$B%G%#%9%H%j%S%e!<%7%g%s$G$O(B
\texttt{python-inotify}$B$H$7$F%Q%C%1!<%82=$5$l$F$$$k!%$3$l$O%P%0$,Hs>o$KB?(B
$B$/!$<BMQ$9$k$K$OHs8zN(E*$G$"$j!$;H$&$Y$-$G(B\emph{$B$J$$(B}$B!%(B
\end{note}
%To get going, it's best to already have a functioning copy of
%Mercurial installed.
$B@h$X?J$`$KEv$C$F!$@5$7$/5!G=$9$k(BMercurial$B$,%$%s%9%H!<%k$5$l$F$$$k$3$H$,(B
$BK>$^$7$$!%(B

\begin{note}
%  If you follow the instructions below, you'll be \emph{replacing} and
%  overwriting any existing installation of Mercurial that you might
%  already have, using the latest ``bleeding edge'' Mercurial code.
%  Don't say you weren't warned!
$B0J2<$N;X<($K=>$C$F%$%s%9%H!<%k$7$?(BMercurial$B$r!$:G?7$N(BMercurial$B%3!<%I$G(B
\emph{$BCV$-49$($k(B}$B$3$H$,$G$-$k!%!J7Y9p$5$l$J$+$C$?$H$O8@$o$J$$$3$H!K(B

\end{note}
\begin{enumerate}
%\item Clone the Python \texttt{inotify} binding repository.  Build and
%  install it.
\item Python \texttt{inotify}$B%P%$%s%G%#%s%0$N%j%]%8%H%j$r%/%m!<%s$7!$%S(B
      $B%k%I$H%$%s%9%H!<%k$r9T$&!%(B
  \begin{codesample4}
    hg clone http://hg.kublai.com/python/inotify
    cd inotify
    python setup.py build --force
    sudo python setup.py install --skip-build
  \end{codesample4}
%\item Clone the \dirname{crew} Mercurial repository.  Clone the
%  \hgext{inotify} patch repository so that Mercurial Queues will be
%  able to apply patches to your cope of the \dirname{crew} repository.
 \item Merecurial$B$N(B\dirname{crew}$B%j%]%8%H%j$r%/%m!<%s$9(B
      $B$k!%(B\hgext{inotify}$B%Q%C%A%j%]%8%H%j$r%/%m!<%s$7!$(BMercurial Queues
      $B$,(B\dirname{crew}$B%j%]%8%H%j$K%Q%C%A$rEv$F$i$l$k$h$&$K$9$k!%(B
  \begin{codesample4}
    hg clone http://hg.intevation.org/mercurial/crew
    hg clone crew inotify
    hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches
  \end{codesample4}
%\item Make sure that you have the Mercurial Queues extension,
%  \hgext{mq}, enabled.  If you've never used MQ, read
%  section~\ref{sec:mq:start} to get started quickly.

\item Mercurial Queues$B3HD%!J(B\hgext{mq}$B!K$,M-8z$K$J$C$F$$$k$3$H$r3NG'$9(B
      $B$k!%(BMQ$B$r;H$C$?$3$H$,$J$1$l$P!$(B\ref{sec:mq:start}$B$r0lFI$9$k$3$H$r$*(B
      $B$9$9$a$9$k!%(B

%\item Go into the \dirname{inotify} repo, and apply all of the
%  \hgext{inotify} patches using the \hgxopt{mq}{qpush}{-a} option to
%  the \hgxcmd{mq}{qpush} command.
\item \dirname{inotify}$B%j%]%8%H%j$X9T$-!$(B\hgxcmd{mq}{qpush}$B%3%^%s%I$K(B
      \hgxopt{mq}{qpush}{-a}$B%*%W%7%g%s$r;H$C$F(B\hgext{inotify}$B$N%Q%C%A$r$9(B
      $B$Y$FE,MQ$9$k!%(B

  \begin{codesample4}
    cd inotify
    hg qpush -a
  \end{codesample4}
%  If you get an error message from \hgxcmd{mq}{qpush}, you should not
%  continue.  Instead, ask for help.

\hgxcmd{mq}{qpush}$B$G%(%i!<$,5/$-$?>l9g!$@h$X?J$^$:$K=u8@$r5a$a$FM_$7$$!%(B

%\item Build and install the patched version of Mercurial.
\item $B%Q%C%A$rEv$F$?(BMercurial$B$r%S%k%I$7$F%$%s%9%H!<%k$9$k!%(B
  \begin{codesample4}
    python setup.py build --force
    sudo python setup.py install --skip-build
  \end{codesample4}
\end{enumerate}
%Once you've build a suitably patched version of Mercurial, all you
%need to do to enable the \hgext{inotify} extension is add an entry to
%your \hgrc.

$BE,@Z$J%Q%C%A$NEv$C$?(BMercurial$B$r%S%k%I$9$l$P!$8e$O(B\hgext{inotify}$B3HD%$rMx(B
$BMQ$9$k$h$&$K(B\hgrc $B$r@_Dj$9$k$@$1$G$"$k!%(B

\begin{codesample2}
  [extensions]
  inotify =
\end{codesample2}
%When the \hgext{inotify} extension is enabled, Mercurial will
%automatically and transparently start the status daemon the first time
%you run a command that needs status in a repository.  It runs one
%status daemon per repository.

\hgext{inotify}$B$,M-8z$K$J$C$F$$$k$H!$(BMercurial$B$O%j%]%8%H%jFb$G%3%^%s%I$,(B
$B:G=i$K<B9T$5$l$?;~$K<+F0E*$+$DF)2aE*$K%9%F!<%?%9%G!<%b%s$r5/F0$9$k!%%j%](B
$B%8%H%j(B1$B$D$4$H$K(B1$B$D$N%9%F!<%?%9%G!<%b%s$,5/F0$5$l$k!%(B

%The status daemon is started silently, and runs in the background.  If
%you look at a list of running processes after you've enabled the
%\hgext{inotify} extension and run a few commands in different
%repositories, you'll thus see a few \texttt{hg} processes sitting
%around, waiting for updates from the kernel and queries from
%Mercurial.

$B%9%F!<%?%9%G!<%b%s$O2?$b=PNO$r9T$o$:!$%P%C%/%0%i%&%s%I$GF0:n$9(B
$B$k!%(B\hgext{inotify}$B3HD%$rM-8z$K$7$?8e$GJL$N%j%]%8%H%jFb$G$$$/$D$+%3%^%s%I(B
$B$r<B9T$7!$<B9TCf$N%W%m%;%9$N%j%9%H$r8+$k$H!$$$$/$D$+$N(B\texttt{hg}$B%W%m%;%9(B
$B$,%+!<%M%k$+$i$N%"%C%W%G!<%H$H(BMercurial$B$+$i$NLd$$9g$o$;$rBT$C$F$$$k$N$,(B
$B8+$i$l$k$@$m$&!%(B

%The first time you run a Mercurial command in a repository when you
%have the \hgext{inotify} extension enabled, it will run with about the
%same performance as a normal Mercurial command.  This is because the
%status daemon needs to perform a normal status scan so that it has a
%baseline against which to apply later updates from the kernel.
%However, \emph{every} subsequent command that does any kind of status
%check should be noticeably faster on repositories of even fairly
%modest size.  Better yet, the bigger your repository is, the greater a
%performance advantage you'll see.  The \hgext{inotify} daemon makes
%status operations almost instantaneous on repositories of all sizes!

\hgext{inotify}$B3HD%$rM-8z$K$7!$%j%]%8%H%jFb$G(BMercurial$B%3%^%s%I$r:G=i$K<B(B
$B9T$7$?;~$ODL>o$N(BMercurial$B%3%^%s%I$HF1MM$N@-G=$GF0$/!%%9%F!<%?%9%G!<%b%s$O(B
$BDL>o$N%9%F!<%?%9%9%-%c%s$r9T$$!$%+!<%M%k$+$i99?7$NDLCN$r<u$1$k$?$a$N%Y!<(B
$B%9%i%$%s$r<hF@$7$F$*$+$J$1$l$P$J$i$J$$$+$i$G$"$k!%0lJ}$G!$8eB3$N%9%F!<%?(B
$B%9%A%'%C%/$r9T$&(B\emph{$B$9$Y$F$N(B}$B%3%^%s%I$O!$$=$3$=$3$NBg$-$5$N%j%]%8%H%j$K(B
$BBP$7$F$bL\$K8+$($F9bB.2=$5$l$k!%$5$i$K%j%]%8%H%j$,Bg$-$/$J$k$KO"$l$F@-G=(B
$B$N8~>e$OBg$-$/$J$k!%(B\hgext{inotify}$B%G!<%b%s$O!$%j%]%8%H%j$N%5%$%:$K4X$o$i(B
$B$:!$%9%F!<%?%9<hF@$r$[$\=V;~$K9T$&$3$H$,$G$-$k!%(B

%If you like, you can manually start a status daemon using the
%\hgxcmd{inotify}{inserve} command.  This gives you slightly finer
%control over how the daemon ought to run.  This command will of course
%only be available when the \hgext{inotify} extension is enabled.

\hgxcmd{inotify}{inserve}$B%3%^%s%I$r;H$C$F%9%F!<%?%9%G!<%b%s$r<jF0$G<B9T$9(B
$B$k$3$H$b2DG=$G$"$k!%$3$l$K$h$j!$%G!<%b%s$,$I$N$h$&$KF0:n$9$k$N$+$r$d$d:Y(B
$B$+$/%3%s%H%m!<%k$9$k$3$H$,$G$-$k!%EvA3$J$,$i!$$3$N%3%^%s%I$O(B
\hgext{inotify}$B$,M-8z$N>l9g$N$_MxMQ2DG=$G$"$k!%(B


%When you're using the \hgext{inotify} extension, you should notice
%\emph{no difference at all} in Mercurial's behaviour, with the sole
%exception of status-related commands running a whole lot faster than
%they used to.  You should specifically expect that commands will not
%print different output; neither should they give different results.
%If either of these situations occurs, please report a bug.

\hgext{inotify}$B3HD%$r;H$C$F$$$k;~$O(BMercurial$B$N(B\emph{$BA4$/JQ2=$J$7(B}$B$H$$$&F0(B
$B:n$K5$IU$/$@$m$&!%%9%F!<%?%9$K4X78$9$k%3%^%s%I$O0JA0$h$j$:$C$H9bB.$K$J$C(B
$B$F$$$k$H$$$&0l$D$NNc30$r=|$$$F%3%^%s%I$OFCJL$N=PNO$b7k2L$b=PNO$7$J$$$3$H(B
$B$KN10U$5$l$?$$!%2?$+FCJL$J$3$H$,5/$-$?$i%P%0$H$7$FJs9p$7$FM_$7$$!%(B

%\section{Flexible diff support with the \hgext{extdiff} extension}
\section{\hgext{extdiff}$B3HD%$K$h$k=@Fp$J(Bdiff$B%5%]!<%H(B}
\label{sec:hgext:extdiff}

%Mercurial's built-in \hgcmd{diff} command outputs plaintext unified
%diffs.
%\interaction{extdiff.diff}
%If you would like to use an external tool to display modifications,
%you'll want to use the \hgext{extdiff} extension.  This will let you
%use, for example, a graphical diff tool.

Mercurial$B$N%S%k%H%$%s%3%^%s%I(B\hgcmd{diff}$B$O(Bunified$B7A<0$N(Bdiff$B$r%W%l!<%s%F(B
$B%-%9%H$G=PNO$9$k!%(B
\interaction{extdiff.diff}
$BJQ99$r30It%D!<%k$r;H$C$FI=<($7$?$$$J$i$P!$(B\hgext{extdiff}$B3HD%$r;H$&$HNI(B
$B$$!%$3$N3HD%$ONc$($P%0%i%U%#%+%k$J(Bdiff$BI=<($r9T$&!%(B

%The \hgext{extdiff} extension is bundled with Mercurial, so it's easy
%to set up.  In the \rcsection{extensions} section of your \hgrc,
%simply add a one-line entry to enable the extension.

\hgext{extdiff}$B3HD%$O(BMercurial$B$KF1:-$5$l$F$$$k$N$G!$%;%C%H%"%C%W$OMF0W$G(B
$B$"$k!%(B\hgrc $B$NCf$N(B\rcsection{extensions}$B%;%/%7%g%s$K(B1$B9T$N@_Dj$rDI2C$9$k(B
$B$@$1$GNI$$!%(B
\begin{codesample2}
  [extensions]
  extdiff =
\end{codesample2}

%This introduces a command named \hgxcmd{extdiff}{extdiff}, which by
%default uses your system's \command{diff} command to generate a
%unified diff in the same form as the built-in \hgcmd{diff} command.
%\interaction{extdiff.extdiff}
%The result won't be exactly the same as with the built-in \hgcmd{diff}
%variations, because the output of \command{diff} varies from one
%system to another, even when passed the same options.

$B$3$N3HD%$G(B\hgxcmd{extdiff}{extdiff}$B$H$$$&%3%^%s%I$,;H$($k$h$&$K$J$k!%(B
$B$3$N%3%^%s%I$O%7%9%F%`$N(B\command{diff}$B$r;H$C$FAH$_9~$_$N(B\hgcmd{diff}$B%3%^(B
$B%s%I$HF1MM$N(Bunified$B7A<0$N(Bdiff$B$r@8@.$9$k!%(B
\interaction{extdiff.extdiff}
$BF@$i$l$k@.2LJ*$OAH$_9~$_$N(B\hgcmd{diff}$B$HA4$/F1$8$K$O$J$i$J$$$@$m$&!%M}M3(B
$B$O(B\command{diff}$B%3%^%s%I$O%7%9%F%`Kh$K0[$J$j!$F1$8%*%W%7%g%s$rEO$7$F$bF1(B
$B$8=PNO$r$9$k$H$O8B$i$J$$$+$i$@!%(B

%As the ``\texttt{making snapshot}'' lines of output above imply, the
%\hgxcmd{extdiff}{extdiff} command works by creating two snapshots of
%your source tree.  The first snapshot is of the source revision; the
%second, of the target revision or working directory.  The
%\hgxcmd{extdiff}{extdiff} command generates these snapshots in a
%temporary directory, passes the name of each directory to an external
%diff viewer, then deletes the temporary directory.  For efficiency, it
%only snapshots the directories and files that have changed between the
%two revisions.

$B=PNO$N(B``\texttt{making snapshot}''$B9T$,<gD%$9$k$h$&(B
$B$K!$(B\hgxcmd{extdiff}{extdiff}$B%3%^%s%I$O%=!<%9%D%j!<$N(B2$B$D$N%9%J%C%W%7%g%C(B
$B%H$r:n$k$h$&$KF/$/!%(B 1$B$DL\$N%9%J%C%W%7%g%C%H$O%=!<%9%j%S%8%g%s$G!$(B2$B$DL\$O(B
$B%o!<%-%s%0%G%#%l%/%H%j$N%?!<%2%C%H%j%S%8%g%s$G$"$k!%(B
\hgxcmd{extdiff}{extdiff}$B%3%^%s%I$O$3$l$i$N%9%J%C%W%7%g%C%H$r%F%s%]%i%j%G%#(B
$B%l%/%H%j$K:n$j!$30It(Bdiff$B%S%e!<%"$K$=$l$>$l$N%G%#%l%/%H%j$NL>A0$rEO$9!%$=(B
$B$N8e!$%F%s%]%i%j%G%#%l%/%H%j$r>C5n$9$k!%8zN($N$?$a$K(B2$B$D$N%j%S%8%g%s4V$GJQ(B
$B99$N$"$C$?%G%#%l%/%H%j$H%U%!%$%k$N%9%J%C%W%7%g%C%H$@$1$r<h$k!%(B

%Snapshot directory names have the same base name as your repository.
%If your repository path is \dirname{/quux/bar/foo}, then \dirname{foo}
%will be the name of each snapshot directory.  Each snapshot directory
%name has its changeset ID appended, if appropriate.  If a snapshot is
%of revision \texttt{a631aca1083f}, the directory will be named
%\dirname{foo.a631aca1083f}.  A snapshot of the working directory won't
%have a changeset ID appended, so it would just be \dirname{foo} in

%this example.  To see what this looks like in practice, look again at
%the \hgxcmd{extdiff}{extdiff} example above.  Notice that the diff has
%the snapshot directory names embedded in its header.

$B%9%J%C%W%7%g%C%H%G%#%l%/%H%j$NL>A0$O%j%]%8%H%j$HF1$8%Y!<%9%M!<%`$r;}$D!%(B
$B%j%]%8%H%j$N%Q%9$,(B\dirname{/quux/bar/foo}$B$J$i$P!$(B\dirname{foo}$B$,%9%J%C%W(B
$B%7%g%C%H%G%#%l%/%H%j$N%Y!<%9%M!<%`$K$J$j!$$3$3$K%A%'%s%8%;%C%H(BID$B$,IU2C$5(B
$B$l$k!%%9%J%C%W%7%g%C%H$N%j%S%8%g%s$,(B\texttt{a631aca1083f}$B$J$i!$%G%#%l%/%H(B
$B%j$O(B\dirname{foo.a631aca1083f}$B$H$J$k!%%o!<%-%s%0%G%#%l%/%H%j$N%9%J%C%W(B
$B%7%g%C%H$O%A%'%s%8%;%C%H(BID$B$r;}$?$J$$$N$G!$$3$NNc$G$O(B\dirname{foo}$B$H$$$&L>(B
$BA0$K$J$k!%<B:]$NF0:n$r8+$k$K$O!$>e5-$N(B\hgxcmd{extdiff}{extdiff}$B$r;2>H$5$l(B
$B$?$$!%(B diff$B$N%X%C%@$K$O%9%J%C%W%7%g%C%H%G%#%l%/%H%jL>$,Kd$a9~$^$l$F$$$kE@(B
$B$KN10U$5$l$?$$!%(B

%The \hgxcmd{extdiff}{extdiff} command accepts two important options.
%The \hgxopt{extdiff}{extdiff}{-p} option lets you choose a program to
%view differences with, instead of \command{diff}.  With the
%\hgxopt{extdiff}{extdiff}{-o} option, you can change the options that
%\hgxcmd{extdiff}{extdiff} passes to the program (by default, these
%options are ``\texttt{-Npru}'', which only make sense if you're
%running \command{diff}).  In other respects, the
%\hgxcmd{extdiff}{extdiff} command acts similarly to the built-in
%\hgcmd{diff} command: you use the same option names, syntax, and
%arguments to specify the revisions you want, the files you want, and
%so on.

\hgxcmd{extdiff}{extdiff}$B%3%^%s%I$K$O=EMW$J%*%W%7%g%s$,(B2$B$D$"$k!%(B
\hgxopt{extdiff}{extdiff}{-p}$B%*%W%7%g%s$G:9J,$r<h$k%3%^%s%I$H$7$F(B
\command{diff}$B0J30$N%3%^%s%I$r;XDj$G$-$k!%(B \hgxopt{extdiff}{extdiff}{-o}
$B%*%W%7%g%s$G(B\hgxcmd{extdiff}{extdiff}$B$,30It%W%m%0%i%`$KEO$9%*%W%7%g%s$rJQ(B
$B99$9$k$3$H$,$G$-$k!%!J%G%U%)%k%H$G$O(B``\texttt{-Npru}''$B$,EO$5$l$k!%$3$l$O(B
\command{diff}$B$,5/F0$5$l$k;~$N$_0UL#$r;}$D!%!K$=$NB>$NE@$G$O(B
\hgxcmd{extdiff}{extdiff}$B%3%^%s%I$O%S%k%H%$%s$N(B\hgcmd{diff}$B$HF1MM$NF0:n$r(B
$B$9$k!%$9$J$o$A!$F1$8%*%W%7%g%sL>!$J8K!!$%j%S%8%g%s$d%U%!%$%k$r;XDj$9$k=q(B
$B<0$J$I$r;}$D!%(B

%As an example, here's how to run the normal system \command{diff}
%command, getting it to generate context diffs (using the

%\cmdopt{diff}{-c} option) instead of unified diffs, and five lines of
%context instead of the default three (passing \texttt{5} as the
%argument to the \cmdopt{diff}{-C} option).
%\interaction{extdiff.extdiff-ctx}

$B$3$3$G%7%9%F%`$NDL>o%3%^%s%I$N(B\command{diff}$B$r!$(Bunified diff$B7A<0$G$O$J(B
$B$/!$!J(B\cmdopt{diff}{-c}$B%*%W%7%g%s$r;H$C$F!K(Bcontext diff$B7A<0$r=PNO$5$;$kNc(B
$B$r8+$F$_$h$&!%(Bcontext diff$B$K4^$^$l$k%3%s%F%-%9%H$N9T?t$b%G%U%)%k%H$N(B3$B9T$G(B
$B$O$J$/!$!J(B\cmdopt{diff}{-C}$B$X(B\texttt{5}$B%*%W%7%g%s$rEO$7$F!K(B5$B9T=PNO$5$;$k(B
$B$h$&$K$9$k!%(B

%Launching a visual diff tool is just as easy.  Here's how to launch
%the \command{kdiff3} viewer.
$B%S%8%e%"%k(Bdiff$B%D!<%k$N5/F0$O$?$d$9$$!%$3$3$G$O(B\command{kdiff3}$B%S%e!<%"$N(B
$B5/F0J}K!$r<($9!%(B
\begin{codesample2}
  hg extdiff -p kdiff3 -o ''
\end{codesample2}

%If your diff viewing command can't deal with directories, you can
%easily work around this with a little scripting.  For an example of
%such scripting in action with the \hgext{mq} extension and the
%\command{interdiff} command, see
%section~\ref{mq-collab:tips:interdiff}.

$BMxMQ$7$h$&$H$9$k(Bdiff$B%S%e!<%3%^%s%I$,%G%#%l%/%H%j$r07$($J$$>l9g!$$o$:$+$J(B
$B%9%/%j%W%H$r=q$/$3$H$G4JC1$K$3$NLdBj$r2sHr$9$k$3$H$,$G$-$k!%<B:]$K;H$o$l(B
$B$F$$$k%9%/%j%W%HNc$H$7$F$O!$(B\hgext{mq}$B3HD%$H(B\command{interdiff}$B%3%^%s%I$N(B
$B4V$N$b$N$,$"$k!%$3$l$K$D$$$F$O(B\ref{mq-collab:tips:interdiff}$B$r;2>H$5$l$?(B
$B$$!%(B

%\subsection{Defining command aliases}
\subsection{$B%3%^%s%I$N%(%$%j%"%9$r:n$k(B}

It can be cumbersome to remember the options to both the
\hgxcmd{extdiff}{extdiff} command and the diff viewer you want to use,
so the \hgext{extdiff} extension lets you define \emph{new} commands
that will invoke your diff viewer with exactly the right options.

All you need to do is edit your \hgrc, and add a section named
\rcsection{extdiff}.  Inside this section, you can define multiple
commands.  Here's how to add a \texttt{kdiff3} command.  Once you've
defined this, you can type ``\texttt{hg kdiff3}'' and the
\hgext{extdiff} extension will run \command{kdiff3} for you.
\begin{codesample2}
  [extdiff]
  cmd.kdiff3 =
\end{codesample2}
If you leave the right hand side of the definition empty, as above,
the \hgext{extdiff} extension uses the name of the command you defined
as the name of the external program to run.  But these names don't
have to be the same.  Here, we define a command named ``\texttt{hg
  wibble}'', which runs \command{kdiff3}.
\begin{codesample2}
  [extdiff]
  cmd.wibble = kdiff3
\end{codesample2}

You can also specify the default options that you want to invoke your
diff viewing program with.  The prefix to use is ``\texttt{opts.}'',
followed by the name of the command to which the options apply.  This
example defines a ``\texttt{hg vimdiff}'' command that runs the
\command{vim} editor's \texttt{DirDiff} extension.
\begin{codesample2}
  [extdiff]
  cmd.vimdiff = vim
  opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'
\end{codesample2}

%\section{Cherrypicking changes with the \hgext{transplant} extension}
\section{\hgext{transplant}$B3HD%$rMQ$$$?%A%'%j!<%T%C%-%s%099?7(B}
\label{sec:hgext:transplant}

%Need to have a long chat with Brendan about this.
$B!J(BBrendan$B$H$h$/OC$r$9$kI,MW$,$"$k!%!K(B

%\section{Send changes via email with the \hgext{patchbomb} extension}
\section{\hgext{patchbomb}$B3HD%$K$h$C$FJQ99$r%a!<%k$9$k(B}
\label{sec:hgext:patchbomb}

Many projects have a culture of ``change review'', in which people
send their modifications to a mailing list for others to read and
comment on before they commit the final version to a shared
repository.  Some projects have people who act as gatekeepers; they
apply changes from other people to a repository to which those others
don't have access.

Mercurial makes it easy to send changes over email for review or
application, via its \hgext{patchbomb} extension.  The extension is so
namd because changes are formatted as patches, and it's usual to send
one changeset per email message.  Sending a long series of changes by
email is thus much like ``bombing'' the recipient's inbox, hence
``patchbomb''.

As usual, the basic configuration of the \hgext{patchbomb} extension
takes just one or two lines in your \hgrc.
\begin{codesample2}
  [extensions]
  patchbomb =
\end{codesample2}
Once you've enabled the extension, you will have a new command
available, named \hgxcmd{patchbomb}{email}.

The safest and best way to invoke the \hgxcmd{patchbomb}{email}
command is to \emph{always} run it first with the
\hgxopt{patchbomb}{email}{-n} option.  This will show you what the
command \emph{would} send, without actually sending anything.  Once
you've had a quick glance over the changes and verified that you are
sending the right ones, you can rerun the same command, with the
\hgxopt{patchbomb}{email}{-n} option removed.

The \hgxcmd{patchbomb}{email} command accepts the same kind of
revision syntax as every other Mercurial command.  For example, this
command will send every revision between 7 and \texttt{tip},
inclusive.
\begin{codesample2}
  hg email -n 7:tip
\end{codesample2}
You can also specify a \emph{repository} to compare with.  If you
provide a repository but no revisions, the \hgxcmd{patchbomb}{email}
command will send all revisions in the local repository that are not
present in the remote repository.  If you additionally specify
revisions or a branch name (the latter using the
\hgxopt{patchbomb}{email}{-b} option), this will constrain the
revisions sent.

It's perfectly safe to run the \hgxcmd{patchbomb}{email} command
without the names of the people you want to send to: if you do this,
it will just prompt you for those values interactively.  (If you're
using a Linux or Unix-like system, you should have enhanced
\texttt{readline}-style editing capabilities when entering those
headers, too, which is useful.)

When you are sending just one revision, the \hgxcmd{patchbomb}{email}
command will by default use the first line of the changeset
description as the subject of the single email message it sends.

If you send multiple revisions, the \hgxcmd{patchbomb}{email} command
will usually send one message per changeset.  It will preface the
series with an introductory message, in which you should describe the
purpose of the series of changes you're sending.

%\subsection{Changing the behaviour of patchbombs}
\subsection{patchbombs$B$N5sF0$rJQ99$9$k(B}

Not every project has exactly the same conventions for sending changes
in email; the \hgext{patchbomb} extension tries to accommodate a
number of variations through command line options.
\begin{itemize}
\item You can write a subject for the introductory message on the
  command line using the \hgxopt{patchbomb}{email}{-s} option.  This
  takes one argument, the text of the subject to use.
\item To change the email address from which the messages originate,
  use the \hgxopt{patchbomb}{email}{-f} option.  This takes one
  argument, the email address to use.
\item The default behaviour is to send unified diffs (see
  section~\ref{sec:mq:patch} for a description of the format), one per
  message.  You can send a binary bundle instead with the
  \hgxopt{patchbomb}{email}{-b} option.  
\item Unified diffs are normally prefaced with a metadata header.  You
  can omit this, and send unadorned diffs, with the
  \hgxopt{patchbomb}{email}{--plain} option.
\item Diffs are normally sent ``inline'', in the same body part as the
  description of a patch.  This makes it easiest for the largest
  number of readers to quote and respond to parts of a diff, as some
  mail clients will only quote the first MIME body part in a message.
  If you'd prefer to send the description and the diff in separate
  body parts, use the \hgxopt{patchbomb}{email}{-a} option.
\item Instead of sending mail messages, you can write them to an
  \texttt{mbox}-format mail folder using the
  \hgxopt{patchbomb}{email}{-m} option.  That option takes one
  argument, the name of the file to write to.
\item If you would like to add a \command{diffstat}-format summary to
  each patch, and one to the introductory message, use the
  \hgxopt{patchbomb}{email}{-d} option.  The \command{diffstat}
  command displays a table containing the name of each file patched,
  the number of lines affected, and a histogram showing how much each
  file is modified.  This gives readers a qualitative glance at how
  complex a patch is.
\end{itemize}

%%% Local Variables:
%%% mode: yatex
%%% TeX-master: "00book"
%%% End: