Mercurial基礎最速マスター -初期設定・基本編-

タイトルはついったー上でみんながこれつけろって言われたので…w
というわけで最速マスターとなるかどうかはわかりませんが入門Mercurial Linux/Windows対応の復習も兼ねてまとめようと思います。
ちなみにインストール方法ではGUIツールのインストール方法も紹介しますが、GUIによる操作の説明はなくコマンドに関してのみの記事となっております。また、主に参考にしている本にはMacに関する記載がなく、僕もMac環境がありませんのでMacに関する説明は少なめとなっておりますこともご了承下さい。


追記:
2010/03/11
 FreeBSDでのインストールについて(ついったーにてご指摘頂きました)
 基礎文法最速マスターから基礎最速マスターへw
2010/03/11
 マージツールの設定にTortoiseHgの場合を追加(コメントより)
 branchの説明を修正(コメントより)
2010/03/15
 addのキャンセルについて

インストール

公式サイト: http://mercurial.selenic.com/wiki/
上記の公式サイトのLatestNews欄に最新のものから順にのっていますので、何か理由がない限りは最新日付のdownloadをクリックして頂ければ、各パッケージの一覧ページにいけますのでそちらからソースまたはバイナリをダウンロードして下さい。
Linuxなどでは後述しますがコマンドよるインストールも可能です。

Windows

Windows環境の場合は主にTortoiseHg・バイナリ(GUIなしのコマンドのみ)・Cygwinの3通りの方法があります。TortoiseHgとバイナリの違いはGUIがあるかどうかだけなので、GUIが必要な方はTortoiseHgをインストールして下さい。

TortoiseHG
パッケージ一覧のWindowsのところに「TortoiseHg」というリンクがありますのでそちらからダウンロードし、インストーラーの指示にしたがってインストールして下さい。ちなみにコマンドライン用のパス通しも設定をはずさなければ自動でしてくれます。
バイナリ
同じくパッケージ一覧のWindowsのところの「Mercurial-x.x installer without TortoiseHg」の「Mercurial-x.x」からダウンロードし、インストーラーの指示したがってインストールして下さい。こちらも同じくパス通しはしてくれます。
Cygwin
Setup.exeより「Devel」または「Python」に分類されておりますのでそちらからインストールして下さい。
Mac

すみません、環境もありませんし調べていませんのでわかりませんorz
ひとまず公式にバイナリがありますのでそちらからインストールできるのではないでしょうか。あと、フロントエンドとしてこのようなツールがあるようです。
Mac OSX向けのシンプルなMercurialフロントエンド·MacMercurial MOONGIFT

UNIX/Linux

公式のバイナリまたは下記の各種コマンドにてインストール可能です。念の為、各環境のアップデートを事前に行うようお願いいたします。

# FreeBSD環境
$ cd /usr/ports/devel/mercurial
$ make 
$ make install

# yum環境
$ sudo yum install mercurial

# apt-get環境
$ sudo apt-get install mercurial

またはeasy_install*1によるインストールも可能です。

$ sudo easy_install Mercurial

あと、ビルドする方法もありますがやったことないので割愛。

初期設定

設定ファイルの場所

実際には設定ファイルは複数の箇所に設置でき、読み込まれる順番などがあるのですが最小設定をということで基本となる設置場所のみを紹介させて頂きます。

Windows
環境変数$HOME/.hgrc
UNIX/Linux/OS X
ユーザホーム/.hgrc
必要最低限の設定

記述方法は [セクション名] によるセクションの宣言と 名前 = 値 とで記述します。ちなみに=前後の空白は無視されます。設定ファイルについての詳細な説明はまた後日に別記事で書こうと思いますので、わかりにくいところありますがご了承下さい。

■ユーザ名(設定した値がそのまま表示されるだけですのでチーム内でルールを決めるなどして下さい。下記は一例です。)

[ui]
username = akineko <akineko@mail.address>


■マージツールの設定

diff3の設定

[ui]
merge = diff3
[merge-tools]
diff3.args = -m $local $base $other > $output

GNU diff3の設定

[ui]
merge = diff3
[merge-tools]
diff3.args = -m -L local -L base -L other $local $base $other > $output

WinMergeの設定

[ui]
merge = winmerge
[extensions]
hgext.extdiff =
[extdiff]
cmd.wmdiff = WinMergeのインストール先/WinMergeU.exe
opts.wmdiff = /r /e /x /ub

TortoiseHgを使用している場合
ある程度の設定が標準されてあり基本的には[ui]セクションのmergeに使用したいツール名を指定するだけでいいそうです。
http://bitbucket.org/tortoisehg/stable/src/tip/contrib/mergetools.rc


簡単に説明するとuiセクションのmergeの値にはマージに使用するコマンドを設定し、merge-toolsセクションにて mergeで設定したコマンド名.args に引数の設定をします。
各使用できる変数の意味は $base(共通リビジョンのファイル) $local(ベースとなるリビジョンのファイル) $other(マージするリビジョンのファイル) $output(結果の出力先のファイル) となります。
WinMergeの設定についてはまだ勉強途中で僕もよくわかってないのでおまじないと思って下さい、すみませんorz


文字コードの設定
ログメッセージやファイル名に日本語を使用する場合に必要です。

環境変数:HGENCODINGを設定する
Windows: cp932
UNIX/Linuxeuc-jp または utf8 (LANGなどに応じて設定して下さい)

また、Windows環境では下記の設定も行ってください。

[extensions]
hgext.win32mbcs =

ただWindowsLinux間などで共有する場合にファイル名の問題があるらしく、ちとまだ情報を全部追いきれてないのでひとまずリンクだけ貼っておいて調べ終わったら修正します。軽く見た感じでは上記のwin32mbcsよりリンク先に書いてあるfixutf8を使えばとりあえずTortoiseHgのGUI以外では問題なさげです。
kuy / thg-ja / wiki / Japanese — Bitbucket


■改行コードの設定
異なる環境での改行コード変換に関する設定です。

Windows環境の改行コードをUNIX/Linuxの改行コードに変換する設定
拡張機能を有効にする

[extensions]
hgext.win32text =

全ファイルを対象とした一括設定

[encode]
** = cleverencode:
[decode]
** = cleverdecode:

拡張子を指定しての設定*2

[encode]
**.c = dumbencode:
**.h = dumbencode:
[decode]
**.c = dubdencode:
**.h = dumbdecode:
管理除外ファイルの設定

■設定ファイルの場所
[ui]
ignore = 除外設定ファイルへのパス
または
リポジトリのルートディクレクトリ/.hgignore


■記述方法
記述方法には Python/Perl正規表現形式 と shellスタイルのワイルドカード形式 の2通りあり、下記のものを記述して宣言します。記述方法の変更は何度でも可能で次の宣言があるまで指定した形式として扱うようになっています。
また、デフォルトは正規表現形式となっています。

ワイルドカード
syntax: glob
正規表現
syntax: regexp


除外ファイルの指定方法一行に1つずつ除外するファイルやフォルダの指定し、行頭に#がある行はコメントとなります。
以下、例。

syntax: glob
*.log
.htaccess
classes

syntax: regexp
.*\.log
\.htaccess
^classes

globだとclassesに一致するフォルダだけでなくファイルも全て含まれるが、regexpなら^でトップディレクトリを指定しているのでclassesフォルダだけが除外される。

各種コマンド

各コマンドのオプションなど詳細についてはよく利用するもののみを紹介といった感じで省略させて頂きますのでご了承下さい。詳細についてはまた後日に別記事にて書きたいと思います。

リポジトリの作成

■ hg init
既存ディレクトリをリポジトリ化する場合はそのディレクトリをカレントディレクトリとして、

$ cd hgrepo
$ hg init

リポジトリとするディレクトリを作成しリポジトリ化する場合はディレクトリ名を指定します。

$ hg init hgrepo
基本ファイル管理

■作業領域の状態表示 hg status
作業領域のファイルが変更されているのかや管理下に追加されているのかなどの状態を表示します。
下記がコマンドの実行例と主な表示の意味です。

$ hg status

? index.html    管理下にないファイル
A src/foo.jsp   管理下に追加されたファイル
M src/bar.jsp   変更があったファイル
! src/buzz.jsp  hg removeコマンド以外による方法で削除されたなど存在しないファイル

? はaddしないとバージョン管理されませんし、! は必要ならなんらかの形で復元するかremoveしないとコミットできませんのでご注意を。


■管理下へ追加 hg add
バージョン管理されるように管理下に追加します。statusでも書きました通りこのコマンドでファイルを管理下に追加しないとバージョン管理されません。また、addしたもののキャンセルはrevertで行えます。

全てのファイルを追加
$ hg add
ファイルを指定して追加(ディレクトリを指定した場合は指定ディレクトリ以下のファイル全て)
$ hg add foo.py
addしたfoo.pyをrevertでキャンセル
$ hg revert foo.py


■管理下から削除 hg remove
管理下から削除し、ファイル自体も削除されます。あくまでコミットした以降のリビジョンでは管理しないように削除するだけですので、削除したという履歴は残りますしそのファイルが存在したリビジョンに戻れば復元されます。

$ hg remove


■ファイルのコピー hg copy
ファイルのコピーだけで元ファイルの管理履歴までコピーされるわけではありませんのでご注意を。

foo.cをbar.cとしてコピー
$ hg copy foo.c bar.c


■ファイルのリネーム hg rename
ファイルをリネームしますが内部処理としては hg copy → 元ファイルをhg removeですのでリネーム前の履歴はなくなってしまいます。ですがリネームしたという履歴は残りますしhg annotateでもオプションを指定すれば履歴を見ることは可能です。

fizz.cppをbuzz.cppにリネーム
$ hg rename fizz.cpp buzz.cpp


■変更の取り消し hg revert
指定したファイルを親リビジョンの状態へ戻します。また、オプションによりリビジョンを指定すれば指定リビジョンの状態へ指定ファイルだけを戻すことが可能です。


-a : 全てのファイルを対象とする
-r : 指定リビジョンの状態へ復元する

foo.cppを親リビジョンの状態に戻します
$ hg revert foo.cpp
コミット

■コミット hg commit
成果物の反映です。このコマンドを実行してリビジョンを作成するまではバージョン管理されませんのであしからず。また、addしていないファイルは反映されませんのでご注意を。

メッセージを指定してのコミット
$ hg commit -m 'コミットメッセージ'

メッセージを記述したファイルを指定してのコミット
$ hg commit -l message.txt

ファイルにより長文のメッセージを指定できますが、後述のlogコマンドなどにて表示されるコミットメッセージには詳細表示のオプションを指定しない限り、一行目のみが表示されますのでご注意ください。


■直前のリポジトリ操作の取り消し hg rollback
直前に行った commit・pull・import・unbundle などのリポジトリに成果を反映する操作を取り消します。あくまで直前の操作のみなので2回連続して実行しても2回目は無効となりますのでご注意を。

$ hg commit -m 'rollback test'

直前のコミットを取り消し
$ hg rollback
rolling back last transaction

$ hg rollback
no rollback information available
↑取り消しは直前の1回のみなので失敗のメッセージ
情報表示系コマンド

■作業領域の変更内容の表示 hg diff
まだコミットしていない作業領域の変更状態を表示します。


-r : 指定リビジョンからの変更内容を表示

piyo.txtを作成し適当に文字を入力して変更状態を表示
$ hg diff

diff -r a4efc684ef5b piyo.txt
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/piyo.txt  Thu Mar 11 01:36:43 2010 +0900
@@ -0,0 +1,2 @@
+piyopiyo
+test


■ファイルの変更履歴を行単位で表示 hg annotate
ファイルの各行がどのリビジョンで変更または追加されたのかが表示されます。

index.htmlの変更履歴を表示
$ hg annotate index.html
1: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
0: <html lang="ja">
0:     <head>
0:        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
1:        <link rel="index" href="./index.html">
5:        <link rel="stylesheet" type="text/css" href="./index.css">
0:        <title>Akinekoの日記</title>
0:    </head>
...


■リビジョンの履歴表示 hg log
リポジトリの履歴が表示されます。主に使用するオプションは下記の通りです。特に表示件数のオプションは指定しないと全履歴が表示されますのでほぼ必須ですね。


ファイル名を指定 : そのファイルが変更された履歴を表示

-r : リビジョンの指定。
-l : 最大表示数の指定。
-p : 詳細情報を表示。各ファイルの変更履歴やコミットメッセージの全文が表示されます。

最大表示数5で履歴表示
$ hg log -l 5

changeset:  0:a4320f371f33
tag:        tip
user:       akineko@home <akineko@mail>
date:       Thu Jan 14 01:01:36 2010 +0900
summary:    init


■親リビジョンの表示 hg parents
現在の作業領域の親として参照しているリビジョンの情報を表示します。

$ hg parents
changeset:  0:a4320f371f33
tag:        tip
user:       akineko@home <akineko@mail>
date:       Thu Jan 14 01:01:36 2010 +0900
summary:    init


■最後に取り込まれたリビジョンの状態表示 hg tip
tipはリポジトリに最後に取り込まれたリビジョンに自動で付与されるタグです。最後に取り込まれたリビジョンですので他リポジトリからの成果を反映した際に、その成果が古い場合でもそちらにtipタグがつきますのでご注意下さい。

$ hg tip

changeset:   13:a4efc684ef5b
branch:      release-line
tag:         tip
parent:      11:127a74430cbf
user:        akineko
date:        Wed Mar 10 23:40:56 2010 +0900
summary:     branch
親リビジョンの変更

■親リビジョンの変更 hg update
指定したリビジョンの状態を作業領域に復元します。ファイルの変更やaddされたファイルが存在する場合は失敗しますのでcommitするか、その変更が必要ないのでしたら下記の強制オプションを指定して下さい。*3


-C : 強制実行する

リビジョン番号3の状態を復元する(リビジョンの指定はハッシュIDでも可)
$ hg update 3
タグ

■タグ付け hg tag
指定リビジョンにタグを付けます。また、このコマンドを実行するとタグを付けたというリビジョンが作成されます。
オプションは下記の通りとなります。


-r : リビジョン指定。(省略した場合は現在参照しているリビジョン)
-l : 他リポジトリには反映されないローカルタグを作成する。

リビジョン3にrelease1.0というタグを付ける
$ hg tag -r 3 release1.0


■タグの一覧表示 hg tags

$ hg tags

tip                                9:0d7442f1412c
release2.0                         8:09d1837a9d9c
release1.1                         6:64895f3c7ac0
release1.0                         3:ec83496189fa
分岐

■ブランチの作成 hg branch
親リビジョンを分岐点として指定した名前のブランチを作成します。このコマンドは実行後にコミットまたはタグ付けによって新しいリビジョンを作成しないと反映されませんのご注意ください。

release-lineという名前のブランチを作成
$ hg branch release-line

release-line-baseというタグを作成して新規リビジョンを作成しbranchコマンドを反映
$ hg tag release-line-base


■ブランチの一覧表示 hg branches
ブランチの一覧をヘッドとなるリビジョンの情報と共に表示します。

$ hg branches

release-line                  13:a4efc684ef5b
default                       12:3da82a8cb523
マージ

■ヘッドとなるリビジョンの表示 hg heads
ヘッドとは子を持たないリビジョン、つまりブランチや他リポジトリの成果によって枝分かれした各枝の最新のリビジョンの事をさします。

$ hg heads

changeset:   10:0d7442f1412c
tag:         tip
user:        akineko
date:        Wed Mar 10 22:38:46 2010 +0900
summary:     Added tag release2.0 for changeset 09d1837a9d9c

changeset:   7:0dcfb46baa73
user:        akineko_sub
date:        Wed Mar 10 22:59:10 2010 +0900
summary:     Added tag SubHead for changeset 64895f3c7ac0


■マージ hg merge
親リビジョンに指定リビジョンをマージします。


-r : リビジョン指定。ヘッドが2つしかない場合は省略可

$ hg heads

changeset:   10:0d7442f1412c
tag:         tip
user:        akineko
date:        Wed Mar 10 22:38:46 2010 +0900
summary:     Added tag release2.0 for changeset 09d1837a9d9c

changeset:   7:0dcfb46baa73
user:        akineko_sub
date:        Wed Mar 10 22:59:10 2010 +0900
summary:     Added tag SubHead for changeset 64895f3c7ac0

マージ。ヘッドが2つなのでリビジョン指定は省略
$ hg merge


■衝突状態の表示・変更 hg resolve
マージによって発生した衝突の状態を表示、または解決・未解決の報告をします。


-l : 衝突が発生しているファイルの一覧を表示。 U:未解決 R:解決済
-m : 指定ファイルを解決済へ
-u : 指定ファイルを未解決へ

状態表示
$ hg resolve -l
U piyo.py

piyo.pyを解決済みへ
$ hg resolve -m piyo.py

$ hg resolve -l
R piyo.py
過去のリビジョンの取り消し hg backout

■過去のリビジョンの取り消し hg backout
指定したリビジョンの成果を打ち消すリビジョンを作成します。作成されるリビジョンは指定したリビジョンから分岐して作成されますのでマージ作業が必要となりますのでご注意ください。


-m : 作成するリビジョンのコミットメッセージ

リビジョン3の成果を打ち消すリビジョンの作成
$ hg backout -m 'バグ原因リビジョンの成果を除外' 3
リポジトリとの連携(ネットワーク形式)

分類としてはネットワーク形式にしましたが、これらのコマンドはネットワークを介さずに作業PC内でも相対パス絶対パスを指定して使用できます。またSSHについての詳細は後述いたしますのでそちらをご参照下さい。


リポジトリの複製 hg clone

ネットワーク上のhgrepoリポジトリを複製してmyworkリポジトリの作成
$ hg clone ssh://user@server/etc/hgrepo mywork


■他リポジトリから成果の取り込み hg pull
リポジトリに指定したリポジトリの成果を取り込みます。指定リポジトリに更新があった場合は分岐が発生しマージ作業が必要となります。また、リポジトリに成果を反映させるだけですのでhg updateしないと作業領域は最新のものになりませんのでご注意をください。
また、反映先の指定ですがcloneコマンドにて複製されたリポジトリは、複製元へのパスを設定ファイルにデフォルトとして自動的に保存されますので、複製元に反映させたい場合は省略する事が可能です(pushも同様)。上記のcloneの例ですとmyworkからhgrepoへは省略可能となります。ただし、その逆は不可ですのでご注意ください。

hgrepoから成果の取り込み
$ hg pull ssh://user@server/etc/hgrepo


■他リポジトリへ成果の反映 hg push
指定リポジトリへ自リポジトリの成果を反映させます。これも同様に作業領域はそのままですので成果を反映させたリポジトリにてhg updateしないと作業領域のファイルは最新のものになりませんのでご注意ください。
指定リポジトリに更新があった場合はエラーメッセージが表示されpushできませんので、pull→マージ作業後に再度pushして下さい。

hgrepoへ成果の反映(cloneの例のmyworkからhgrepoへと仮定して省略)
$ hg push
リポジトリとの連携(ファイル形式)

主にネットワークを介する事が出来ない場合に使用します。テキストベースとバイナリベースの違いは細かい説明をはぶきますとバイナリデータを扱えるかどうかです。というかbundle・unbundleはファイルによるpush・pullだと思って頂ければいいかと。


■テキストベースのリポジトリの出力 hg export
指定したリビジョンの変更内容を出力します。リビジョンの指定は半角スペース区切りで複数指定することが可能です。
また、-o省略時はコンソールに表示されますのでご注意ください。


-o : 出力先の指定

リビジョン2と7の情報を出力
$ hg export -o ../export.%h 2 7
%hはハッシュIDに置換されます


■テキストベースのリポジトリの入力 hg import
exportで生成されたファイルを指定してリポジトリに取り込みます。内部処理的には作業領域をexportファイルの状態へ→commitが行われます。

ecportfileの内容を取り込む
$ hg import exportfile


■バイナリベースのリポジトリの出力 hg bundle
バイナリデータも含めた変更内容を出力します。

-a : 全てのリビジョンを含める
-r : 指定リビジョンを含める
--base : 指定したリビジョン以降の情報を含めます

全てのリビジョンをbundle.allに出力
$ hg bundle -a bundle.all

リビジョン2をbundle.twoに出力
$ hg bundle -r 2 bundle.two

リビジョン3以降のリビジョンをbundle.threeAfterに出力
$ hg bundle --base 3 bundle.threeAfter

リポジトリhgrepoに含まれていないリビジョンをbundle.hgrepoに出力
$ hg bundle bundle.hgrepo ssh://user@server//etc/hgrepo


■バイナリベースのリポジトリの入力 hg unbundle
bundleで出力されたファイルの情報をリポジトリに取り込みます。

bundleの例のリビジョン2のファイルを取り込む
$ hg unbundle bundle.two
成果物の出力

アーカイブ形式にて出力 hg archive
現在のリポジトリの内容をMercurialの管理ファイル.hg以下のファイルや管理下から除外されているファイルなど、不要なものを自動的に取り除いて指定先に一括出力します。


-r : リビジョン指定
-t : 出力形式(files:無圧縮 tar tgz zip などなど)

リビジョン2の状態を~/hoge.tgzとして出力
$ hg archive -r 2 -t tgz ~/%h.tgz
↑%hは指定リビジョンのハッシュIDに置換されます。


■ファイル内容の出力 hg cat
特定ファイルの内容を出力します。-oオプションを指定しないとコンソールに表示されるだけなのでご注意ください。


-r : リビジョン指定
-o : 内容を出力する保存ファイル名

ハッシュID a4320f371f33 リビジョンのhoge.javaの内容を出力
$ hg cat -r a4320f371f33 -o /tmp/%p hoge.java
↑%pはリポジトリのルートからの相対パスで置換してくれます。
リポジトリルート/foo/hoge.java にあるのなら /tmp/foo/hoge.java として出力されます。

SSHについて

設定

UNIX/Linux環境ですとsshコマンドさえ使えるようになっていれば特に設定も必要ありませんが、Windows環境の場合ですとsshコマンドはありませんので設定が必要となります。設定は簡単で設定ファイルにsshに使用するプログラムや引数を指定するだけでOKです。
以下はPuTTYコマンドライン版であるplink.exeを使用する場合の設定です。plink.exeへの絶対パスに空白が含まれますと設定できませんのでご注意ください。

[ui]
ssh = plink.exeのあるディレクトリへの絶対パス\plink.exe -ssh -i "秘密鍵への絶対パス"
表記
ssh://user@server/path

上記の例を順番に説明しますと、
user : リポジトリのあるサーバーに接続するユーザ名
server : ドメインIPアドレスなどサーバーへのアドレス。アドレスの後ろに:80などのようにポートを指定することも可能です。
path : リポジトリとなるディレクトリへの絶対パス、または接続したユーザのホームからの相対パスです。絶対パスにて指定する場合は/からはじめること、つまり ssh://user@server//etc/hgrepo のように / が2つ重なることにご注意ください。




といった感じで以上が初期設定と主に使用すると思われるコマンドとそのオプションなどです。
タイトルに反して最速マスターではありませんね…orz
実際の作業の流れや詳細な説明、応用的な使い方・考え方などはまた後日に別記事で書きたいと思いますのであてにせずにお待ちくださいw

Git

Mercurialなんて興味ねぇんだよ!俺はGitが知りたいんだよ!って方は id:bleis-tift さんによるこちらをどうぞ!
Git 基礎最速マスター - ぐるぐる~

*1:easy_installとは

*2:PDFファイルなど改行コードが変換されては困るファイルがある場合などに使用

*3:強制的にupdateするので当然変更したファイルの情報は失われます。