このエントリーをはてなブックマークに追加

Mercurialでshelveを使う

Mercurialアドベントカレンダー 2012の10日目です。

なお、TortoiseHgアドベントカレンダー 2012の10日目である、TortoiseHgで shelveを使うとも関連があります。

shelveって?

みなさま一度は作業領域が編集中な状態でmergeしようとして、「作業領域の変更が未コミットです」と言われたことがあるかと思います。そして、「い、いや、今はcommitしたくないんだよ!」と思ったことも。

こういう場合に使える拡張が、hgshelveです。shelve(棚)という名前の通り、現在の編集状況を一時的に保管し「棚上げ」できる拡張です。

「棚上げ」した変更はリポジトリの特別な場所に格納され、いつでもその変更を作業領域に戻せます。

実はMQを使えば同じことが出来るのですが、MQはなんでも出来てしまうので、ちょっと怖い面もあります。特に慣れないうちはshelveのように特定の用途だけを行うツールを使うと良いのではないかと思います。

インストール

shelveは標準ではついてきませんので、自分で入れる必要があります。

# どこか好きな場所に
% cd /path/to/hgshelve
# hgshelveをclone
% hg clone https://bitbucket.org/tksoh/hgshelve/

その後 .hgrc にこう書き加えます。

[extensions]
hgshelve=/path/to/hgshelve/hgshelve.py

これでおーけーです。

使い方

変更を一時的に保存

hg shelveと打ちます。

% hg shelve

すると、

diff --git a/ChangeLog b/ChangeLog
1 個の差分、 2 行の変更
shelve changes to 'ChangeLog'? [Ynsfdaq?]

と出てきます。ここでは、ChangeLogというファイルへの変更を行いましたので、このChangeLogへの変更をどうするか?と聞かれています。

?を押すと選択肢が出てきます。

shelve changes to 'ChangeLog'? [Ynsfdaq?]   ?
y - shelve this change
n - skip this change
s - skip remaining changes to this file
f - shelve remaining changes to this file
d - done, skip remaining changes and files
a - shelve all changes to all remaining files
q - quit, shelving no changes
? - display help
shelve changes to 'ChangeLog'? [Ynsfdaq?]
  • y: この変更を保存する
  • n: この変更を保存せずにスキップする
  • s: このファイルの以降の変更をすべてスキップする
  • f: このファイルの以降の変更をすべて保存する
  • d: 終了。これ以降の全てのファイルの変更をスキップする
  • a: これ以降の全てのファイルの変更を保存する
  • q: なにも保存せずに終わる

です。ここでYを押すと、

shelve changes to 'ChangeLog'? [Ynsfdaq?]  y
@@ -1,4 +1,4 @@
-2010-12-27  r_rudi  <shirou@shiroumac.local>
+hogehogheoghoehgo2012-12-09  r_rudi

   * version 1.1

 shelve this change to 'ChangeLog'? [Ynsfdaq?]  ?

と言うように、変更(hunk)をどうするか聞いてきます。これを全ての変更に対して繰り替えしていきます。一回目はファイルに対して聞かれており、二回目は変更(hunk)に対して聞かれています。ファイルの変更にNを押すと、そのファイル中の変更はすべて保存されないことになります。

ここで述べたように、shelveで保存する変更は「ファイル単位」ではなく、「変更(hunk)」単位です。したがって、record拡張のようにファイルの一部分だけ残してcommit、という用途にも使えます。

全部保存

% hg shelve --all

と、--allをつけると無条件に全ての変更を保存します。

名前付きで保存

保存した変更には--nameで名前をつけられます。

% hg shelve --name myshelf

一度保存した変更に、さらに変更を追加したい場合は--appendを使います。

あるいは、上書きしたい場合は--forceです。

% hg shelve --name myshelf --force
% hg shelve --name myshelf --append

保存してある変更の一覧を見るには--listを使います。

% hg shelve --list

保存した変更を戻す

保存した変更をまた戻して作業領域に反映させるにはunshelveを使います。

% hg unshelve

名前をつけた変更を戻したい場合は--nameをつけます。

% hg unshelve --name myshelf

保存される場所

shelveの内容は.hg/shelvesに保存されています。

%ls .hg/shelves
2012-08-27_17-27-23_parent_rev_1166

注意点

win32text拡張を使っている場合、 .hgrc にこう書いておかないと、変更点の改行コード解釈がうまくいかないそうです。

[patch]
eol = auto

まとめ

今回はコミット前の変更を「棚上げ」できる hgshelve 拡張を紹介しました。MQでもできますが、hgshelveの方が慣れない人には分かりやすいかと思います。

なお、この記事ではコマンドラインでの使い方だけを解説しました。TortoiseHgでの使い方はTortoiseHgでshelveを使うも参照してください。