個人で簡単に使える分散バージョン管理ツール Mercurial
先日の Trac で OpenID を使う際に、必要に迫られて Mercurial というバージョン管理ツールをインストールした。 正直なところ、バージョン管理には Subversion があるし、「分散」バージョン管理ツールなんて複雑で面倒なだけだろうと思っていた。 でも、ちょっと使ってみたら大間違い。むしろ「分散」なんて意識せずに個人で使うにはとっても向いているんじゃないか。 個人で分散バージョン管理ツールを使うべき理由はこんな感じかな。
- 「リポジトリ」へのチェックイン、チェックアウトという概念がない。
- わざわざワークスペースを別に用意しなくていい。
- 作業しているディレクトリをそのままバージョン管理ツールで管理できる。
- ネットワークに繋がっていなくてもdiffを確認できる。
- CGIスクリプトを設置すればレンタルサーバと連携できる(設置にはシェルが必要らしい)
- WebDAV と違ってHTTPプロキシとの親和性がいい(PROPFINDなどのメソッドをサポートしていなくてもOK)
考えてみれば、 CVS や Subversion は中央にリポジトリを置くモデルなので、 svn-admin で領域を作って、ソースをインポートして、そこからチェックアウトして、と1人で使う分には最初のセットアップがちょっと面倒。 でも、分散バージョン管理ツールの場合はそれぞれのマシンがリポジトリになれる。 ということは、別に他のマシンと連携しなくても、そのマシンだけで完結しているというメリットがあること。
これは使わざるを得ない。 って訳で、一人で使う分で必要になる操作を簡単にまとめてみたよ。 構成は、結城さんのSubversionの基礎練習を参考にさせてもらった。
インストール
Mercurial の公式サイトに Windows 用、 Mac 用、 Debian, Ubuntu, RedHat のそれぞれのバイナリパッケージが置いてあるので、それを入れるだけでOK。
バージョン管理するファイルの作成
まずはバージョン管理したいディレクトリを作って、その中にファイルを追加する。 今回は test1.txt, test2.txt とした。
$ mkdir hgtest $ cd hgtest $ vi test1.txt $ vi test2.txt $ ls test1.txt test2.txt
リポジトリの作成
Subversion が svn というコマンドを使うように、 Mercurial は hg というコマンドを使う。 管理したいディレクトリに移動して、 init コマンドを発行するだけで OK 。 Subversion の svn-admin create と import を同時にやっているような感じ。
$ hg init
これで、カレントディレクトリに .hg ディレクトリが作成され、このディレクトリが Mercurial の管理下に入る。 hg stat で管理状態が確認できる。まだファイルを追加していないので「?」が表示される。
$ hg stat ? test1.txt ? test2.txt
add コマンドでファイルを追加し commit コマンドでリポジトリへ反映する。
$ hg add * $ hg commit -m 'first import'
この辺は Subversion と同じだなぁ。 面倒なインポートやチェックアウトが無く、作業中のディレクトリをそのまま管理対象にできるので Subversion より最初の敷居が低い。
管理用の .hg というディレクトリが作られている。Subversion と違ってトップのディレクトリのみに作られるっぽい。
$ ls .hg 00changelog.i requires undo.branch dirstate store/ undo.dirstate
ファイルの差分を確認する
追加したファイルを変更してみる。
$ vi test1.txt
hg diff で差分をみることができる。
diff -r 3b701cee8925 test1.txt --- a/test1.txt Wed Mar 12 01:31:25 2008 +0900 +++ b/test1.txt Wed Mar 12 01:36:26 2008 +0900 @@ -1,1 +1,1 @@ -hello mercurial +good night...
変更内容を戻す場合は revert が使える。 revert すると変更中のファイルが .orig として残る。 うっかり revert して作業中のファイルを消した人には助かる機能。
$ hg revert test1.txt $ ls test1.txt test1.txt.orig test2.txt
あと、ファイルを消した場合は hg update で復活(最後にコミットした状態で)。
コミットと履歴の確認
変更点をコミットしてコミットログを表示。
$ hg commit -m 'test1.txt: hello to good night' $ hg log changeset: 1:bd8bcd244b94 tag: tip user: machu@macbook.local date: Wed Mar 12 01:37:00 2008 +0900 summary: test1.txt: hello to good night changeset: 0:3b701cee8925 user: machu@macbook.local date: Wed Mar 12 01:31:25 2008 +0900 summary: first commit
Subversion と違ってリポジトリが手元にあるので、コミットしたリビジョンの diff も簡単に確認できる。
$ hg diff -r 0:1 diff -r 3b701cee8925 -r bd8bcd244b94 test1.txt --- a/test1.txt Wed Mar 12 01:31:25 2008 +0900 +++ b/test1.txt Wed Mar 12 01:37:00 2008 +0900 @@ -1,1 +1,1 @@ -hello mercurial +good night...
ファイル名の変更
ファイル名の変更は rename 。svn move と同じかな。
$ hg rename test1.txt test3.txt $ hg stat M test1.txt.orig A test3.txt R test1.txt
でも commit したら前のファイルも .orig として残った。
$ hg commit -m 'rename test1.txt to test3.txt' $ ls test1.txt.orig test2.txt test3.txt
ヘルプをみたら copy + remove と書いてあった。
rename rename files; equivalent of copy + remove
HTTP サーバ
serve コマンドで HTTP サーバが起動する。
$ hg serve
デフォルトポートは8000番。変えたい時は --port オプションで指定できる。
$ hg serve --port 8080
リポジトリの削除
トップディレクトリにある .hg ディレクトリを丸ごと消せば、何事もなかったかのようにバージョン管理していない状態に戻る。
その他のコマンド
その他のコマンド類は help で確認できる。
$ hg help Mercurial Distributed SCM list of commands: add add the specified files on the next commit addremove add all new files, delete all missing files annotate show changeset information per file line archive create unversioned archive of a repository revision backout reverse effect of earlier changeset bisect subdivision search of changesets branch set or show the current branch name branches list repository named branches bundle create a changegroup file cat output the current or given revision of files clone make a copy of an existing repository commit commit the specified files or all outstanding changes copy mark files as copied for the next commit diff diff repository (or selected files) export dump the header and diffs for one or more changesets grep search for a pattern in specified files and revisions heads show current repository heads or show branch heads help show help for a command, extension, or list of commands identify identify the working copy or specified revision import import an ordered set of patches incoming show new changesets found in source init create a new repository in the given directory locate locate files matching specific patterns log show revision history of entire repository or files manifest output the current or given revision of the project manifest merge merge working directory with another revision outgoing show changesets not found in destination parents show the parents of the working dir or revision paths show definition of symbolic path names pull pull changes from the specified source push push changes to the specified destination recover roll back an interrupted transaction remove remove the specified files on the next commit rename rename files; equivalent of copy + remove revert restore individual files or dirs to an earlier state rollback roll back the last transaction root print the root (top) of the current working dir serve export the repository via HTTP showconfig show combined config settings from all hgrc files status show changed files in the working directory tag add a tag for the current or given revision tags list repository tags tip show the tip revision unbundle apply one or more changegroup files update update working directory verify verify the integrity of the repository version output version and copyright information
まとめ
「分散」バージョン管理ツールと聞くと、 Subversion などの集中型のバージョン管理ツールよりも難しい印象があったけど、むしろそれよりも分かりやすくて便利。 ブランチやタグや他のリポジトリとの連携は試していないけど、1人で使うだけならそこまで知らなくても十分に使える。 ということで、これまで使っていた個人リポジトリは Subversion から Mercurial へと移行してみようかな。 もちろん、チームで使う場合はこれまで通り Subversion を使うけどね。
はてぶのMercurialタグで関連する情報を調べられる。 こういう珍しい名前だとノイズが入らなくていいね。