Mac
Mercurial
bitbucket
hg

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

1*Hj82rzxZQqZQe0PKYgcmOQ.jpeg

Image courtesy of 4Gamer

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

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

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

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

  • セーブポイント → リポジトリ
  • セーブする → コミットする
  • ロードする → アップデートする
  • プレイデータ → チェンジセット

macOS (OS X) の準備

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

Mercurialのインストール

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

1*AHGg_HIhIlPA31gwAJL9zw.png

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

1*eVypoFxGvbndWf1kS89WuQ.png

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

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

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

1*iEV2Xwo80eijSBFhJ1v6jA.png

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

1*ErsMDH4Hu3vW7PX43lY6Gg.png

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

バージョン管理の準備

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

1*WgKizEnXZ0CEPZ4-3aiX8g.png

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

1*CsNespkeYHh3acg7GwIoDA-2.png

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

1*qiMFeBP_VVfsUDJdE6wclQ-2.png

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

バージョン管理の第一歩

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

1*fprvUp90kQhlduNdo5tbpQ.png

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

1*2f-FRF0YgB93iX68etupDQ-2.png

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

1*pMjRymcMUBvp5HjaE3YQHA.png

すると,

? spec.txt

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

1*zXSnt-8ZgRHyAXbWqOFUaA.png

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

1*2LAouYiGSgxhMZrz4s6uvA.png

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

A spec.txt

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

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

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

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

1*lVau8GsaYJG1FLvZQiybEw-2.png

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

1*pO_Bl_5anDWvSG-Xoy7dxw.png

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

1*V4QX17GdqHlXq0uYXITHFg.png

今度は

M spec.txt

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

1*MQK-uL_Y53b-Hbf3_6s-1Q-2.png

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

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

1*QqPR9eJsi-TP3np7xDHfjQ-2.png

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

1*0sVCmdF8N0qxFqMlkk5Igw-2.png

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

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

古いデータを取り出す

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

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

1*KFUR1yZqSPmfvfvh4J7gEA-2.png

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

1*wMTNeHosMcR4NBjKFcruLw-2.png

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

1*oZcQYdQBHeotmc9jFO_kjQ.png

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

平行宇宙へ行く

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

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

1*CWagAAeWdwetl-WvtlZLEw.png

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

1*2UEHFgl5sfLfbMVt5O9aHA.png

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

1*Kffm_mN3rOBX8AZfw1rV4Q.png

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

1*5-Wx2bByk3ejBXauWiQpmA.png

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

1*V4QX17GdqHlXq0uYXITHFg-2.png

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

M spec.txt

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

1*Pm5NUnnbxweHDs_s3mz5wQ.png

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

created new head

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

1*KdWrSIK5TZP6RytKHxU5-g.png

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

1*Dq1bmODh4uBMYcJO7eDW8g-2.png

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

1*obPPD_ULKCL9DZcMSaDAlg.png

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

1*5a4MLZATzpzbE-sAnQTmAg.png
1*_G5xlGlmeUKFfUq4HogCbw.png

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

1*S8svn557fx-adFtNX7v6ug.png

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

あといくつかのコマンド

バイオハザードでは必要ないが,あといくつかの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番目からを実行すれば良い.とだけ書くと不親切なので,順を追って説明しよう.なお以下の手順は将来変わるかもしれないので,参考程度にしてもらいたい.

  1. Bitbucketにログインする.
  2. Repositoriesメニューから Create repository サブメニューを選ぶ.
  3. “Create a new repository” という画面になったら “Repository name” 項目に “Hello” と入力し “Repository type” を “Mercurial” にする.他はそのままでよい.念のため “Access level” の項目 “This is a private repository” にチェックが入っているか確認しよう.
  4. “Create repository” ボタンを押す.
  5. ターミナルでHelloディレクトリに移動し hg push https://{Bitbucketユーザ名}@bitbucket.org/{Bitbucketユーザ名}/Hello とする.途中パスワードを聞かれるので,Bitbucketで設定したパスワードを打ち込もう.(Bitbucketはリポジトリ名の大文字を小文字へ変換してしまうのでHelloはhelloでも構わない.)うまくいくと次のような画面になるだろう.
  6. 最後にBitbucketのサイトに正しく保存されているか確認しよう.これには https://bitbucket.org/{Bitbucketユーザ名}/hello へアクセスすればよい.画面右手の “Recent activity” にメモ(コミットメッセージ)が並んでいれば成功だ.
  7. あとは定期的に 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になってしまうが,手動でhelloをHelloに変えておいても問題はない.

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


元記事はこちら.