secretbase.log

コードはすべてNYSLです

パッチ管理リポジトリ入門 ~MQ(パッチ)もMercurialで管理できるよ~

先日 pyfes でご挨拶させていただいた @ さんからバトンを受けまして Mercurial Advent Calendar 2012 - connpass 本日4日目の記事を書かせて頂きます。

パッチ管理リポジトリ入門ということで、MQ自体の管理について簡単にご紹介させていただきたいと思います。

パッチ?

そもそもパッチとはなんでしょうか?ここでいうパッチとはMQのことです。え?よくわかりません。そうですね。
簡単にいうと、 diff の固まり です。Mercurialのチェンジセットのひとつひとつは結局は差分に過ぎません。

よって、コミット済みのチェンジセットもdiffの固まり(つまりMQ)に変換することができます。
この MQ を自在に使いこなすことで、Mercurialの持っているパフォーマンスを最大限引き出すことができます。

MQの詳細については、TokyoMercurial #4.5 で行われた MQハンズオン資料がわかりやすいので、こちらを見てみると少しはMQが理解できると思います。


この先は、この MQ 自体を"リポジトリ管理"するお話になります。


パッチ管理リポジトリ入門しましょう

まずMQ自体について内部的にどのような動作になっているか簡単に説明したいと思います。

知っておくべきことは下記3点です。

パッチの場所(ディレクトリ) .hg/patches
パッチのファイル順番 .hg/patches/series
パッチリポジトリ .hg/patches/.hg

.hg 配下に patches というディレクトリがあるんだ、くらいの認識で次にいきましょう。


ステップバイステップで理解しよう

Mercurialリポジトリ上で、下記コマンドを実行します。

ここでは、 patchrepo というリポジトリ名 とします。

パッチリポジトリの初期化

$ hg init --mq

そうすると、.hg/patches ができています。


あとは通常のパッチ操作をします。

$ hg qnew P1
$ touch README.rst
$ hg add README.rst
$ hg qrefresh -m "add README.rst"

P1のパッチができました。

P2もつくってみましょう。

$ hg qnew P2
$ touch index.rst
$ hg add index.rst
$ hg qrefresh -m "add index.rst"

できました。P1と同じような内容ですが、内容はここでは関係ないのでいいでしょう。

$ hg qseries
P1
P2


ここで、パッチリポジトリに移動しましょう。 .hg/patches に移動します。

$ cd .hg/patches

$ ls -al
total 9
drwxr-xr-x    3 tkondou  Administ     4096 Dec  4 19:50 .
drwxr-xr-x    5 tkondou  Administ     4096 Dec  4 19:50 ..
drwxr-xr-x    3 tkondou  Administ     4096 Dec  4 19:50 .hg
-rw-r--r--    1 tkondou  Administ       39 Dec  4 19:44 .hgignore
-rw-r--r--    1 tkondou  Administ      145 Dec  4 19:49 P1
-rw-r--r--    1 tkondou  Administ      142 Dec  4 19:50 P2
-rw-r--r--    1 tkondou  Administ        6 Dec  4 19:50 series
-rw-r--r--    1 tkondou  Administ       88 Dec  4 19:50 status

.hg があるんです。そうです。ここは普通にMercurialのコマンドが使える世界なのであなたは自由を手に入れました。


例えば hg status を実行すると、追加された状態なんですね。

$ hg st
A .hgignore
A P1
A P2
A series


では、パッチをコミットしましょう。

$ hg commit -m "init patches"

リポジトリのクローン(パッチリポジトリ付き)

別のリポジトリに、パッチを伝搬することができます。

パッチ付きのリポジトリをcloneするために、便利なコマンド qclone が用意されています。

hg qclone コマンドを使うことで、リポジトリとパッチ管理領域の同時複製できます。

$ hg qclone patchrepo patchrepo-clone
差分はありません
ブランチ default へ更新中
ファイルの更新数 4、 マージ数 0、 削除数 0、 衝突未解消数 0
ファイルの更新数 0、 マージ数 0、 削除数 0、 衝突未解消数 0


クローン先の中身が正しくパッチが複製されているかみてみましょう。

$ cd patchrepo-clone

$ hg qseries
P1
P2

$ cd .hg/patches/

$ hg glog 
@  チェンジセット:   0:0581551f990c
   タグ:             tip
   ユーザ:           tkondou <tkondou@gmail.com>
   日付:             Tue Dec 04 20:02:41 2012 +0900
   要約:             init patches

問題ないですね!


クローン元との同期

作業が進むと、クローン元と同期したくなりますね。

hg pull --mq

hg push --mq

とすればOKです。 --mq オプションは、MQリポジトリに対する操作になります。


他に、
hg commit
hg status
hg add
hg log

などは、 --mq を持っているので、 .hg/patches 配下にわざわざ移動しないでも操作可能です。
慣れてきたら、 --mq オプションを使っていくとよいでしょう。

さいごに

いかがでしたでしょうか?
MQ を使いこなすことでMercurialマスターへの一歩が踏み出せます。
TortoiseHgのリポジトリブラウザの画面を見ながら操作するともっとわかりやすいですよ。

明日は、 Mercurial界の海老蔵こと @ さんです。よろしくお願いします。