パッチ管理リポジトリ入門 ~MQ(パッチ)もMercurialで管理できるよ~
先日 pyfes でご挨拶させていただいた @IanMLewis さんからバトンを受けまして Mercurial Advent Calendar 2012 - connpass 本日4日目の記事を書かせて頂きます。
パッチ管理リポジトリ入門ということで、MQ自体の管理について簡単にご紹介させていただきたいと思います。
パッチ?
そもそもパッチとはなんでしょうか?ここでいうパッチとはMQのことです。え?よくわかりません。そうですね。
簡単にいうと、 diff の固まり です。Mercurialのチェンジセットのひとつひとつは結局は差分に過ぎません。
よって、コミット済みのチェンジセットもdiffの固まり(つまりMQ)に変換することができます。
この MQ を自在に使いこなすことで、Mercurialの持っているパフォーマンスを最大限引き出すことができます。
MQの詳細については、TokyoMercurial #4.5 で行われた MQハンズオン資料がわかりやすいので、こちらを見てみると少しはMQが理解できると思います。
- TokyoMercurial #4.5 (Mercurial Queue ハンズオン) - Togetter
- Mercurial Queues ハンズオン (TokyoMercurial#4.5) - Google Drive
- Mercurial Queue の適用事例 - 彷徨えるフジワラ
この先は、この 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 オプションを使っていくとよいでしょう。