%\chapter{Behind the scenes}
\chapter{舞台裏}
\label{chap:concepts}

%Unlike many revision control systems, the concepts upon which
%Mercurial is built are simple enough that it's easy to understand how
%the software really works.  Knowing this certainly isn't necessary,
%but I find it useful to have a ``mental model'' of what's going on.

多くのリビジョンコントロールシステムと違って， Mercurialの動作の基本となっ
ているコンセプトを理解することは容易い．
これを理解することは必ずしも必要ではないが，筆者は，何が起きているのかに
ついてモデルを意識していることは有用であると考えている．

%This understanding gives me confidence that Mercurial has been
%carefully designed to be both \emph{safe} and \emph{efficient}.  And
%just as importantly, if it's easy for me to retain a good idea of what
%the software is doing when I perform a revision control task, I'm less
%likely to be surprised by its behaviour.

このことを理解した後で，筆者はMercurialが\emph{安全}と\emph{効率}を実現す
るように注意深く設計されていると確信するに至った．
また，重要な点として，リビジョンコントロールの操作を行う際にソフトウェア
が何をするのかを記憶に留めておくことによって，不意の挙動で驚くことが少な
くなった．

%In this chapter, we'll initially cover the core concepts behind
%Mercurial's design, then continue to discuss some of the interesting
%details of its implementation.

この章ではまずMercurialの設計のコアコンセプトをカバーする．そして実装上の
いくつかの興味深い点の詳細について議論する．

%\section{Mercurial's historical record}
\section{Mercurialの履歴記録}

%\subsection{Tracking the history of a single file}
\subsection{ファイル履歴の追跡}

%When Mercurial tracks modifications to a file, it stores the history
%of that file in a metadata object called a \emph{filelog}.  Each entry
%in the filelog contains enough information to reconstruct one revision
%of the file that is being tracked.  Filelogs are stored as files in
%the \sdirname{.hg/store/data} directory.  A filelog contains two kinds
%of information: revision data, and an index to help Mercurial to find
%a revision efficiently.

Mercurialはファイルへの変更を追跡する時，ファイルの履歴を\emph{filelog}と
呼ばれるメタデータオブジェクトに格納する．ファイルログ内の各々のエントリ
は，追跡対象のファイルのリビジョンを再建するのに十分な情報を持つ．ファイ
ルログは\sdirname{.hg/store/data}ディレクトリにファイルとして保存される．
ファイルログはリビジョンデータとMercurialがリビジョンを効率的に見つけられ
るようにするためのインデックスの2種類の情報を持つ．

%A file that is large, or has a lot of history, has its filelog stored
%in separate data (``\texttt{.d}'' suffix) and index (``\texttt{.i}''
%suffix) files.  For small files without much history, the revision
%data and index are combined in a single ``\texttt{.i}'' file.  The
%correspondence between a file in the working directory and the filelog
%that tracks its history in the repository is illustrated in
%figure~\ref{fig:concepts:filelog}.

サイズの大きなファイルや，膨大な履歴を持つファイルは，データが
(``\texttt{.d}'' suffix) およびインデックス (``\texttt{.i}'' suffix)のファ
イルに分割されたfilelogを持つ．サイズが小さく，履歴の大きくないファイルは
リビジョンデータとインデックスが1つの``\texttt{.i}''ファイルに結合されて
いる．ワーキングディレクトリ内のファイルとリポジトリ内の履歴を追跡する
filelogとの対応を図~\ref{fig:concepts:filelog}に示す．

\begin{figure}[ht]
  \centering
%  \grafix{filelog}
  \includegraphics{filelog}
%  \caption{Relationships between files in working directory and
%  filelogs in repository}
  \caption{ワーキングディレクトリ内のファイルとリポジトリのファイルログ
 の関係}
  \label{fig:concepts:filelog}
\end{figure}

%\subsection{Managing tracked files}
\subsection{追跡されているファイルの管理}

%Mercurial uses a structure called a \emph{manifest} to collect
%together information about the files that it tracks.  Each entry in
%the manifest contains information about the files present in a single
%changeset.  An entry records which files are present in the changeset,
%the revision of each file, and a few other pieces of file metadata.

Mercurialは\emph{マニフェスト}と呼ばれる構造を用いて，追跡すべきファイル
の情報を集めている．マニフェスト内の各々のエントリは，単一のチェンジセッ
ト内に存在するファイルの情報を持っている．エントリはどのファイルがチェン
ジセットに存在しているか，それらのリビジョンが何であるのかという情報と，
いくつかの他のファイルメタデータを記録している．

%\subsection{Recording changeset information}
\subsection{チェンジセット情報の記録}

%The \emph{changelog} contains information about each changeset.  Each
%revision records who committed a change, the changeset comment, other
%pieces of changeset-related information, and the revision of the
%manifest to use.

\emph{changelog}は各々のチェンジセットの情報を持つ．各々のリビジョン記録
は，誰が変更をコミットしたのか，チェンジセットのコメント，変更に関連した
他の情報，使用されるマニフェストのリビジョンを持つ．

%\subsection{Relationships between revisions}
\subsection{リビジョン間の関係}

%Within a changelog, a manifest, or a filelog, each revision stores a
%pointer to its immediate parent (or to its two parents, if it's a
%merge revision).  As I mentioned above, there are also relationships
%between revisions \emph{across} these structures, and they are
%hierarchical in nature.

チェンジログ，マニフェスト，ファイルログ内で，各々のリビジョンは直接の親
（あるいはマージの場合はその両親）へのポインタを持つ．
すでに述べたように，この構造に現れるリビジョンの間には関係があり，本質
的に階層的である．

%For every changeset in a repository, there is exactly one revision
%stored in the changelog.  Each revision of the changelog contains a
%pointer to a single revision of the manifest.  A revision of the
%manifest stores a pointer to a single revision of each filelog tracked
%when that changeset was created.  These relationships are illustrated
%in figure~\ref{fig:concepts:metadata}.

リポジトリにあるすべてのチェンジセットは，チェンジログ内で正確に1つのリビ
ジョンを持つ．チェンジログの各々のリビジョンは，マニフェストの単一のバー
ジョンへのポインタを持つ．マニフェストの各々のリビジョンは，チェンジセッ
トが生成された時のファイルログの各々の単一リビジョンへのポインタを持つ．
この関係を図~\ref{fig:concepts:metadata}に示す．

\begin{figure}[ht]
  \centering
  \includegraphics{metadata}
%  \caption{Metadata relationships}
  \caption{メタデータの関係}
  \label{fig:concepts:metadata}
\end{figure}

%As the illustration shows, there is \emph{not} a ``one to one''
%relationship between revisions in the changelog, manifest, or filelog.
%If the manifest hasn't changed between two changesets, the changelog
%entries for those changesets will point to the same revision of the
%manifest.  If a file that Mercurial tracks hasn't changed between two
%changesets, the entry for that file in the two revisions of the
%manifest will point to the same revision of its filelog.

イラストで示されているように，リビジョンとチェンジログ，マニフェストまた
はファイルログの間には1対１の関係はない．マニフェストが2つのチェンジセッ
トの間で変化しなかった場合は，チェンジログ内でこれらのチェンジセットを表
すエントリは同じバージョンのマニフェストを示す．Mercurialが追跡するファイ
ルが，2つのチェンジセット間で変化しなかった場合は， 2つのマニフェストのリ
ビジョンで，そのファイルを示すエントリはファイルログの同じリビジョンを示
す．

%\section{Safe, efficient storage}
\section{安全かつ効率的なストレージ}

%The underpinnings of changelogs, manifests, and filelogs are provided
%by a single structure called the \emph{revlog}.

チェンジログ，マニフェストおよびファイルログの土台に使われているは共通の
\emph{revlog}という構造体である．

%\subsection{Efficient storage}
\subsection{効率的なストレージ}

%The revlog provides efficient storage of revisions using a
%\emph{delta} mechanism.  Instead of storing a complete copy of a file
%for each revision, it stores the changes needed to transform an older
%revision into the new revision.  For many kinds of file data, these
%deltas are typically a fraction of a percent of the size of a full
%copy of a file.

revlogは\emph{delta}機構を使ってリビジョンの効率的な記憶を提供する．ファ
イルの各々のバージョンの完全なコピーを保存するのではなく，古いリビジョン
を新しいバージョンへ変換するのに必要な変更を保存する．多くのファイルデー
タに対して， deltaは典型的にはファイルのフルコピーの1パーセント未満でああ
る．

%Some obsolete revision control systems can only work with deltas of
%text files.  They must either store binary files as complete snapshots
%or encoded into a text representation, both of which are wasteful
%approaches.  Mercurial can efficiently handle deltas of files with
%arbitrary binary contents; it doesn't need to treat text as special.

古いリビジョンコントロールシステムのいくつかはテキストファイルのdeltaに対
してしか機能しない．それらのシステムではバイナリファイルは完全なスナップ
ショットか，テキスト表現にエンコードされた形式である必要がある．これらは
共に無駄の多いアプローチである． Mercurialは任意のバイナリファイルについ
て，deltaを効率的に扱うことができ，テキストを特別扱いする必要がない．

%\subsection{Safe operation}
\subsection{安全な動作}
\label{sec:concepts:txn}

%Mercurial only ever \emph{appends} data to the end of a revlog file.
%It never modifies a section of a file after it has written it.  This
%is both more robust and efficient than schemes that need to modify or
%rewrite data.

Mercurialはrevlogファイルの末尾にデータの\emph{追加}のみを行う．一度書き
込まれた部分は後になって変更されることはない．これはデータの変更や再書き
込みを行う方法よりも頑強かつ効率的である．

%In addition, Mercurial treats every write as part of a
%\emph{transaction} that can span a number of files.  A transaction is
%\emph{atomic}: either the entire transaction succeeds and its effects
%are all visible to readers in one go, or the whole thing is undone.
%This guarantee of atomicity means that if you're running two copies of
%Mercurial, where one is reading data and one is writing it, the reader
%will never see a partially written result that might confuse it.

加えて，Mercurialはあらゆる書き込みを複数のファイルへの\emph{トランザクショ
ン}の一部と見なす．トランザクション全体が成功し，読み出し側に一度に結果が
見える場合も，そうでない場合もトランザクションは\emph{アトミック}である．
このアトミック性の保証は， 2つのMercurialを，片方はデータの読み出し，もう
一方は書き込みで実行している場合，読み出し側には混乱の原因となる部分的な
書き込み結果は見えないことを意味する．

%The fact that Mercurial only appends to files makes it easier to
%provide this transactional guarantee.  The easier it is to do stuff
%like this, the more confident you should be that it's done correctly.

Mercurialはファイルに追記のみをすることで，トランザクションの保証を容易に
している．物事を単純化することによって，処理の正しさを確実にするようにし
ている．

%\subsection{Fast retrieval}
\subsection{高速な取得}

%Mercurial cleverly avoids a pitfall common to all earlier
%revision control systems: the problem of \emph{inefficient retrieval}.
%Most revision control systems store the contents of a revision as an
%incremental series of modifications against a ``snapshot''.  To
%reconstruct a specific revision, you must first read the snapshot, and
%then every one of the revisions between the snapshot and your target
%revision.  The more history that a file accumulates, the more
%revisions you must read, hence the longer it takes to reconstruct a
%particular revision.

Mercurialはこれまでのリビジョンコントロールシステムに共通した落とし穴を
賢明に避けている．問題だったのは\emph{非効率的な取得}であった．
大抵のリビジョンコントロールシステムはリビジョンの内容をスナップショット
への一連の変更の増分として保存している．特定のリビジョンを再現するために
はまずスナップショットを読み込み，しかる後に目的のリビジョンを読む必要が
あった．ファイルへの履歴が増えれば増えるほど読み込まなければならないリビ
ジョンが多くなり，特定のリビジョンを再現するのに時間がかかるようになる．

\begin{figure}[ht]
  \centering
  \includegraphics{snapshot}
%  \caption{Snapshot of a revlog, with incremental deltas}
  \caption{差分を用いたrevlogのスナップショット}
  \label{fig:concepts:snapshot}
\end{figure}

%The innovation that Mercurial applies to this problem is simple but
%effective.  Once the cumulative amount of delta information stored
%since the last snapshot exceeds a fixed threshold, it stores a new
%snapshot (compressed, of course), instead of another delta.  This
%makes it possible to reconstruct \emph{any} revision of a file
%quickly.  This approach works so well that it has since been copied by
%several other revision control systems.

Mercurialではこの問題を単純だが効果的な方法で解決している．前回にスナップ
ショットを作成した時点からの累積的な増分が一定の閾値を越えると，新たな増
分ではなく，新たなスナップショットが保存される（このスナップショットは勿
論圧縮されている）．これによって\emph{いかなる}リビジョンも迅速に再現され
る．このアプローチは以後他のリビジョンコントロールシステムにコピーされる
ほどうまく機能している．

%Figure~\ref{fig:concepts:snapshot} illustrates the idea.  In an entry
%in a revlog's index file, Mercurial stores the range of entries from
%the data file that it must read to reconstruct a particular revision.

図~\ref{fig:concepts:snapshot}に概念を示す．Mercurialはrevlogのインデック
スファイルのエントリに特定のリビジョンを再現するのに必要なデータファイル
内のある範囲のエントリを保存する．

%\subsubsection{Aside: the influence of video compression}
\subsubsection{その他: ビデオ圧縮の影響}

%If you're familiar with video compression or have ever watched a TV
%feed through a digital cable or satellite service, you may know that
%most video compression schemes store each frame of video as a delta
%against its predecessor frame.  In addition, these schemes use
%``lossy'' compression techniques to increase the compression ratio, so
%visual errors accumulate over the course of a number of inter-frame
%deltas.

ビデオ圧縮に慣れていたり，デジタルによるケーブルまたは衛星放送に慣れてい
るのなら，大部分のビデオ圧縮の仕組みでは，ビデオの各フレームが，前のフレー
ムとの差分として保存されていることを知っているだろう．加えて，これらの仕
組みは圧縮率を稼ぐために不可逆な圧縮技術を使っており，映像のエラーはフレー
ム間の差分が増えるに従って蓄積していく．

%Because it's possible for a video stream to ``drop out'' occasionally
%due to signal glitches, and to limit the accumulation of artefacts
%introduced by the lossy compression process, video encoders
%periodically insert a complete frame (called a ``key frame'') into the
%video stream; the next delta is generated against that frame.  This
%means that if the video signal gets interrupted, it will resume once
%the next key frame is received.  Also, the accumulation of encoding
%errors restarts anew with each key frame.

ビデオストリームでは，信号の不具合によって時折ドロップアウトが出ることが
あり，また不可逆圧縮による影響の蓄積を抑えるため，ビデオエンコーダは定期
的に（キーフレームと呼ばれる）完全なフレームをストリームに挿入する．次の
差分はこのフレームに対して取られる．これによって，ビデオ信号が途絶えても
次のキーフレームを受信すれば正常に戻ることができる．またエンコードエラー
の蓄積はキーフレームごとに除去される．

%\subsection{Identification and strong integrity}
\subsection{識別と強い一貫性}

%Along with delta or snapshot information, a revlog entry contains a
%cryptographic hash of the data that it represents.  This makes it
%difficult to forge the contents of a revision, and easy to detect
%accidental corruption.

差分やスナップショット情報と共に，revlogエントリはデータの暗号ハッシュ
を持つ．ハッシュにより，リビジョンの内容を偽ることが困難になり，また
事故によって内容が破損した場合，発見が容易になる．

%Hashes provide more than a mere check against corruption; they are
%used as the identifiers for revisions.  The changeset identification
%hashes that you see as an end user are from revisions of the
%changelog.  Although filelogs and the manifest also use hashes,
%Mercurial only uses these behind the scenes.

ハッシュは単に破損をチェックする以上のことを行う．これらはリビジョンの識
別にも用いられる．チェンジセットの識別ハッシュは，エンドユーザからはチェ
ンジログでユーザ名と共に現れる数字として目にすることが多いだろう．
ファイルログとマニフェストでもハッシュは使われているが，Mercurialはこれ
らを背後でのみ用いる．

%Mercurial verifies that hashes are correct when it retrieves file
%revisions and when it pulls changes from another repository.  If it
%encounters an integrity problem, it will complain and stop whatever
%it's doing.

Mercurialはファイルのリビジョン取得時と変更を別のリポジトリからpullする時
にハッシュが正しいことを確認する．一貫性に問題があると，エラーメッセージ
を出力し，動作を停止する．

%In addition to the effect it has on retrieval efficiency, Mercurial's
%use of periodic snapshots makes it more robust against partial data
%corruption.  If a revlog becomes partly corrupted due to a hardware
%error or system bug, it's often possible to reconstruct some or most
%revisions from the uncorrupted sections of the revlog, both before and
%after the corrupted section.  This would not be possible with a
%delta-only storage model.

取得の効率に加えて，Mercurialは周期的にスナップショットを使うことで，部分
的なデータの破損に対して頑強になっている．ハードウェアの問題やシステムの
バグでrevlogが部分的に破損した場合でも，多くの場合，revlogの破損していな
い部分から破損した部分の前後でいくつかのリビジョンや大半のリビジョンを再
建することができる．差分のみを記録するシステムではこれを実現することはで
きない．

%\section{Revision history, branching, and merging}
\section{リビジョン履歴，ブランチ，マージ}

%Every entry in a Mercurial revlog knows the identity of its immediate
%ancestor revision, usually referred to as its \emph{parent}.  In fact,
%a revision contains room for not one parent, but two.  Mercurial uses
%a special hash, called the ``null ID'', to represent the idea ``there
%is no parent here''.  This hash is simply a string of zeroes.

Mercurial revlogのすべてのエントリは，通常\emph{parent}として参照される直
接の祖先のリビジョンを知っている．実際には，リビジョンは1つだけでなく2つ
の親を記録することができる．Mercurialは``null ID''という特別なハッシュを
使って``ここには親になるリビジョンがない''ということを表現する．このハッ
シュは単にゼロを並べた文字列である．

%In figure~\ref{fig:concepts:revlog}, you can see an example of the
%conceptual structure of a revlog.  Filelogs, manifests, and changelogs
%all have this same structure; they differ only in the kind of data
%stored in each delta or snapshot.

revlogの概念的な構造の一例を図~\ref{fig:concepts:revlog}に示す．ファイル
ログ，マニフェストおよびチェンジログはすべて同じ構造を持つ．これらの違い
は，各々の差分やスナップショットに格納するデータの違いだけである．

%The first revision in a revlog (at the bottom of the image) has the
%null ID in both of its parent slots.  For a ``normal'' revision, its
%first parent slot contains the ID of its parent revision, and its
%second contains the null ID, indicating that the revision has only one
%real parent.  Any two revisions that have the same parent ID are
%branches.  A revision that represents a merge between branches has two
%normal revision IDs in its parent slots.

revlogでの最初のリビジョン（図の一番下）はnull IDを両親を示すスロットの
両方に持ち，このリビジョンが実際にはただ一つの親しか持たないことを表して
いる．同じ親のIDを持つ任意の2つのリビジョンはブランチである．
ブランチ間のマージを表すリビジョンは，2つのノーマルリビジョンIDを両親の
スロットに持つ．

\begin{figure}[ht]
  \centering
  \includegraphics{revlog}
  \caption{}
  \label{fig:concepts:revlog}
\end{figure}

%\section{The working directory}
\section{ワーキングディレクトリ}

%In the working directory, Mercurial stores a snapshot of the files
%from the repository as of a particular changeset.

Mercurialはリポジトリのある特定のチェンジセットのファイルスナップショット
をワーキングディレクトリ内に持つ．

%The working directory ``knows'' which changeset it contains.  When you
%update the working directory to contain a particular changeset,
%Mercurial looks up the appropriate revision of the manifest to find
%out which files it was tracking at the time that changeset was
%committed, and which revision of each file was then current.  It then
%recreates a copy of each of those files, with the same contents it had
%when the changeset was committed.

ワーキングディレクトリがどのチェンジセットに更新されているがあるのかは既
知である．ワーキングディレクトリが特定のチェンジセットになるように更新す
る際， Mercurialは適切なリビジョンのマニフェストを検索し，そのチェンジセッ
トがコミットされた時点でどのファイルが追跡されているかを調べ，各々のファ
イルのリビジョンを特定する．そしてチェンジセットがコミットされた時点の内
容をもつファイルのコピーを作成する．

%The \emph{dirstate} contains Mercurial's knowledge of the working
%directory.  This details which changeset the working directory is
%updated to, and all of the files that Mercurial is tracking in the
%working directory.

\emph{dirstate}にはワーキングディレクトリについてMercurialが把握している
情報が格納されている．その内容はワーキングディレクトリがアップデートされ
ているチェンジセットおよびワーキングディレクトリ内でMercurialが追跡してい
る全てのファイルについての詳細である．

%Just as a revision of a revlog has room for two parents, so that it
%can represent either a normal revision (with one parent) or a merge of
%two earlier revisions, the dirstate has slots for two parents.  When
%you use the \hgcmd{update} command, the changeset that you update to
%is stored in the ``first parent'' slot, and the null ID in the second.
%When you \hgcmd{merge} with another changeset, the first parent
%remains unchanged, and the second parent is filled in with the
%changeset you're merging with.  The \hgcmd{parents} command tells you
%what the parents of the dirstate are.

revlogにおけるリビジョンが2つの親の情報を格納する領域を持ち，通常のリビジョ
ン（親は1つ）または2つの親のマージを表現できるのと同様にdirstateも2つの親
のためのスロットを持っている．\hgcmd{update}コマンドを実行すると，アップ
デート先のチェンジセットが1つ目の親のスロットに記録され，null IDが2つ目の
親のスロットに記録される．他のチェンジセットと\hgcmd{merge}を行うと，最初
の親はそのままに，2番目の親はマージするチェンジセットとな
る．\hgcmd{parents}コマンドでdirstateの両親を知ることができる．

%\subsection{What happens when you commit}
\subsection{コミット時に何が起きるのか}

%The dirstate stores parent information for more than just book-keeping
%purposes.  Mercurial uses the parents of the dirstate as \emph{the
%  parents of a new changeset} when you perform a commit.

dirstateは管理目的意外の情報も保存している． Mercurialは，コミットの際に
dirstateの両親を\emph{新たなチェンジセットの両親}として用いる．

\begin{figure}[ht]
  \centering
  \includegraphics{wdir}
%  \caption{The working directory can have two parents}
  \caption{ワーキングディレクトリは2つの親を持ち得る}
  \label{fig:concepts:wdir}
\end{figure}

%Figure~\ref{fig:concepts:wdir} shows the normal state of the working
%directory, where it has a single changeset as parent.  That changeset
%is the \emph{tip}, the newest changeset in the repository that has no
%children.

図~\ref{fig:concepts:wdir}にワーキングディレクトリの通常状態を示す．
リポジトリの最新のチェンジセットは\emph{tip}で，子を一切持たない．

\begin{figure}[ht]
  \centering
  \includegraphics{wdir-after-commit}
%  \caption{The working directory gains new parents after a commit}
  \caption{コミット後，ワーキングディレクトリは新たな両親を持つ}
  \label{fig:concepts:wdir-after-commit}
\end{figure}

%It's useful to think of the working directory as ``the changeset I'm
%about to commit''.  Any files that you tell Mercurial that you've
%added, removed, renamed, or copied will be reflected in that
%changeset, as will modifications to any files that Mercurial is
%already tracking; the new changeset will have the parents of the
%working directory as its parents.

ワーキングディレクトリが``コミットしようとしているチェンジセット''である
と見なすことは役に立つ．追加，削除，リネームまたはコピーしたファイルを
Mercurialに認識させると，すでにMercurialが追跡している任意のファイルへの
変更と同様，すべてチェンジセットに反映される．新たなチェンジセットはワー
キングディレクトリの両親を両親として持つ．

%After a commit, Mercurial will update the parents of the working
%directory, so that the first parent is the ID of the new changeset,
%and the second is the null ID.  This is shown in
%figure~\ref{fig:concepts:wdir-after-commit}.  Mercurial doesn't touch
%any of the files in the working directory when you commit; it just
%modifies the dirstate to note its new parents.

コミット後，Mercurialはワーキングディレクトリの両親を更新し，1つ目の親が
新たなチェンジセットのID，2番目をnull IDにする．これを
図~\ref{fig:concepts:wdir-after-commit}に示す．Mercurialはコミット時にワー
キングディレクトリ内のファイルには一切触れず，dirstateに新たな両親を記録
する．

%\subsection{Creating a new head}
\subsection{新たなヘッドを作る}

%It's perfectly normal to update the working directory to a changeset
%other than the current tip.  For example, you might want to know what
%your project looked like last Tuesday, or you could be looking through
%changesets to see which one introduced a bug.  In cases like this, the
%natural thing to do is update the working directory to the changeset
%you're interested in, and then examine the files in the working
%directory directly to see their contents as they were when you
%committed that changeset.  The effect of this is shown in
%figure~\ref{fig:concepts:wdir-pre-branch}.

ワーキングディレクトリを現在のtip以外のチェンジセットに更新することはいさ
さかもおかしなことではない．例えば，この前の火曜日にプロジェクトがどのよ
うな状態であったか知りたいと思うかもしれないし，チェンジセットのうちのど
れがバグを混入させたか突き止めたいと考えることがあるかもしれない．このよ
うな場合，ワーキングディレクトリを興味のあるチェンジセットに更新し，チェ
ンジセットをコミットした時にそれらがどのようであったかを見るためにワーキ
ングディレクトリ内のファイルを調べるのが自然である．この影響は
図~\ref{fig:concepts:wdir-pre-branch}に示す．

\begin{figure}[ht]
  \centering
  \includegraphics{wdir-pre-branch}
%  \caption{The working directory, updated to an older changeset}
  \caption{古いチェンジセットへと更新されたワーキングディレクトリ}
  \label{fig:concepts:wdir-pre-branch}
\end{figure}

%Having updated the working directory to an older changeset, what
%happens if you make some changes, and then commit?  Mercurial behaves
%in the same way as I outlined above.  The parents of the working
%directory become the parents of the new changeset.  This new changeset
%has no children, so it becomes the new tip.  And the repository now
%contains two changesets that have no children; we call these
%\emph{heads}.  You can see the structure that this creates in
%figure~\ref{fig:concepts:wdir-branch}.

ワーキングディレクトリを古いチェンジセットに更新し，変更を行ってコミット
すると何が起こるだろうか？ Mercurialは前述のように振舞う．ワーキングディ
レクトリの両親は新たなチェンジセットの両親となる．新たなチェンジセットは
子を持たず，従って新たなtipとなる．リポジトリには\emph{heads}と呼ばれる2
つのチェンジセットができる．この時の構造を
図~\ref{fig:concepts:wdir-branch}に示す．

\begin{figure}[ht]
  \centering
  \includegraphics{wdir-branch}
%  \caption{After a commit made while synced to an older changeset}
  \caption{古いチェンジセットに同期中にコミットが行われた場合}
  \label{fig:concepts:wdir-branch}
\end{figure}

%\begin{note}
%  If you're new to Mercurial, you should keep in mind a common
%  ``error'', which is to use the \hgcmd{pull} command without any
%  options.  By default, the \hgcmd{pull} command \emph{does not}
%  update the working directory, so you'll bring new changesets into
%  your repository, but the working directory will stay synced at the
%  same changeset as before the pull.  If you make some changes and
%  commit afterwards, you'll thus create a new head, because your
%  working directory isn't synced to whatever the current tip is.
%
%  I put the word ``error'' in quotes because all that you need to do
%  to rectify this situation is \hgcmd{merge}, then \hgcmd{commit}.  In
%  other words, this almost never has negative consequences; it just
%  surprises people.  I'll discuss other ways to avoid this behaviour,
%  and why Mercurial behaves in this initially surprising way, later
%  on.
%\end{note}

\begin{note}
Mercurialを使い始めたばかりであれば，よくある``エラー''を覚えておくとよ
い．それは\hgcmd{pull}コマンドをオプションなしで実行することである．デフォ
ルトでは\hgcmd{pull}はワーキングディレクトリの更新を\emph{行わない}．その
ため，リポジトリには新しいチェンジセットが到着しているのにワーキングディ
レクトリは前回pullしたチェンジセットのままである．ここでなんらかの変更を
行ってコミットしようとすると，ワーキングディレクトリが現在のtipに同期して
いないため，新たなヘッドを作ることになってしまう．

``エラー''という言葉を引用符で括ったのは，この状態は\hgcmd{merge}と
\hgcmd{commit}だけで解消できるからだ．言い替えると，この状態はほとんどの
場合害をなすものではななく，単にユーザを驚かす程度のものである．この振舞
を避ける別の方法や，なぜMercurialがこのように驚かせるような方法で動作する
のかについては後ほど議論する．
\end{note}

%\subsection{Merging heads}
\subsection{ヘッド間のマージ}

%When you run the \hgcmd{merge} command, Mercurial leaves the first
%parent of the working directory unchanged, and sets the second parent
%to the changeset you're merging with, as shown in
%figure~\ref{fig:concepts:wdir-merge}.

\hgcmd{merge}コマンドを実行した時，Mercurialはワーキングディレクトリの最
初の親を変更せず残し，2番目の親を図~\ref{fig:concepts:wdir-merge}のよう
にマージ先のチェンジセットとする．

\begin{figure}[ht]
  \centering
  \includegraphics{wdir-merge}
%  \caption{Merging two heads}
  \caption{2つのヘッドのマージ}
  \label{fig:concepts:wdir-merge}
\end{figure}

%Mercurial also has to modify the working directory, to merge the files
%managed in the two changesets.  Simplified a little, the merging
%process goes like this, for every file in the manifests of both
%changesets.

Mercurialは2つのチェンジセット内で管理されているファイルをマージするため
にワーキングディレクトリを変更する必要がある．少し単純化すると，マージプ
ロセスは双方のチェンジセットのマニフェスト内にある全てのファイルに対して
次のように行われる．

\begin{itemize}
%\item If neither changeset has modified a file, do nothing with that
%  file.
 \item どちらのチェンジセットでも変更されていないファイルに対しては何も
       行わない．
%\item If one changeset has modified a file, and the other hasn't,
%  create the modified copy of the file in the working directory.
 \item 変更されたファイルが片方のチェンジセットに含まれ，もう一方には含
       まれない場合，ワーキングディレクトリに変更されたコピーが作成され
       る．
%\item If one changeset has removed a file, and the other hasn't (or
%  has also deleted it), delete the file from the working directory.
 \item 一方のチェンジセットで削除されたファイルがあり，もう一方がそのファ
       イルを含まないか，同様に削除されている場合はワーキングディレクト
       リからそのファイルを削除する．
%\item If one changeset has removed a file, but the other has modified
%  the file, ask the user what to do: keep the modified file, or remove
%  it?
 \item 一方のチェンジセットでファイルが削除されており，もう一方ではその
       ファイルが変更されている場合は，変更されたファイルを維持するかファ
       イルを消去するかかユーザに尋ねる．
%\item If both changesets have modified a file, invoke an external
%  merge program to choose the new contents for the merged file.  This
%  may require input from the user.
 \item 両方のチェンジセットでファイルが変更されている場合，マージ後のファ
       イルの内容を選択するために外部のマージプログラムを起動する．これ
       を行うためにはユーザの入力が必要である．
%\item If one changeset has modified a file, and the other has renamed
%  or copied the file, make sure that the changes follow the new name
%  of the file.
 \item 一方のチェンジセットでファイルが変更されており，もう一方ではファ
       イルがリネームまたはコピーされている場合，変更は新しい名前のファ
       イルに取り込まれる．
\end{itemize}

%There are more details---merging has plenty of corner cases---but
%these are the most common choices that are involved in a merge.  As
%you can see, most cases are completely automatic, and indeed most
%merges finish automatically, without requiring your input to resolve
%any conflicts.

詳しく述べればマージにはいろいろな特殊例がある．しかしここでは最も普通の
選択について説明する．これまで見てきたように，大半のケースは完全に自動で
あり，実際に大半のマージは衝突を解決するために入力を求めることなく自動的
に完了する．

%When you're thinking about what happens when you commit after a merge,
%once again the working directory is ``the changeset I'm about to
%commit''.  After the \hgcmd{merge} command completes, the working
%directory has two parents; these will become the parents of the new
%changeset.

マージ後にコミットを行うとき何が起こるかを考える場合はやはりワーキングディ
レクトリを``これからコミットしようとするチェンジセット''と考えるとよい．
\hgcmd{merge}コマンドが完了した後，ワーキングディレクトリは2つの親を持
ち，これらは新たなチェンジセットの両親となる．

%Mercurial lets you perform multiple merges, but you must commit the
%results of each individual merge as you go.  This is necessary because
%Mercurial only tracks two parents for both revisions and the working
%directory.  While it would be technically possible to merge multiple
%changesets at once, the prospect of user confusion and making a
%terrible mess of a merge immediately becomes overwhelming.

Mercurialは複数回のマージを促す．ここでそれぞれのマージの結果を自分自身で
コミットしなければならない．これはMercurialがリビジョンとワーキングディレ
クトリの双方について2つの親のみを追跡することによる．複数のチェンジセット
を一度にマージすることは技術的には可能だが，マージによる混乱を引き起こ
し，収拾がつかなくなる見込みが大きい．

%\section{Other interesting design features}
\section{設計の他の興味深い点}

%In the sections above, I've tried to highlight some of the most
%important aspects of Mercurial's design, to illustrate that it pays
%careful attention to reliability and performance.  However, the
%attention to detail doesn't stop there.  There are a number of other
%aspects of Mercurial's construction that I personally find
%interesting.  I'll detail a few of them here, separate from the ``big
%ticket'' items above, so that if you're interested, you can gain a
%better idea of the amount of thinking that goes into a well-designed
%system.

前節でMercurialの設計の最も重要な面について取り上げ，信頼性と性能に細心の
注意を払っていることを強調した．しかし細部への注意はそれだけに留まらない．
Mercurialの構造には，個人的に興味深く感じた点が多々ある．巧妙に設計された
システムの背後にあるアイディアについて読者が興味を持つならば，より深い理
解が出来るよう，前述した大きな括りとは別にその2,3について取り上げてみよう
と思う．

%\subsection{Clever compression}
\subsection{賢い圧縮}

%When appropriate, Mercurial will store both snapshots and deltas in
%compressed form.  It does this by always \emph{trying to} compress a
%snapshot or delta, but only storing the compressed version if it's
%smaller than the uncompressed version.

適切な場合，Mercurialはスナップショットと差分を圧縮された形式で保存する．
Mercurialは常にスナップショットや差分の圧縮を\emph{試みる}が，それを保存
するのは圧縮されたバージョンが元のバージョンよりも小さい時のみである．

%This means that Mercurial does ``the right thing'' when storing a file
%whose native form is compressed, such as a \texttt{zip} archive or a
%JPEG image.  When these types of files are compressed a second time,
%the resulting file is usually bigger than the once-compressed form,
%and so Mercurial will store the plain \texttt{zip} or JPEG.

つまり，Mercurialは\texttt{zip}アーカイブやJPEG画像などのように元々圧縮さ
れているファイルの保存を``正しいやり方''で行う．これらのファイルでは，差
分取って圧縮を行っても結果として得られるファイルは通常，元のファイルより
も大きくなる．そこでMercurialは\texttt{zip}やJPEGをそのまま保存する．

%Deltas between revisions of a compressed file are usually larger than
%snapshots of the file, and Mercurial again does ``the right thing'' in
%these cases.  It finds that such a delta exceeds the threshold at
%which it should store a complete snapshot of the file, so it stores
%the snapshot, again saving space compared to a naive delta-only
%approach.

通常，圧縮されたファイルのリビジョン間の差分はファイルのスナップショット
より大きい．ここでもMercurialは``正しいやり方''を用いている．このような
状況で，差分のサイズがファイルの完全なスナップショットとして保存した方が
有利となる閾値を越えると，差分ではなくスナップショットを保存する．このよ
うにして単純に差分のみを記録するアプローチよりも記憶領域を節約している．

%\subsubsection{Network recompression}
\subsubsection{ネットワーク再圧縮}

%When storing revisions on disk, Mercurial uses the ``deflate''
%compression algorithm (the same one used by the popular \texttt{zip}
%archive format), which balances good speed with a respectable
%compression ratio.  However, when transmitting revision data over a
%network connection, Mercurial uncompresses the compressed revision
%data.

ディスクにリビジョンを保存する際，Mercurialは``deflate''圧縮アルゴリズム
を用いる．（これは人気の高い\texttt{zip}アーカイブフォーマットと同じアル
ゴリズムである．）このアルゴリズムは高い圧縮率と高速性をバランスさせてい
る．しかしリビジョンデータをネットワークで伝送する際にはMercurialは圧縮さ
れているリビジョンデータを伸長する．

%If the connection is over HTTP, Mercurial recompresses the entire
%stream of data using a compression algorithm that gives a better
%compression ratio (the Burrows-Wheeler algorithm from the widely used
%\texttt{bzip2} compression package).  This combination of algorithm
%and compression of the entire stream (instead of a revision at a time)
%substantially reduces the number of bytes to be transferred, yielding
%better network performance over almost all kinds of network.

HTTPによる接続の場合，Mercurialはデータストリーム全体をより圧縮率の高いア
ルゴリズム（広く用いられている圧縮パッケージである\texttt{bzip2}で使われ
ているBurrows-Wheelerアルゴリズム）で再圧縮する．このアルゴリズムと，（リ
ビジョン毎でなく）ストリーム全体を圧縮することにより，送信されるバイト数
は大きく低減され，あらゆるネットワークでよい性能をえることができる．

%(If the connection is over \command{ssh}, Mercurial \emph{doesn't}
%recompress the stream, because \command{ssh} can already do this
%itself.)

（\command{ssh}による接続の場合，Mercurialはストリームの再圧縮は行わな
い．\command{ssh}コマンド自体が圧縮を行うためである．）

%\subsection{Read/write ordering and atomicity}
\subsection{読み書きの順序とアトミック性}

%Appending to files isn't the whole story when it comes to guaranteeing
%that a reader won't see a partial write.  If you recall
%figure~\ref{fig:concepts:metadata}, revisions in the changelog point to
%revisions in the manifest, and revisions in the manifest point to
%revisions in filelogs.  This hierarchy is deliberate.

ファイルへの追記は読み手が部分ファイルを読まないことの保証としては十分で
はない． 図~\ref{fig:concepts:metadata}を思い起こすと，チェンジログ内のリ
ビジョンはマニフェスト内のリビジョンを指し示しており，マニフェスト内のリ
ビジョンはファイルログ内のリビジョンを指し示していた．この階層構造は重要
な意味を持っている．

%A writer starts a transaction by writing filelog and manifest data,
%and doesn't write any changelog data until those are finished.  A
%reader starts by reading changelog data, then manifest data, followed
%by filelog data.

書き手はファイルログとマニフェストを書き込むことでトランザクションを
開始するが，これらが完了するまでチェンジログデータの書き込みは行わない．
一方，読み手はチェンジログデータ，マニフェストデータ，ファイルログデータ
の順に読み出しを行う．

%Since the writer has always finished writing filelog and manifest data
%before it writes to the changelog, a reader will never read a pointer
%to a partially written manifest revision from the changelog, and it will
%never read a pointer to a partially written filelog revision from the
%manifest.

書き手は常にファイルログとマニフェストデータをチェンジログの前に書き込み
終了しているため，読み手は部分的に書かれたマニフェストリビジョンへのポイ
ンタををチェンジログから読み出すことはない．また部分的に書かれたファイル
ログリビジョンへのポインタをマニフェストから読み出すこともない．

%\subsection{Concurrent access}
\subsection{同時アクセス}

%The read/write ordering and atomicity guarantees mean that Mercurial
%never needs to \emph{lock} a repository when it's reading data, even
%if the repository is being written to while the read is occurring.
%This has a big effect on scalability; you can have an arbitrary number
%of Mercurial processes safely reading data from a repository safely
%all at once, no matter whether it's being written to or not.

読み書きの順序とアトミック性の保証により，Mercurialではデータの読み出し時
にリポジトリの\emph{ロック}が不要になっている．読み出し中に書き込みが発生
したとしても同様である．このことはスケーラビリティに大きな効果をもたら
す．多数のMercurialプロセスがあっても，リポジトリへの書き込みの有無に関わ
らず，リポジトリから一度に安全にデータを読み出すことができる．

%The lockless nature of reading means that if you're sharing a
%repository on a multi-user system, you don't need to grant other local
%users permission to \emph{write} to your repositoryin order for them
%to be able to clone it or pull changes from it; they only need
%\emph{read} permission.  (This is \emph{not} a common feature among
%revision control systems, so don't take it for granted!  Most require
%readers to be able to lock a repository to access it safely, and this
%requires write permission on at least one directory, which of course
%makes for all kinds of nasty and annoying security and administrative
%problems.)

Mercurialでは，ロック無しで読み出しを行うため，マルチユーザシステム上でリ
ポジトリを共有している場合でもcloneやpullを行おうとする他のローカルユーザ
にリポジトリへの\emph{書き込み}許可を与える必要はない．彼らには\emph{読み
出し}許可があればよい．（他のリビジョンコントロールシステムではこうはいか
ず，大半のシステムでは読み手が安全にリポジトリにアクセスするためにロック
を取得することを必要とする．これはすなわち読み手が少なくとも1つのディレク
トリに対して書き込み許可を持っていなければならないことを意味する．このた
めにセキュリティや管理上の厄介な問題が発生し得る．）

%Mercurial uses locks to ensure that only one process can write to a
%repository at a time (the locking mechanism is safe even over
%filesystems that are notoriously hostile to locking, such as NFS).  If
%a repository is locked, a writer will wait for a while to retry if the
%repository becomes unlocked, but if the repository remains locked for
%too long, the process attempting to write will time out after a while.
%This means that your daily automated scripts won't get stuck forever
%and pile up if a system crashes unnoticed, for example.  (Yes, the
%timeout is configurable, from zero to infinity.)

Mercurialは一度に1プロセスだけがリポジトリに書き込むことを保証するために
ロックを使っている．（Mercurialの用いるロックメカニズムはNFSのようにロッ
クと相性の悪いことで有名なファイルシステム上でも安全である．）リポジトリ
がロックされると，書き込みプロセスはリポジトリがアンロックされるまでしば
らく待つ．しかしリポジトリが長時間にわたってロックされ続ける場合は，書き
込みしようとするプロセスはタイムアウトする．これは，例えば，日常用いる自
動スクリプトは永遠にスタックするわけではないことを意味する．（もちろんタ
イムアウトまでの時間はゼロから無限の間で設定かのうである）

%\subsubsection{Safe dirstate access}
\subsubsection{安全なdirstateアクセス}

%As with revision data, Mercurial doesn't take a lock to read the
%dirstate file; it does acquire a lock to write it.  To avoid the
%possibility of reading a partially written copy of the dirstate file,
%Mercurial writes to a file with a unique name in the same directory as
%the dirstate file, then renames the temporary file atomically to
%\filename{dirstate}.  The file named \filename{dirstate} is thus
%guaranteed to be complete, not partially written.

リビジョンデータの時と同様に，Mercurialはdirstateファイルを読み出す際には
ロックを行わない．ロックを行うのは書き込みの時のみである．一部のみが書き
込まれたdirstateファイルを読み込まないようにするため， Mercurialは同じディ
レクトリ内にユニークな名前でdirstateファイルを書き，この一時ファイルをア
トミックに\filename{dirstate}にリネームする．これによ
り，\filename{dirstate}ファイルは常に完全であることが保証される．

%\subsection{Avoiding seeks}
\subsection{シークの回避}

%Critical to Mercurial's performance is the avoidance of seeks of the
%disk head, since any seek is far more expensive than even a
%comparatively large read operation.

Mercurialの性能には，ディスクヘッドのシークを避けることが不可欠である．
シークは大規模な読み出し操作と比較しても非常に高くつく．

%This is why, for example, the dirstate is stored in a single file.  If
%there were a dirstate file per directory that Mercurial tracked, the
%disk would seek once per directory.  Instead, Mercurial reads the
%entire single dirstate file in one step.

その理由は，例えば，dirstateは1つのファイルに保存されているためで，
Mercurialが追跡しているdirstateファイルがディレクトリ毎にある
と，Mercurialはディレクトリ毎にシークを行うことになる．実際にはMercurial
は全体で一つのdirstateファイルをワンステップで読む．

%Mercurial also uses a ``copy on write'' scheme when cloning a
%repository on local storage.  Instead of copying every revlog file
%from the old repository into the new repository, it makes a ``hard
%link'', which is a shorthand way to say ``these two names point to the
%same file''.  When Mercurial is about to write to one of a revlog's
%files, it checks to see if the number of names pointing at the file is
%greater than one.  If it is, more than one repository is using the
%file, so Mercurial makes a new copy of the file that is private to
%this repository.

Mercurialはリポジトリをローカルストレージにクローンする際に``コピーオンラ
イト''手法を使っている．元のリポジトリから新しいリポジトリへ全てのrevlog
ファイルをコピーするのではなく，ハードリンクを作成する．ハードリンクは同
一のファイルを指し示す別名を作る簡単な方法である． Mercurialはrevlogファ
イルに書き込みを行う際にファイルを示す名前が2つ以上ある稼働かをチェックす
る． 2つ以上の名前がある場合，2つ以上のリポジトリがファイルを使用してお
り，Mercurialはファイルのリポジトリに固有な新しいコピーを作成する．

%A few revision control developers have pointed out that this idea of
%making a complete private copy of a file is not very efficient in its
%use of storage.  While this is true, storage is cheap, and this method
%gives the highest performance while deferring most book-keeping to the
%operating system.  An alternative scheme would most likely reduce
%performance and increase the complexity of the software, each of which
%is much more important to the ``feel'' of day-to-day use.

リビジョンコントロールシステムの開発者の幾人かは，ファイルの完全なプライ
ベートコピーを作るというアイディアは，ストレージの利用量の観点からあまり
効率的でないと指摘している．これは事実であるが，ストレージは安価であり，
この方法はOS上で差分を取る場合最高の性能をもたらす．その他の手法は性能を
損ない，ソフトウェアが複雑になる可能性が高い．これらは日々の使用感よりも
ずっと重要である．

%\subsection{Other contents of the dirstate}
\subsection{dirstateの他の内容}

%Because Mercurial doesn't force you to tell it when you're modifying a
%file, it uses the dirstate to store some extra information so it can
%determine efficiently whether you have modified a file.  For each file
%in the working directory, it stores the time that it last modified the
%file itself, and the size of the file at that time.

Mercurialは，ファイルを変更した場合でも，変更の申告を強制しないため，
dirstateに追加の情報を保存することでファイルを変更したかどうか効果的に判
別する．ワーキングディレクトリのすべてのファイルについて，最後にファイル
が変更された時刻と，その際のファイルサイズを記録している．

%When you explicitly \hgcmd{add}, \hgcmd{remove}, \hgcmd{rename} or
%\hgcmd{copy} files, Mercurial updates the dirstate so that it knows
%what to do with those files when you commit.

明示的にファイルを\hgcmd{add}, \hgcmd{remove}, \hgcmd{rename} または
\hgcmd{copy}した場合，Mercurialはdirstateを更新し，コミットの際にそれら
のファイルをどう取り扱うかを判断する．

%When Mercurial is checking the states of files in the working
%directory, it first checks a file's modification time.  If that has
%not changed, the file must not have been modified.  If the file's size
%has changed, the file must have been modified.  If the modification
%time has changed, but the size has not, only then does Mercurial need
%to read the actual contents of the file to see if they've changed.
%Storing these few extra pieces of information dramatically reduces the
%amount of data that Mercurial needs to read, which yields large
%performance improvements compared to other revision control systems.

Mercurialがワーキングディレクトリのファイルの状態をチェックする際は，まず
ファイルの更新日時を調べる．これが変更されていない場合はファイルは変更が
ないということがわかる．ファイルサイズが変わっている場合は，ファイルが変
更されたことがわかる．更新日時が変わっているが，サイズが同じ場合は
Mercurialはファイルの内容を直接見て，変更されているかどうかを判断する必要
がある．これらのごく僅かの情報を保存することによって，Mercurialはデータの
読み取り量を劇的に削減し，他のリビジョンコントロールシステムと比較して大
きな性能向上を達成している．

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