Mercurial チュートリアル hginit.com の和訳 (Ground up Mercurial)

あなたが一人で働いていたとしても、あなたはバージョン管理の恩恵を得るために Mercurial を使うべきである。
このチュートリアルではあなたが古いバージョンを簡単に追跡できるように、どれだけ簡単に Mercurialディレクトリをチェックインできるかを説明する。

Ground up Mercurial

Mercurialバージョン管理システムだ。
開発者はソースコードの管理のためにこれを使う。
そして2つの重要な目的を果たす。  

  1. 全てのファイルの全ての古いバージョンを追跡し続ける
  2. あなたのコードの異なるバージョン間でマージを可能にし、その結果としてチームメイトが独立してコードに取り組めるようにし、 時には彼らの変更をマージできるようにする

Mercurial 無しだと、あなたは古いバージョンを維持するために全てのコードを含んだ全ディレクトリのコピーをたくさん作る事になるだろう。

この退屈な、ディスク容量を喰うやり方には困惑する。バージョン管理を使うのが better なやり方だ。

ほとんどの人は Mercurialコマンドラインで使うが、windows でも Unix でも Mac でもそうだ。Mercurial のコマンドは hg だ。

c:\hginit> hg
Mercurial Distributed SCM

basic commands:
                                
add        add the specified files on the next commit
annotate   show changeset information by line for each file
clone      make a copy of an existing repository
commit     commit the specified files or all outstanding changes
diff       diff repository (or selected files)
export     dump the header and diffs for one or more changesets
forget     forget the specified files on the next commit
init       create a new repository in the given directory
log        show revision history of entire repository or files
merge      merge working directory with another revision
pull       pull changes from the specified source
push       push changes to the specified destination
remove     remove the specified files on the next commit
serve      export the repository via HTTP
status     show changed files in the working directory
summary    summarize working directory state
update     update working directory
                                
use "hg help" for the full list of commands or "hg -v" for details

引数無しで hg とタイプすると、最も一般的な利用可能コマンドの一覧が得られる。 また hg help と試せばコマンドの完全なリストが得られる。

バージョン管理の恩恵を得るためには、リポジトリが必要だ。 リポジトリはあなたの全てのファイルの古いバージョンを保存している。ディスク容量を抑えるために、実際に全ての古いバージョンが保存されているわけでは無く、 -コンパクトな変更のリストが保存されている。

一昔前にはリポジトリを手に入れるのは大変な事だった。あなたはどこかの中央サーバを持たなきゃならないし、そこにはソフトウェアをインストールしなければならなかった。 Mercurial は分散なので、手の込んだ中央サーバが無くても使うことが出来る。あなたのコンピュータ上で完全にそれを実行できる。 そしてリポジトリを手に入れるのは超簡単だ。作業中のコードのあるトップのディレクトリへ行き・・・

c:\hginit> cd CountDown

c:\hginit\CountDown> dir /w
 Volume in drive C has no label.
 Volume Serial Number is 9862-36C5

 Directory of c:\hginit\CountDown

[.]                       [..]                      a.txt
AlternateMessages.xml     App.config                App.xaml
App.xaml.cs               CountDown.xaml            CountDown.xaml.cs
DevDaysCountDown.csproj   favicon.ico               [Images]
[Properties]              [TweetSharp]
               9 File(s)        155,932 bytes
               5 Dir(s)  76,083,609,600 bytes free

・・・そこに私のコードがあるのだが、あなたは hg init とタイプする。

hg init

リポジトリを作る

c:\hginit\CountDown> hg init

c:\hginit\CountDown>


ちょっと待って、何が起きた?何も起こっていないように見える。
でも注意深く見ると、.hg というディレクトリが作られているのがわかるだろう。

c:\hginit\CountDown> dir /w
 Volume in drive C has no label.
 Volume Serial Number is 9862-36C5

 Directory of c:\hginit\CountDown

[.]                       [..]                      [.hg]
a.txt                     AlternateMessages.xml     App.config
App.xaml                  App.xaml.cs               CountDown.xaml
CountDown.xaml.cs         DevDaysCountDown.csproj   favicon.ico
[Images]                  [Properties]              [TweetSharp]
               9 File(s)        155,932 bytes
               6 Dir(s)  76,083,650,560 bytes free


それがリポジトリなんだ!それは Mercurial が必要とする全てが詰まったディレクトリだ。設定、古いバージョンのファイル、タグ、雨が降った時のための予備の靴下などなど。だけどそのディレクトリに行ってはいけない。あなたはそのディレクトリに直接ちょっかいを出そうなんて思っちゃいけない。

OK, 私たちは今、フレッシュな新しいリポジトリを手に入れたので、そこにソースフファイルを追加したいと思うだろう。これも簡単だ。ただ hg add とタイプすればいい。

hg add

リポジトリに追加するファイルを予約する。あなたがコミットするまでは実際に追加されない。

c:\hginit\CountDown> hg add
adding AlternateMessages.xml
adding App.config
adding App.xaml
adding App.xaml.cs
adding CountDown.xaml
adding CountDown.xaml.cs
adding DevDaysCountDown.csproj
adding Images\background_city.jpg
adding Images\carsonified_presents.png
adding Images\darkpanel.png
adding Images\devdays.png
adding Images\failwhale.png
adding Images\holding_image.jpg
adding Images\jeff_atwood.jpg
adding Images\joel_spolsky.jpg
adding Images\logo_stackoverflow.png
adding Images\matt_lacey.jpg
adding Images\sideDarkpanel.png
adding Images\vertical_lines2.png
adding Properties\AssemblyInfo.cs
adding Properties\Resources.Designer.cs
adding Properties\Resources.resx
adding Properties\Settings.Designer.cs
adding Properties\Settings.settings
adding TweetSharp\Dimebrain.TweetSharp.dll
adding TweetSharp\Dimebrain.TweetSharp.xml
adding TweetSharp\Newtonsoft.Json.dll
adding a.txt
adding favicon.ico

あなたの変更を commit するには、まだもう一ステップある。何の変更だって?全てのファイルを追加したという変更だ

なぜコミットしなければならないのか? Mercurial では、コミット中に「やあ、ファイルは今はもっともらしく見えているけど-思い出してくれないか?」と言ってくる。
まるでディレクトリ全体のコピーを作成しているかのようだ・・・あなたがいくらかの変更をして、コミットしようとした時に。

hg commit

全てのファイルの現在の状態をリポジトリに保存する。

c:\hginit\CountDown> hg commit

この時、Mercurial はコミットメッセージをあなたがタイプ出来るように、エディタをポップアップしてくれる。これは単にこのコミットであなたが何を変更したかを思い出せるようにするためのものだ。

あなたがコメントを保存してエディタを終了させると、あなたのファイルはコミットされる。

あなたは hg log とタイプすれば変更履歴を見ることが出来る。まるであなたのリポジトリのブログのようだ。

hg log

コミットしたリポジトリの変更履歴を表示する。

c:\hginit\CountDown> hg log
changeset:   0:da5f372c3901
tag:         tip
user:        Joel Spolsky 
date:        Fri Feb 05 13:04:30 2010 -0500
summary:     Initial version of the CountDown code

それではファイルを変更して何が起こるか見てみよう。

このファイルを・・・
a.txt:

Scott Adams: Normal people believe that if it ain't broke, don't fix it. Engineers believe that if it ain't broke, it doesn't have enough features yet.

このように変更する。
a.txt:

SCOTT ADAMS: Normal people believe that if it ain't broke, don't fix it. Engineers believe that if it ain't broke, it doesn't have enough features yet.

変更したので、hg commit を使ってコミット出来る。

c:\hginit\CountDown> hg commit

Mercurial が、変更した a.txt というファイルだけを意識しているのに注目してほしい。

そして今私がコミットしたので、ログを見てみよう。

c:\hginit\CountDown> hg log
changeset:   1:a9497f468dc3
tag:         tip
user:        Joel Spolsky 
date:        Fri Feb 05 13:26:13 2010 -0500
summary:     Capitalized "Scott Adams"

changeset:   0:da5f372c3901
user:        Joel Spolsky 
date:        Fri Feb 05 13:04:30 2010 -0500
summary:     Initial version of the CountDown code

最近のブログみたいに、Mercurial は最新の記事を先頭に持ってくる。

さらに変更を加えよう。おもしろいから。

a.txt:

SCOTT ADAMS: Normal people believe that if it ain't broke, don't fix it. Engineers believe that if it ain't broke, it doesn't have enough features yet.

・・・このように変更する。

a.txt:

SCOTT ADAMS: Normal people believe that if it isn't broken, don't fix it. Engineers believe that if it isn't broken, it doesn't have enough features yet.

コミットする。

c:\hginit\CountDown> hg commit

私のコミットメッセージ

何のログが表示されている?

c:\hginit\CountDown> hg log
changeset:   2:55490459b740
tag:         tip
user:        Joel Spolsky 
date:        Fri Feb 05 13:47:43 2010 -0500
summary:     Fixed some grammar

changeset:   1:a9497f468dc3
user:        Joel Spolsky 
date:        Fri Feb 05 13:26:13 2010 -0500
summary:     Capitalized "Scott Adams"

changeset:   0:da5f372c3901
user:        Joel Spolsky 
date:        Fri Feb 05 13:04:30 2010 -0500
summary:     Initial version of the CountDown code

OK, いろいろ楽しいね。私はいくつかの変更を作り、そしてそれぞれの時期で意味のある変更を作り、リポジトリにコミットした。

私にはあなたが何を考えているのかわかるよ。あなたはこう考えている。「ジ ョ エ ル 、 こ れ は 時 間 の 無 駄 だ よ。」なぜこんな無駄なコミットをさせるの?

我慢だ、young grasshopper。あなたは今ここから恩恵を得る方法を学んでいるのだから。

Number one。仮にあなたが大きな編集の失敗をしてしまったとしよう。

a.txt:

SCOTT ADAMS: Normal people believe that if it isn't broken, don't fix it. Engineers believe that if it isn't broken, it doesn't have enough features yet.

このように失敗する。
a.txt:

DAN QUAYLE: Illegitimacy is something we should talk about in terms of not having it.

そしてその時、ああ神様、おまけにあなたは重要な一組のファイルを消してしまった。

c:\hginit\CountDown> del favicon.ico

c:\hginit\CountDown> del App.xaml

Mercurial 以前の日々では、なぜここ8ヶ月もバックアップシステムが故障していたのかと、システム管理者になきついて耳をつんざくように叫びながら悲しい質問をする好機であっただろう。

システム管理者というのはお決まりのメニューを注文するものだが、とても恥ずかしがり屋でチームの他のメンバーと昼食を一緒に取りたがらない。こういった彼のオフィスの回転椅子から彼を遠ざけるような稀な出来事があると、あなたは彼の足の間にメキシカンランチからこぼれて出来た三角形のサルサソースの色の染みが床に付いているのに気づき、誰も彼の椅子に座らないように保険をかけようと思うことだろう。たとえそれが会社創設者が自ら買ってきた上級のハーマンミラーのものであり、背中を痛くする基本的な99ドルの特価品ではなかったとしてもだ。

とにかく、まぁ、バックアップは無いんだ。

ありがとう Mercurial 。だって変更に関する不幸な出来事があった時に、あなたのディレクトリを最後にコミットした状態に戻す hg revert という便利なコマンドを実行出来るのだから。

hg revert

変更したファイルをコミットしたバージョンに戻す。

c:\hginit\CountDown> hg revert --all
reverting App.xaml
reverting a.txt
reverting favicon.ico

c:\hginit\CountDown> type a.txt
SCOTT ADAMS: Normal people believe that if it isn't
broken, don't fix it. Engineers believe that if it
isn't broken, it doesn't have enough features yet.

私がコマンドライン引数で --all を使ったのは、私が全てのファイルを元の状態に戻したかったからだ。

だから、あなたが Mercurialソースコードの作業をする時には、

  1. いくつかの変更をする
  2. 動くことを確認する
  3. もし動いたら、それらを commit する
  4. もし動かなかったら、それらを revert する
  5. GOTO 1

(わかってる。私はWindowsコマンドプロンプトとGOTOステートメントを使う、あまりクールではないプログラマだ)

hg status

変更したファイルの一覧を表示する。

時が経つにつれて、あなたは今どこにいて、前回のコミットから何を変更したのかわからなくなってしまうかもしれない。 Mercurial はあなたのために全てを追跡し続けている。あなたがすべきことは hg status とタイプすることで、そうすれば Mercurial は、あなたに変更したファイルのリストを与えてくれる。

私がファイルを作成、編集、削除したとしよう。

c:\hginit\CountDown> copy a.txt b.txt
        1 file(s) copied.

c:\hginit\CountDown> notepad2 a.txt

c:\hginit\CountDown> del favicon.ico

c:\hginit\CountDown> hg status
M a.txt
! favicon.ico
? b.txt

hg status は変更のあったファイルの先頭にあなたがしたことに関する短い説明を加えて一覧を表示する。
"M"は修正あり。-ファイルに変更があった。
"!"は紛失。 -そこにあるはずのファイルが無い。
"?"は unknown。 -Mercurial はこのファイルが何なのかわからない。

それではこれらのファイルの変更を一つずつ処理していこう。まず修正したファイル a.txt。
何が修正されたんだっけ? あなたは何を変更したのか忘れてしまうかもしれない!
ふん、私には朝食に何を食べたかわずかに思い出せるだけだ。どっちが特に厄介かというと、それは常にコーンフレークの方だ。
どっちみち a.txt は変更されたんだ。何が変わった?

こういう場合に使うコマンドがある。hg diff は、あなたに最後のコミットからファイルにどのような変更があったのかを正確に教えてくれる。

hg diff

ファイルの変更内容を表示する。

c:\hginit\CountDown> hg diff a.txt
diff -r 55490459b740 a.txt
--- a/a.txt     Fri Feb 05 13:47:43 2010 -0500
+++ b/a.txt     Fri Feb 05 14:31:18 2010 -0500
@@ -1,3 +1,3 @@
-SCOTT ADAMS: Normal people believe that if it isn't
+SCOTT ADAMS: Civilians believe that if it isn't
 broken, don't fix it. Engineers believe that if it
 isn't broken, it doesn't have enough features yet.

このフォーマットはちょっと不可解だが、興味深い部分から出来ている。マイナスで始まる行は削除された行で、プラスで始まる行は追加された行だ。この例では"Normal people"が"Civilians"に編集されていることがわかる。

hg remove

リポジトリから削除するファイルを予約する。あなたが実際にコミットするまで削除しない。

次だ。失われたファイル favicon.ico だ。前述のとおり、あなたがもしそれを削除するつもりではなかったとしたら、あなたは hg revert を実行する事が出来るけれど、ここではあなたが本当に削除するつもりだったとしよう。いつでもあなたがファイルを削除(もしくは追加)すると、あなたは Mercurial に言っておかなければならない。

c:\hginit\CountDown> hg remove favicon.ico

c:\hginit\CountDown> hg status
M a.txt
R favicon.ico
? b.txt

"R"は削除を意味し、私たちがファイルを次にコミットする時に削除される。
(ファイルの履歴はリポジトリに残り、もちろん私たちはいつでもそれを元に戻すことが出来る) 最後に、私たちは新しいファイル b.txt を追加する。

c:\hginit\CountDown> hg add
adding b.txt

c:\hginit\CountDown> hg st
M a.txt
A b.txt
R favicon.ico

"A"は追加を意味する。私が hg status のタイプに手を抜いていたことに気づいただろうか。 Mercurial は特定が出来るだけの文字があれば十分で、st から始まるコマンドは他に無いんだ。

すべての?'や!'を解決すると、私は先に進んで私の変更をチェックインすることが出来る。

c:\hginit\CountDown> hg commit

c:\hginit\CountDown> hg log
changeset:   3:2f4718ee168e
tag:         tip
user:        Joel Spolsky 
date:        Fri Feb 05 14:54:45 2010 -0500
summary:     A few highly meaningful changes. No favicon.ico no more.

changeset:   2:55490459b740
user:        Joel Spolsky 
date:        Fri Feb 05 13:47:43 2010 -0500
summary:     Fixed some grammar

changeset:   1:a9497f468dc3
user:        Joel Spolsky 
date:        Fri Feb 05 13:26:13 2010 -0500
summary:     Capitalized "Scott Adams"

changeset:   0:da5f372c3901
user:        Joel Spolsky 
date:        Fri Feb 05 13:04:30 2010 -0500
summary:     Initial version of the CountDown code

hg log の出力結果についてもう一つ。changeset 行は全てのコミットに対する番号を示していて・・・実際のところ2つの番号がある。便利で、短い、頭文字で"0"と書いてあるほうとその他があるが長い、よくわからない16進数の方は今は無視しておいていい。

Mercurial が古いバージョンの古いファイルを再構築するのに十分な情報をリポジトリ内に維持していることを思い出してほしい。

hg cat

いずれかのリビジョンのいずれかのファイルを表示する。

まず最初に、シンプルな hg cat コマンドは古いバージョンのファイルを出力するために使うことが出来る。例えば a.txt の今を見るならこうだ。

c:\hginit\CountDown> hg cat a.txt
SCOTT ADAMS: Civilians believe that if it isn't
broken, don't fix it. Engineers believe that if it
isn't broken, it doesn't have enough features yet.

過去のファイルを見るなら、ログから changeset の番号を取り出せばよい。この時、私は cat コマンドを-r ("revision")引数を付けて使用する。

c:\hginit\CountDown> hg cat -r 0 a.txt
Scott Adams: Normal people believe that if it ain't
broke, don't fix it. Engineers believe that if it
ain't broke, it doesn't have enough features yet.

もしファイルが長くて複雑で、変更がちょっとだけだったなら、私は hg diff コマンドを -r 引数を付けて実行し、 2つのリビジョン間の差を表示することが出来る。例えばリビジョン0と1の間の変更を見るならこうだ。

c:\hginit\CountDown> hg diff -r 0:1 a.txt
diff -r da5f372c3901 -r a9497f468dc3 a.txt
--- a/a.txt     Fri Feb 05 13:04:30 2010 -0500
+++ b/a.txt     Fri Feb 05 13:26:13 2010 -0500
@@ -1,3 +1,3 @@
-Scott Adams: Normal people believe that if it ain't
+SCOTT ADAMS: Normal people believe that if it ain't
 broke, don't fix it. Engineers believe that if it
 ain't broke, it doesn't have enough features yet.

最後に、もしあなたが疲れきって挫折してしまっていたのでないのなら、このチュートリアルを終える前に、ちょっとした事をもう一つあなたに見せたい。あなたは hg update コマンドを使って好きなリビジョンに戻ったり進んだり出来る。そう、あなたは未来そのものに進むことは出来ないが、しかし、それが出来るなら超クールだ。もしあなたが4つのリビジョンしか持っていないのに hg update -r 103994 と実行すると、反重力SFの未来におけるバージョンを手に入れることが出来るならね。でも、もちろんそんなことは不可能だ。

hg update

作業中のディレクトリを特定のリビジョンに Update する。

バージョンを戻すと何が可能になるのか。見てほしい。

c:\hginit\CountDown> hg update -r 0
2 files updated, 0 files merged, 1 files removed, 0 files unresolved

c:\hginit\CountDown> type a.txt
Scott Adams: Normal people believe that if it ain't
broke, don't fix it. Engineers believe that if it
ain't broke, it doesn't have enough features yet.

c:\hginit\CountDown> hg up -r 1
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

c:\hginit\CountDown> type a.txt
SCOTT ADAMS: Normal people believe that if it ain't
broke, don't fix it. Engineers believe that if it
ain't broke, it doesn't have enough features yet.

c:\hginit\CountDown> hg up
2 files updated, 0 files merged, 1 files removed, 0 files unresolved

c:\hginit\CountDown> type a.txt
SCOTT ADAMS: Civilians believe that if it isn't
broken, don't fix it. Engineers believe that if it
isn't broken, it doesn't have enough features yet.

hg update はディレクトリにある全てのファイルを変更して時間を進んだり戻ったりする。もしファイルが追加したり削除されていたりしたら、それを追加したり削除したりする。引数無しで、hg update を実行すると最新のバージョンになる。

自己診断テスト

OK! 以上が今回のチュートリアルだ。あなたが今ここで理解するべきやり方はこの通りだ。

  1. リポジトリを作る
  2. リポジトリにファイルを追加する、もしくは削除する
  3. 変更を加えた後で、あなたがコミットしていない変更分を確認する
  4. ・・・もし望むならコミットする
  5. ・・・もし望まないなら元に戻す
  6. 古いバージョンのディレクトリを見て、好きな時点のディレクトリに戻したり進めたりする

次回はチーム全体の作業を Mercurial でどのように取ってくるかについて見てみよう。

目次へ