Mercurial入門

Ichi Kanaya
Pineapple Blog
Published in
19 min readJan 14, 2016

ゲーム「バイオハザード」シリーズでは,ゲーム中に現れるアイテム「タイプライター」を使ってプレイデータをセーブ(保存)できる.タイプライターは一般的にはセーブポイントと呼ばれるシステムで,それまでのプレイ内容をセーブしておき,あとでそこから再開できるようにするためのシステムだ.

Typewriter (Image courtesy of 4Gamer)

バイオハザードではタイプライターのある場所でしかプレイデータをセーブできず,またセーブ回数も持っているインクリボンの個数までという制限があった.一方で,普段お使いのコンピュータシステムなら,どこでも,無制限に,プレイデータ(作業内容)をセーブできる.

このようなシステムをバージョン管理システム (Version Control System) と呼び,略して VCS と言う.VCS には様々な種類があるが,現在主流なのは Git本稿で解説する Mercurial である.コンピュータエンジニアは Git を強く好む傾向があるが,Git は多機能な反面わかりやすさを犠牲にしている.現在関わっているプロジェクトが全面的に Git を採用しているというような事情がなければ,Mercurial は魅力的な選択肢である.

本稿では OS X (Mac) でのMercurialの使い方に焦点をあてて解説をしてみたい.OS X では SourceTree のようなアプリを使えばコマンドラインに降りることなく Mercurial を使うことができるが,本稿ではコマンドラインで Mercurial を使う.そのために,手前味噌ではあるが「『新しいLinuxの教科書』をMacで実践する」を先に参考にしてもらいたい.

なおMercurial(水銀)の元素記号はHgであるから,Mercurial のことを Hg と呼ぶこともしばしばある.またセーブポイント(バイオハザードのタイプライター)は正しくは「リポジトリ」と呼ぶが,本稿ではセーブポイントと呼び続けることにする.その他,以下のように正式な呼称が対応する.

□セーブポイント → リポジトリ

□セーブする → コミットする

□ロードする → アップデートする

□プレイデータ → チェンジセット

OS X の準備

OS X に開発環境と Homebrew が入っていると便利なので,こちらの記事を参考に Homebrew のインストールまでしておいてもらいたい.

Mercurialのインストール

Homebrew を使ってインストールする.ターミナルから brew install mercurial を実行しよう.

brew install mercurial

これで準備ができた.ターミナルで hg と打って以下のようなメッセージが出て来れば成功だ.

hg

準備の締めくくりに,Mercurial に自分の名前とメールアドレスを教えておいてあげよう.これにはホームディレクトリに .hgrc というファイルを作り,以下のような内容を書いておく.(ここで (at)@ に置き換えてもらいたい.)

[ui]
username = Ichi Kanaya <kanaya(at)pineapple.cc>

と言っても,いきなりエディタでピリオドから始まるファイル名を扱えないので,適当なテキストエディタで上記の内容を書いたらひとまず hgrc.txt という名前でホームディレクトリ (/Users/{ユーザ名}) に保存しよう.どうしてもテキストエディタがない場合はWordでかまわない.保存するときに「書式なし(.txt)」を選び,次に出てくるダイアログの「行末」の部分だけ「改行文字(LF)のみ」に変更して保存してもらいたい.

続けてターミナルで mv hgrc.txt .hgrc としてファイル名を変えよう.

mv hgrc.txt .hgrc

リターンキーを押して何も言われなければ無事ファイル名が変更されている.文句を言われた場合はちゃんと hgrc.txt と書いているか確認しよう.

バージョン管理の準備

バージョン管理したいドキュメントを入れるフォルダを作ろう.ここではホームディレクトリ(僕の場合は /Users/kanaya/ になっている)の下の Documents というフォルダの中に Hello というフォルダを作ることにしよう.Documents ディレクトリは最初からあるので,そこへ cd してから mkdir する.

cd Documents; mkdir Hello

つづいて Hello ディレクトリへ移り hg init する.

cd Hello; hg init

これで Hello ディレクトリにMercurialのセーブポイント(リポジトリ)が組み込まれた.試しに ls -aF してみると .hg という隠しディレクトリがあることがわかる.

ls -aF

この .hg ディレクトリがセーブポイント(リポジトリ)の正体である.ここをいじってしまうとセーブデータが消えてしまうので .hg ディレクトリは触らないようにしよう.逆に言えば,定期的にセーブ(コミット)している限り,他は何をしてもだいたい安全だ.

バージョン管理の第一歩

適当なテキストエディタでテキストファイルを作ってみよう.僕は TextWranglerspec.txt というファイルを作った.(テキスト形式ならWordでも構わないし,後で述べる diff 機能を使わないのであればdocやdocx形式でも構わないのだが,話を簡単にするために TextWrangler を使うという前提で進めさせていただく.)

spec.txt

これを Hello ディレクトリ(フォルダ)に保存する.

ls

この spec.txt をこれからセーブポイント(リポジトリ)にセーブ(コミット)しよう.まずこの spec.txt がいまどんな状態にあるのか Mercurial に問い合わせてみよう.打つのは hg status だ.

hg status

すると,

? spec.txt

と言われる.「spec.txt なんて知りまへんでえ,ぶぅぶぅ」というわけだ.そこで spec.txt がセーブポイント(リポジトリ)へのセーブ(コミット)対象であることを Mercurial に教えてあげよう.具体的には hg add spec.txt とする.

hg add spec.txt

ここでもう一度 hg status をしてみよう.

hg status

今度は spec.txt の状態が「?」ではなく次のように「A」になった.

A spec.txt

この状態では spec.txt はまだセーブ(コミット)されていないので,こんどは Mercurial に「セーブ(コミット)するよ」と伝えないといけない.このときコミットメッセージという短いメモをつけないといけない.今回は最初のセーブ(コミット)なので “The first version.” とメモをつけてみよう.

hg commit -m ‘The first version.’

メモ(コミットメッセージ)は日本語も通るのだが,最初なので格好つけて英語にしておいた.

Ouch!!

ここで -m 以下を省略するとデフォルトのエディタがいきなり立ち上がり,メモ(コミットメッセージ)を書けと迫られる.悪いことにデフォルトのエディタは特別に設定しない限りvimというマニアックなエディタになっている.もし -m 以下をつけ忘れてこのような画面になってしまったら,落ち着いて,まず英語入力モードに切り替えよう.日本語キーボードなら「英数」キーを押すとか,古参 Mac ユーザならコマンド+スペースとか,ともかく英語入力モードにしてくれ.次に冷静に :q! とキーを押してくれ.これでエディタの終了と先ほどの hg commit の影響をキャンセルできる.この後もう一度 hg commit -m ‘The first version.’ からやり直してもらいたい.

さて,もう一度 hg status をしてみると,もはや Mercurial はすることがないので何も言わなくなっていることがわかる.

hg status

ここで spec.txt をちょっと改変してみよう.下の写真のように2行ほど行を追加してみた.

spec.txt

ファイル spec.txt を上書き保存して,ターミナルで hg status を実行してみよう.次のようになるはずだ.

hg status

今度は

M spec.txt

になった.この「M」は「spec.txt は前回のセーブ(コミット)から進んでまっせ」という意味だ.どう進んだかというのも Mercurial は知っている.それを知るのが hg diff という命令だ.次のように hg diff spec.txt と打ち込んでみよう.

hg diff spec.txt

では,この変更もセーブポイント(リポジトリ)にセーブ(コミット)してしまおう.すでに Mercurial は spec.txt がセーブ(コミット)対象だと知っているので,今度は hg add する必要はない.《Gitユーザへの注意: Mercurialでは一度リポジトリに追加したファイルは毎回 add しなくても良い.》

hg commit -m ‘作成者と日時情報を追加’

正しくセーブ(コミット)できた場合 Mercurial は Unix の伝統に従って口をつぐむ.念のため hg status してみても Mercurial は「もうやることあらへんで〜」と何も言わない.

hg status

が,セーブ(コミット)の履歴は残っている.それを確認してみよう.タイプするのは hg log だ.

hg log

セーブ(コミット)した履歴が残っているのがお分かりいただけるだろう.バイオハザードと違って,プレイデータは上書き保存されない.いつでも古いプレイデータを取り出せるのだ.ちなみにプレイデータは正しくはチェンジセットと言う.技術的な話になるが Mercurial は過去のプレイデータとの差分だけを保存しているので,チェンジ(変化)の集合(セット)と呼ぶのだ.

次は古いプレイデータ(チェンジセット)を取り出す方法を見てみよう.

古いデータを取り出す

いま spec.txt に加えた変更がまずかったと気がついたとしよう.今回の例のように行を足しただけならそれほど問題にはならないが,長い文章を推敲してセーブ(コミット)したが,やはり気に入らなくなったということもあるだろう.そんな時には,セーブポイント(リポジトリ)から古いデータを取り戻すことができる.

まず,念のため spec.txt を開いているエディタを閉じておこう.続けて Mercurial に0番のプレイデータ(チェンジセット)を出してくれと伝えよう.こうするには hg update 0 とすればいい.

hg update 0

この状態でエディタで spec.txt を開いてみてくれ.このように最初にセーブ(コミット)した状態に戻っているだろう.

spec.txt

もちろん,2番目のプレイデータ(チェンジセット)も1番として保存されている.それを引き出してみよう.念のためエディタを閉じてから,ターミナルで次のようにしてもらいたい.いまプレイデータ(チェンジセット)の1番(つまり2番目)は最新なので,番号指定は省略できる.

hg update

このようにして,Mercurial を使えば歴史を行ったり来たりできるのだ.

平行宇宙へ行く

タイムマシンで過去に行って過去を書き換えてしまったら,当然異なった未来が訪れるだろう.

いまの spec.txt の状態を過去から未来へという図で表すとこんな感じになる.

いまいちど hg update 0 で最初のプレイデータ(チェンジセット)である0番を呼び戻そう.

hg update 0

これで一旦プレイデータ(チェンジセット)の1番のことは忘れておける.次のような状態だと思って欲しい.

ここで spec.txt を編集して,次のような一文を加えたとしよう.

spec.txt

改めて hg status を見てみよう.

hg status

すると spec.txt が改変されているので,もうお馴染みの

M spec.txt

となっている.これをセーブポイント(リポジトリ)にセーブ(コミット)しよう.もちろん hg commit -m ‘memo’ をすれば良い.やってみよう.

hg commit -m ‘仕様書の概要を追加’

今度は Mercurial から次のようなメッセージが来た.

created new head

これはどういうことかというと,歴史を書き換えてしまったため,次の図のようにプレイデータ(チェンジセット)の履歴が枝分かれしていることを伝えてくれているのだ.

ここで hg log spec.txt としてみると,次のように changeset 2番の parent が0番になっているのがわかる.

hg log spec.txt

ここでまた気が変わって,プレイデータ(チェンジセット)の1番を元に編集を続けたくなったとしよう.もうやり方はお分かりだと思う.スクリーンショットだけ掲載しよう.

hg update 1

ここで spec.txt にまたなにがしかの編集を行い,セーブ(コミット)しよう.

spec.txt
hg status; hg diff spec.txt; hg commit -m ‘要件を三つ書いた’

この結果,プレイデータ(チェンジセット)の履歴は次のようになる.

このように,過去データをロード(チェックアウト)して編集したあとセーブポイント(リポジトリ)へセーブ(コミット)していくことで,平行宇宙を作りつつもお互い行ったり来たりできるようになるのである.

あといくつかのコマンド

バイオハザードでは必要ないが,あといくつかの Mercurial コマンドを覚えておけば役にたつだろう.

hg rename {元ファイル名} {新ファイル名} はファイル名を変更するときに用いる.コマンドラインで mv {元ファイル名} {新ファイル名} とする代わりで,Mercurial を通してファイル名変更をすることで履歴が引き継がれるようにできる.

hg forget {ファイル名}hg add の反対でファイルを Mercurial の管理から外すために使う.管理から外してもファイルはそのまま残る.

hg remove {ファイル名} はファイルの削除をするときに用いる.これは hg forget {ファイル名}rm {ファイル名} を連続して実行するのと同じである.なおファイルは消してもリポジトリには残っており,履歴が遡って消されるわけではない.あと hg add した直後は hg remove できないので hg forget を使おう.

Bitbucketを使ってバックアップをとる

セーブポイント(リポジトリ)を消してしまっては元も子もないので,それをバックアップする方法を書いておこう.

もともと Mercurial は複数のセーブポイント(リポジトリ)を同期させることができるようになっている.これは複数メンバで作業するときに便利なようにだ.この機能は,単にセーブポイント(リポジトリ)のバックアップとしても使える.

バックアップ先は,運用ポリシーが許せば外部サーバにするのが確実だ.万が一Macのディスクごと壊れても,外部サーバが生きていれば復旧できるからだ.僕はバックアップ先として Atlassian が運営する Bitbucket をお勧めしたい.Bitbucket は Mercurial に対応しているし,無料アカウントでもリポジトリを非公開にできるからだ.以下 Bitbucket を使ったバックアップ方法について述べる.

まず Bitbucket で無料アカウントを作成する.Bitbucket アカウント名,パスワードは後々使うので覚えておこう.続けてヘルプページの “Import an existing, unversioned code project to an empty repository” という項目の5番目からを実行すれば良い.とだけ書くと不親切なので,順を追って説明しよう.なお以下の手順は将来変わるかもしれないので,参考程度にしてもらいたい.

(0) Bitbucket にログインする.

(1) Repositories メニューから Create repository サブメニューを選ぶ.

(2) “Create a new repository” という画面になったら “Repository name” 項目に “Hello” と入力し “Repository type” を “Mercurial” にする.他はそのままでよい.次のような画面になっていれば正解だ.念のため “Access level” の項目 “This is a private repository” にチェックが入っているか確認しよう.

Create a new repository

(3) “Create repository” ボタンを押す.

(4) ターミナルで Hello ディレクトリに移動し hg push https://{Bitbucketユーザ名}@bitbucket.org/{Bitbucketユーザ名}/Hello とする.途中パスワードを聞かれるので,Bitbucket で設定したパスワードを打ち込もう.(Bitbucket はリポジトリ名の大文字を小文字へ変換してしまうので Hellohello でも構わない.)

うまくいくと次のような画面になるだろう.

hg push https://{ユーザ名}@bitbucket.org/{ユーザ名}/Hello

(5) 最後に Bitbucket のサイトに正しく保存されているか確認しよう.これには https://bitbucket.org/{Bitbucketユーザ名}/hello へアクセスすればよい.画面右手の “Recent activity” にメモ(コミットメッセージ)が並んでいれば成功だ.

あとは定期的に hg push https://{Bitbucketユーザ名}@bitbucket.org/{Bitbucketユーザ名}/Hello をすればその都度バックアップが取られる.コマンドが長くて面倒な人向けに,デフォルトのバックアップ先(リモートホストと言う)を設定する方法があるのだが,残念ながら .hg/hgrc というテキストファイルを直接いじるか,次の節で述べるように一旦 Bitbucket から復元するかしかない.一応 .hg/hgrc を直接いじりたい人向けに,一番簡単な方法だけ書いておこう.ターミナルで echo “[paths]\ndefault = https://{Bitbucketユーザ名}@bitbucket.org/{Bitbucketユーザ名}/hello” >> .hg/hgrc とするのだ.

【追記】.hg/hgrc を更新するツール hgsetup を作成した.hgsetup はシェルスクリプトなので,自分の作業ディレクトリにコピーした上で chmod +x hgsetup; ./hgsetup ‘{お名前}’ {メールアドレス} {Bitbucketアカウント} {プロジェクト名} と実行してもらいたい.実行後はhgsetupスクリプトを削除して構わない.

Bitbucket からの復元

ディスクがクラッシュした,OS をクリーンインストールした,新しい Mac を買ったなどで,Bitbucket からリポジトリごと復元したい場合はターミナルで hg clone https://{Bitbucketユーザ名}@bitbucket.org/{Bitbucketユーザ名}/hello とする.残念ながらディレクトリ名は Hello ではなく小文字の hello になってしまうが,手動で helloHello に変えておいても問題はない.

なお,この状態でデフォルトのバックアップ先(リモートホスト)が設定されているので,以降バックアップは hg push だけでよい.

--

--