Mercurial 勉強中 (1)
Mercurial の特徴
Mercurialでバージョン管理,http://python.matrix.jp/modules/mercurial.html#id3 も参照のこと。
- 分散型 SCM として設計されている
- 各レポジトリのチェックアウトはおのおの(基本的に)独立している;独立して生きていける
- Subversion のように中央集権的レポジトリを作れない,というわけではない
- 各作業者が「マスターレポジトリ」の共通認識をもてばよい(そこから
clone
してきてpull
/push
するのだ,と)
- 各作業者が「マスターレポジトリ」の共通認識をもてばよい(そこから
- レポジトリのセットアップ等がかんたん
- レポジトリのセットアップは管理したいフォルダに移動して
hg init
とうつだけ(その後hg addremove
したり) - 分散管理ではなく自分だけで管理するなら RCS 並,いやそれ以上に簡単
- レポジトリのセットアップは管理したいフォルダに移動して
- レポジトリデータは,レポジトリのトップディレクトリの直下の
.hg
というディレクトリのみにおかれる- ローカルだろうがリモートだろうがレポジトリごと複製/移動したい場合,極端な話
cp -R
/scp -r
してしまえばよい
- ローカルだろうがリモートだろうがレポジトリごと複製/移動したい場合,極端な話
- ほぼ Python で書かれている
- 一部 OS レベルの処理とバイナリファイルを扱う処理で C のコードがある(0.9.5 で 5 つほど)
- コマンドラインインタフェースのコマンド名は
hg
(名前の由来は⇒ http://www.pshared.net/diary/20080104.html#p01)
軽さだのなんだのはまだ実感するほど使いこなしていません。
Mercurial と Subversion (SVK) の違い
Subversion も SVK を組み合わせると分散レポジトリ管理ができるようになりますが,それでもやっぱり感覚的に違う部分があるので図におこしてみました。
- Subversion (
svn
) の場合,checkout の際は指定したリビジョン(省略時はHEAD
)のスナップショットを取得します - Subversion の場合,working copy の各サブフォルダに管理用フォルダとして
.svn
がおかれます - Mercurial の場合は,working copy 直下の
.hg
のみが管理用フォルダです - SVK については,あえて一般的と思われる local copy を作る方式を記載しました*1
- mirror repository から直接 checkout する方法もあります(⇒ http://coderepos.org/share/wiki/FAQ/svk)。この場合,ユーザの使用感としては
svn
を使う感覚でupdate
/commit
するだけですむようです*2 *3。
- mirror repository から直接 checkout する方法もあります(⇒ http://coderepos.org/share/wiki/FAQ/svk)。この場合,ユーザの使用感としては
Subversion (SVK) ユーザのための Mercurial
SCM はどのソフトウェアもだいたい同じようなコマンドラインをうけつけるようになっています。しかし hg
には svn
(svk
) と異なるいくつかの注意すべき点があります。
checkout
(co
) の代わりにclone
- ただし
svn co
と違って,レポジトリ全体(全履歴)を取得します(上記参照) svk copy //REPO1 //REPO2
もhg clone REPO1 REPO2
checkout
自身はupdate
のエイリアスになっています
- ただし
import
はパッチセットをインポートするためのコマンドになっている- しいていうなら
addremove
を初回に実行するとその代わりになります
- しいていうなら
svk
push
/pull
は同様にhg
push
/pull
- ただし
svk push -C
の代わりにhg out
- ただし
HEAD
に近いキーワードはtip
。ただしコンテキストによって意味が変わるのでparents
のほうをよく使うかも。- Mercurial は空ディレクトリを管理対象に含めることができない - daily dayflower
ほか,似ているところ,違うところなど。
- リビジョン管理は Subversion とおなじように(そして CVS と異なり)「チェンジセット」ベース
- 無視ファイルの指定は
svn:ignore
プロパティの代わりに .hgignore というファイルを使う - 「複数ヘッド」に気をつけろ
- conflict が発生した場合にマージをしなければならない(これは Subversion とかでもそうだけど)が,conflict が起きているかどうか,ということを知る方法が Subversion ユーザにとって*4直感的ではない
- 上記「複数ヘッド」がからんできます
詳しくはいつか書く- Mercurial 勉強中 (5) - conflict と multiple heads, merge - daily dayflower
- Subversion レポジトリをマスターレポジトリとして扱うためには hgsvn がある
- ⇒ Mercurial から Subversion リポジトリにコミットする - ursmの日記
- いつか書く
- これで CodeRepos 利用者もあんしん?
push
はまだ怖い気もするけどね……*5 - 標準機能だけで import も一応できる⇒ Mercurial の Subversion convert extension - daily dayflower
hg clone A B と cp -R A B はどう違うのか
hg clone の場合,レポジトリのコピー元に関する情報が記載されます。((実はこのように一段 clone するだけだと clone 元の default path と同じになるので cp -R
したときと等価になります。しかし複数段 clone した場合には直 clone 元が default path になるという違いがでてきます。))
% ( mkdir hello && cd hello && hg init ) % hg clone hello my-hello % cd my-hello % cat .hg/hgrc [paths] default = /home/dayflower/src/hello
ですので,hg push | pull | outgoing | incoming
等で対象となるレポジトリを省略した場合,コピー元(親)のレポジトリが対象となります。
% touch a.txt % hg addremove adding a.txt % hg ci -m "a.txt を追加した" % hg out # ← 対象レポジトリを指定する必要がないことに注目 searching for changes changeset: 1:b4c9e5d06c5f tag: tip user: dayflower date: Thu Feb 28 13:35:43 2008 +0900 summary: a.txt を追加した
hg out
(going
) というのは,もし hg push
した場合に,どの changeset が送信されるか調べるコマンドです。反対に hg pull
する前に使うと便利な hg in
(coming
) というコマンドもあります。ま,それは本筋の話ではなくて,default path が適切に設定されていると,hg push
等する際に,対象を指定する必要がないよ,ということです(svk と同じですね)。
また,hg clone
の場合 cp -R
と違って,同じファイルシステムにレポジトリが存在する際にレポジトリ内の履歴ファイルはハードリンクになります。
% ls -li .hg/store/data/ total 4 231234 -rw-r--r-- 1 dayflower users 64 Feb 28 10:00 a.txt.i % ls -li ../hello/.hg/store/data/ total 4 231234 -rw-r--r-- 1 dayflower users 64 Feb 28 10:00 a.txt.i
くわしくは hg help clone
を参照してください。
*1:図では簡略化して書いてありますが,実際には Mirrored Master や Local copy はローカルマシン上に Subversion レポジトリを構成してそこに入れ込んであるイメージです。ほか色々ややこしい説明は ⇒ svk によるレポジトリ分割の作業記録 - daily dayflower
*2:なので上の図はちょっと不公平ですよね
*3:でも分散…というかミラーリングすることの旨味が減るような
*4:少なくともわたしにとって
*5:プロパティとかどうなるのかまだ検証していません