Commits

Katsunori FUJIWARA committed d7c87f4

元資料に対する修正案の提案

- 用語や概念の登場順とかを考えての記述順序の入れ替え: ブランチ等
- 説明の追加: リビジョン/ヘッド等

Comments (0)

Files changed (1)

 -----------------------------------
 TODO 思いの丈をぶつけます
 
-リポジトリとはなにか
---------------------
-全ての変更点、履歴をまとめて格納するデータベースの事です。
-Subversionなどの集中型のバージョン管理システムでは基本的にはリポジトリはリモートに一つだけ存在します。
-作業を行う場合、リポジトリをチェックアウトして最新のコピーを取得し作業を行います。
-分散バージョン管理システム(Bazaar、Git、Mercuiralなど)では、チェックアウトして開発を行うのではなく、
-リポジトリ自体のコピーを作成して開発を行います。
+リポジトリ
+-----------------------------------
 
-Subversionでは最新のコピーを取得しているだけです。
-履歴を閲覧する場合はリモートのリポジトリから履歴を得ます。コミットする場合はリモートのリポジトリにコミットを行います。
+(狭義の)リポジトリ
+^^^^^^^^^^^^^^^^^^^^
+SCM ツールにおいて、
+作成/改変/移動/削除といったファイルに対する作業内容や、
+実施者/日付といった
+「履歴」 (history) に関する管理情報を格納しておく領域を、
+(狭義の)「リポジトリ」 (repository) と呼びます。
+
+作業領域
+^^^^^^^^^^^^^^^^^^^^
+リポジトリに格納されている情報を元に、
+ファイルを取り出したり、
+取り出したファイルに対する作成/改変/移動/削除といった作業を行う領域を、
+CVS や Subversion では
+「ワーキングコピー」 (working copy) 、
+『 `パターンによるソフトウェア構成管理`_ 』
+では「プライベートワークスペース」 (private workspace) などと呼びますが、
+Mercurial では「作業領域」 (working directory) と呼びます。
+
+.. _`パターンによるソフトウェア構成管理`: http://www.amazon.co.jp/dp/4798112593
+
+CVS や Subversion では、
+リポジトリからの「チェックアウト」 (checkout)
+によって作業領域が作成されます。
 
   ::
-
+    
      リポジトリ                        作業領域
     |----------|    チェックアウト    |--------|
     |          |   ---------------->  |        |
     |          |                      |        |
     |----------|                      |--------|
     
+    図 svn 時代の作業領域作成
+
+
+作業領域には、
+ごくわずかの管理情報
+(例: 各ディレクトリの CVS/ や .svn/)
+しか保存されないため、
+履歴情報の参照/変更が必要になった際には、
+基本的に常にチェックアウト元のリポジトリに対して
+(場合によってはネットワーク経由で)
+問い合わせが発生します。
+
+
+  ::
+    
      リポジトリ                        作業領域
     |----------|                      |--------|
     |          |                      | xxx    | なにか作業する
     |----------|   ---------------->  |--------| ---------->
 
      リポジトリ                        作業領域
-    |----------|      svn commit      |--------|   svn commit
+    |----------|      作業内容        |--------|   svn commit
     | xxx      |   <----------------  | xxx    | <----------
     |          |                      |        |
     |          |      結果            |        |   結果
     |----------|   ---------------->  |--------| ----------->
     
-    図 svn 時代
+    図 svn 時代の日常作業
 
-Mercurialではリポジトリ自体のコピーを作成しています。
-履歴を閲覧する場合は手元のリポジトリの履歴を、コミットする場合は手元のリポジトリにコミットを行います。
+その一方 Mercurial の場合は、
+作業領域とリポジトリは一体化しており、
+この「作業領域と一体になったリポジトリ」も、
+広義の意味で「リポジトリ」と呼んでいます。
+
+CVS や Subversion では、
+たとえリポジトリが空であっても、
+「リポジトリ」を作って「作業領域」にチェックアウトする、
+という手順を踏む必要がありますが、
+Mercurial では (当面一人で新規の作業するのであれば)
+リポジトリの新規作成を行うコマンド ("hg init") を事項したなら、
+即座に作業領域として使用することができます。
+
+  ::
+    
+                           リポジトリ兼作業領域
+         hg init          |--------|
+       ---------------->  |        |
+         新規作成         |        |
+                          |        |
+                          |--------|
+    
+    図 svn 時代の作業領域作成
+
+「リポジトリ兼作業領域」は、
+以下のようなディレクトリ構成になっています。
 
   ::
 
-     リポジトリ                        リポジトリ(兼作業領域)
-    |----------|     クローン         |--------|
-    |          |   ---------------->  |        |
-    |          |                      |        |
-    |          |                      |        |
-    |----------|                      |--------|
+    / リポジトリルート(兼 作業領域となるディレクトリ)
+    |
+    |-- .hg/ メタデータ格納ディレクトリ
+    | |
+    | |-- store/ リビジョンの格納されているディレクトリ
+    | |          絶対触るな!
+    | |
+    | |-- hgrc リポジトリ固有のMercurialの設定ファイル
+    | |        hg init で初期化した場合は作成されない為、手で作成する
+    | |        よく編集するファイル
+    | |
+    | |-- .... 他にもいろいろあるけど、用途を理解するまでは
+    |          基本的に「触るな!」
+    |
+    |-- 作業領域
+    
+    図 リポジトリの構成
+
+
+「(狭義の)リポジトリ」と「作業領域」が一体となっているため、
+「(狭義の)リポジトリへの履歴情報の問い合わせ」も、
+手元の(広義の)リポジトリの中で完結します。
+
+  ::
+    
+         リポジトリ兼作業領域
+        |--------|
+        | xxx    | なにか作業する
+        |        |
+        |        |
+        |--------|
+    
+         リポジトリ兼作業領域
+        |--------|   hg log
+        | xxx    | <---------
+        |        |
+        |        |   履歴
+        |--------| --------->
+    
+         リポジトリ兼作業領域
+        |--------|   hg commit
+        | xxx    | <------------
+        |        |
+        |        |   結果
+        |--------| ------------>
+    
+    図 分散時代の日常作業
+
+リポジトリ間での連携は、
+他のリポジトリ(= 他の作業/他の人/他の拠点等)
+における作業成果を、
+自身のリポジトリに取り込みたい場合や、
+自身の成果を他のリポジトリに反映したい場合にのみ、
+必要となります。
+
+他からの取り込みは "hg pull"、
+他への反映は "hg push" で行います。
+
+  ::
     
      リポジトリ                        リポジトリ(兼作業領域)
-    |----------|                      |--------|
-    |          |                      | xxx    | なにか作業する
+    |----------|      変更要求        |--------|   hg pull
+    | yyy      |   <----------------  | xxx    | <----------
     |          |                      |        |
-    |          |                      |        |
-    |----------|                      |--------|
+    |          |      変更履歴        | yyy    |   結果
+    |----------|   ---------------->  |--------| ---------->
     
-     リポジトリ                        リポジトリ(兼作業領域)
-    |----------|                      |--------|   hg log
-    |          |                      | xxx    | <---------
-    |          |                      |        |
-    |          |                      |        |   履歴
-    |----------|                      |--------| --------->
     
-     リポジトリ                        リポジトリ(兼作業領域)
-    |----------|                      |--------|   hg commit
-    | xxx      |                      | xxx    | <------------
-    |          |                      |        |
-    |          |                      |        |   結果
-    |----------|                      |--------| ------------>
-    
-    図 分散時代
-
-リポジトリ間の変更点の同期にはhg pushを利用します。
-
-  ::
-
-     リポジトリ                        リポジトリ(兼作業領域)
-    |----------|       変更点         |--------|   hg push
+    |----------|      変更反映        |--------|   hg push
     | xxx      |   <----------------  | xxx    | <----------
     |          |                      |        |
-    |          |       結果           |        |   結果
+    | yyy      |       結果           |        |   結果
     |----------|   ---------------->  |--------| ---------->
     
     図 分散時代のリポジトリ間の同期
 
+
+共同作業の成果を共有する場合、
+作業領域にファイルを取り出さない/作業しないようにして、
+「狭義のリポジトリ」のみで運用する、
+いわゆる「共有リポジトリ」を設置するのが一般的です。
+
+既に記録された誰かの成果を元に作業を開始する場合は、
+リポジトリの新規作成 ("hg init") ではなく、
+「共有リポジトリ」からの複製 ("hg clone") によって、
+自分用の(広義の)リポジトリを作成するのが一般的です。
+
+
 TODO 概要っぽい図じゃない。。。
 
 TODO 複数人での作業をどうする、、
 
-作業領域
---------
-DVCSではリポジトリは複製(クローン、clone)して利用する事が前提となっています。
-実際にプログラミングなどの作業を行うために複製したリポジトリを作業領域と呼びます。
-
-具体的にはリポジトリの.hgディレクトリ以外を作業領域として利用します。
-これは、Mercurialでは履歴などのメタデータを.hgディレクトリに格納するためです。
 
 作業領域でファイルを編集し、コミットすると、複製元には存在しない新しいリビジョンを作成する事が出来ます。
 
 リビジョン
-----------
-一度のコミットに含まれる変更点のまとまりの事です。チェンジセットやコミットとも呼ばれます。
+-----------------------------------
 
-具体的に、リビジョンには次の情報が記録されています。
+リビジョンとは
+^^^^^^^^^^^^^^^^^^^^
+構成管理における、変更履歴の記録単位。
+リビジョンの連なりによって、
+作業の履歴が形成されます。
+各リビジョン毎に以下の内容が記録されます。
 
-  - 作成したしたユーザ名
-  - 作成した日付
-  - ファイルに関する情報(変更、追加、削除など)
-  - チェンジセットに対するコメント
-  - その他情報(ブランチ名などを含む)
+  - 自リビジョンの識別子
+  - 親リビジョンの識別子 (※ ぱっと見、見えない場合あり)
+  - 記録したユーザ名
+  - 記録した日付
+  - コメント
+  - その他の属性情報(ブランチ名など)
+  - ファイルに対する変更内容
 
-次の情報は直接リビジョンの情報として管理するのではなく、コミットしたファイルから取得します。
-
-  - タグ
-
-リビジョンの指定方法
---------------------
-Mercurialでは次の方法でリビジョンを一意に指定出来ます。
-
-  - ハッシュ値 リビジョン固有の40桁の16進数
-  - リビジョン番号 一つのリポジトリ内の連番
-
-リビジョンの指定にタグ名やブランチ名を利用した場合は、次のルールで該当するリビジョンを決定します。
-
-  - タグ名(タグ名が付けられたリビジョン)
-  - ブランチ名(ブランチ名が付けられたリビジョンのうち、最新のもの)
-
-一つのリビジョンではなく、リビジョンの集合を指定したい場合は、集合の条件を簡単に記述する為のDSLが用意されています。
-
-  - DSLの例
+"hg log" 等のコマンドの実行により、以下のような形式で表示されます。
 
   ::
 
-    # "指定したブランチの先祖を新しい順で、ただしマージコミットは除く"リビジョンのログを出力
+    ※ TODO !!!!後で差し替えてください!!!!)
+    チェンジセット:   359:a0fbbc6ba9e4
+    タグ:             tip
+    ユーザ:           FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
+    日付:             Thu Oct 20 17:32:13 2011 +0900
+    要約:             Solaris Internals ch9 まとめ資料を更新 (〜 9.5)
+
+CVS 以前の SCM ツールでは、
+ファイル毎にリビジョンの記録を管理していたため、
+「ファイルに対する変更内容」の管理がファイル毎にばらばらでした。
+
+しかし、Subversion からは、記録の管理単位が
+「(利用者にとって)意味を持つ、
+一連のファイルへの変更のまとまり」となったことで、
+これを「変更内容の集合」の意味から
+「チェンジセット」(changeset)と呼ぶようになりました。
+
+また、変更内容を履歴に記録する際のコマンド名が
+「コミット」 (commit) であることから、
+「リビジョン」「チェンジセット」「コミット」は多くの場合、
+同等の意味を持ちます。
+
+    ※ TODO Mercurial コマンドのメッセージ翻訳では、
+    基本的に「リビジョン」に統一しています。
+    が、"hg log" の出力では、原文に倣って「チェンジセット」を使用しています
+    ... orz (by 藤原)
+
+
+以下の情報の記録は、リビジョンに対してではなく、
+管理ファイルに別途記録されます。
+
+  - タグ(後述)とリビジョンの対応関係
+
+
+リビジョンの指定方法
+^^^^^^^^^^^^^^^^^^^^
+Mercurialでは次の方法でリビジョンを一意に指定出来ます。
+
+  - 完全長ハッシュ値: リビジョン固有の40桁の16進数
+  - 短縮ハッシュ値: リビジョン固有の12桁の16進数
+  - リビジョン番号: リポジトリ内での通し番号
+
+「完全長」ないし「短縮」ハッシュ値は、
+「チェンジセットID」(changeset ID)とも呼ばれます。
+
+ハッシュ値による識別は、
+基本的にリポジトリをまたいでユニークですが、
+リビジョン番号は手元のリポジトリでのみ有効な番号ですので、
+全く同じリポジトリを操作している時以外に、
+他の人との会話で使用すると、
+混乱の元になりますから注意しましょう。
+
+    ※ TODO 完全長ハッシュ値は確実にユニーク。
+    短縮ハッシュ値は「まぁまぁ」ユニークな点に注意
+
+特定のリビジョンに対して、
+人が認識しやすい名前を付ける機能が「タグ」 (tag) 付け機能です。
+タグが付いているリビジョンに関しては、上記の3種類以外に、
+タグ名を使ってリビジョンを指定することも可能です。
+
+通常のタグ付けは、
+一旦設定したなら基本的には対象リビジョンに固定されますが、
+「一番最新」のリビジョンを指す "tip" というタグは、
+リビジョンが増える度に Mercurial が自動的に設定対象を更新します。
+
+一つのリビジョンではなく、リビジョンの集合を指定したい場合、
+旧来の簡易表記方式 ("hg help multirevs" 参照) と:
+
+  ::
+
+    # リビジョン番号 3 からリビジョン番号 10 までを表示
+    $ hg log -r 3:10
+
+集合の条件を簡単に記述する為の DSL (Domain Specific Language) である
+revsets (revision sets) 方式 ("hg help revsets" 参照)
+の2種類で指定可能です。
+
+  ::
+
+    # "指定したブランチの先祖を新しい順で、ただしマージコミットは除く"
+    # リビジョンのログを出力
     hg log -r "reverse(ancestors('BRANCH_NAME')) and not merge()"
 
 ヘッド
-------
-コミットを積み重ねるとリポジトリの中では次の様なグラフが作成されます。
-「o」一つ一つがリビジョンです。コミットすると出来ます。「@」は今の作業領域のリビジョンです。
+--------------------
+
+ヘッドとは
+^^^^^^^^^^^^^^^^^^^^
+コミットを積み重ねることで、
+リビジョン記録のグラフ (= 履歴) が作成されます。
+
+リビジョングラフの中で、
+子リビジョンを持たないリビジョンの事を
+「ヘッド」 (HEAD) と呼びます。
+次のグラフではリビジョン2がヘッドです。
 
   ::
 
     
     図 リビジョングラフ
 
-リビジョングラフの中で子リビジョンを持たないリビジョンの事をヘッド(HEAD)と呼びます。
-次のグラフではリビジョン2がヘッドです。
+マルチプルヘッドとは
+^^^^^^^^^^^^^^^^^^^^
+ヘッド「でない」リビジョンを親にして、
+新たなリビジョンを生成することを、
+Mercurial では(広義の)「ブランチ」 (branch: 枝分かれ) と呼びます。
+原文では "topological branch" などと呼ばれています。
+
+以下の履歴ツリーで言えば、
+リビジョン 2 の後で生成されたリビジョン 3 はブランチになります。
 
   ::
 
-    @    2:default(ヘッド)
-    |
-    |
-    o    1:default
-    |
-    |
-    o    0:default
+    TODO
     
-    図 ヘッド
+    図 リビジョングラフ
 
-例外として、親リビジョンと子リビジョンのブランチ名が異なる場合は、親リビジョンはヘッド扱いされます。
-次のグラフでは親リビジョン1と子リビジョン2のブランチ名が異なるので、リビジョン1はヘッドです。
+ヘッドを親にして新たなリビジョンを作成した場合は、ブランチになりません。
 
   ::
 
-    @    2:default(ヘッド)
-    |\
-    | |
-    | o  1:feature/hogehoge(ヘッド)
-    |/
-    |
-    o    0:default
+    TODO
     
-    図 ブランチが異なる場合のヘッド
+    図 リビジョングラフ
 
-マルチプルヘッド
-----------------
-Mercurialではコミットすると必ずリビジョンが出来ます。
-では、次の様に親リビジョンに戻った後に新しいリビジョンを作ったらどうなるでしょうか。
-
-  ::
-
-    o    1:default
-    |
-    |
-    @    0:default
-    
-    図 親リビジョンに戻った状態でコミットするとどうなる?
-
-Mercurialではコミットすると必ずリビジョンが出来ます。大事なので2回言いました。
-答えはつぎの様なグラフになります。
-
-  ::
-
-    @    2:default(ヘッド)
-    |
-    |
-    | o  1:default(ヘッド)
-    |/
-    |
-    o    0:default
-    
-    図 マルチプルヘッド
-
-このグラフでは、defaultという同一ブランチ内に二つ以上のヘッドが存在します。
-このような状態の事を(狭義の)マルチプルヘッドと呼びます。
-
-毎回(狭義の)マルチプルヘッドと呼ぶのは手間なのでこれ以降は単にマルチプルヘッドと呼びます。
-
-.. note:: (広義の)マルチプルヘッド
-
-  再度、ヘッドの項で例外として紹介したブランチの存在するグラフを見てみましょう。
-
-    ::
-    
-      @    2:default(ヘッド)
-      |\
-      | |
-      | o  1:feature/hogehoge(ヘッド)
-      |/
-      |
-      o    0:default
-      
-      図 ブランチが異なる場合のヘッド
-
-  このグラフでは、同一ブランチ内に二つ以上のヘッドは存在しません。
-  しかし、リポジトリ全体としてはリビジョン1とリビジョン2の二つのヘッドが存在します。
-  このように、リポジトリ全体でヘッドが二つ以上存在する状態の事を(広義の)マルチプルヘッドと呼びます。
-  
-  このことから、ブランチを1つでも作成するとそれ以降、そのリポジトリは(広義の)マルチプルヘッドとなります。
+ブランチによってヘッドが複数ある状態を、
+「マルチプルヘッド」 (multiple heads) と呼びます。
 
 複数人での協調作用で発生するマルチプルヘッド
---------------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 先ほどのマルチプルヘッドの例では無理矢理マルチプルヘッドを作成していました。
 これは一人で作業している場合はマルチプルヘッドが作成されにくい為です。
 
 ------
 マルチプルヘッドの様に、二つの分離してしまった履歴を統合する作業をマージと呼びます。
 
+マージ手順例
+^^^^^^^^^^^^^^^^^^^^
 先ほどの新Bobリポジトリでマージを行うと次の様になります。
 
   ::
     図 Bobリポジトリのマージの成果を中央リポジトリの変更を取り込む
 
 コミット済み成果ベースのマージ
-------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 Mercurialは自動的に複数人の作業のマージを行わないので、Subversionから比べると一見不便に見えます。
 
 しかしこれはとても安全な方法なのです。
 
 これらのことからMercurialのマージはとても安全な方法といえます。
 
-ブランチとは何か
-----------------
-Mercurialではチェンジセットに付けられた属性の事です。
+(名前付き)ブランチ
+------------------
 
-一連の作業のまとまりを区別する為にブランチを利用します。
-作業の目的でブランチを切り(ブランチ名の変更のみを持つコミットをすること)作業を行います。
-ブランチでの作業が完了したら、元のブランチにマージをしてブランチの変更を取り込みます。
+名前付きブランチとは
+^^^^^^^^^^^^^^^^^^^^
+Mercurial では、
+履歴ツリーにおける枝分かれ元と枝分かれ先を識別するために、
+枝分かれ先に名前を付けることができます。
+このように名前をつけられたブランチを「名前付きブランチ」
+(named branch) と呼びます。
 
-ブランチをなぜ使うのか
-----------------------
+以下の履歴グラフでは、
+リビジョン 3 が "RELEASE" という名前付きブランチに属します。
+
+  ::
+
+    TODO
+    
+    図 リビジョングラフ
+
+CVS や Subversion 等の多くの SCM ツールで言うところの「ブランチ」は、
+Mercurial での「名前付きブランチ」とほぼ等価と考えてよいでしょう
+(厳密には色々違いますが....)。
+
+その一方で、
+これまでの説明で使用してきた、
+名前付き「ではない」ブランチは
+「名前無しブランチ」 (anonymous branch) と呼ばれます。
+
+名前付きブランチに属するリビジョンを親に持つリビジョンは、
+以下のいずれにも当てはまらない場合、親と同じ名前付きブランチに属します。
+
+  - 新たな名前付きブランチとしてブランチ
+  - 別な名前付きブランチへとマージ(後述)
+
+"default" は、明示的に名前付きブランチが作られていない状態で、
+生成されたリビジョンに対して割り当てられる、特別なブランチ名です。
+
+Mercurial では、
+全てのリビジョンは必ず何らかの名前付きブランチに属しますが、
+特別に "default" に属しているリビジョンに関しては、
+(便宜上)「名前付きブランチには属さないもの」とみなしている、
+と考えてください。
+
+なお、「名前付きブランチ」は、
+必ずしも「ブランチ」状態を伴わない場合もあります。
+例えば、先述した「マルチプルヘッド」での
+「ヘッドを親にして新たなリビジョンを作成」する場合に、
+新規リビジョンから先を「名前付きブランチ」として扱うこともできますが、
+この場合、いわゆる「ブランチ」状態は発生しません。
+
+  ::
+
+    TODO
+    
+    図 リビジョングラフ
+
+これは、一般的な運用であれば、ブランチ元の親リビジョンに対して、
+将来的に新たな子リビジョンが生成されることが想定できますので、
+長期的なスパンで見た場合には「ブランチしている」と言えるでしょう。
+
+  ::
+
+    TODO
+    
+    図 リビジョングラフ
+
+名前付きブランチのマージ
+^^^^^^^^^^^^^^^^^^^^^^^^
+Mercurial のマージでは、マージ対象となる2つのリビジョンが、
+異なる名前付きブランチに属している場合、
+どちらをマージ元/先にするかが重要となります。
+
+2つの名前付きブランチ B_one と B_two を想定します。
+
+作業領域の親リビジョン (= マージ先) が B_one、
+マージ対象 (= マージ元) が B_two の場合、
+マージによって生成されるリビジョンは B_one ブランチに属します。
+
+  ::
+
+    TODO
+    
+    図 リビジョングラフ
+
+この逆に、
+作業領域の親リビジョンが B_two、マージ対象が B_one の場合、
+マージによって生成されるリビジョンは B_two ブランチに属します。
+
+  ::
+
+    TODO
+    
+    図 リビジョングラフ
+
+
+名前付きブランチをなぜ使うのか
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 TODO 利点、運用の変化について
 
 大きく分けて次の二つの種類のブランチが存在する。