ツール群

トップページ

Google
WWWを検索
サイト内を検索

Mercurial初心者が絶対にブックマークすべきページ

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

Mercurial の使い方のチュートリアル』を一読しておけば、日常作業に困る事は無いと思います。しかし、たまにはリポジトリに間違ったコミットをしてしまうものですし、最初は誰でも間違いがちです。そこで間違えたときに打つべきコマンドの覚え書きとして、以下のコマンド入力例を公開します。

ワーキングツリーにカレント・ディレクトリを移動している状態を前提にした操作例なので注意してください。また、各コマンドの詳細なオプションは hg help [コマンド] を見て確認してください。なお、Mercurialはバージョン1.7.3で動作確認しています。

  1. リポジトリへの追加登録を取り消す
  2. 編集を取り消し、あるチェンジセットの状態に戻す
  3. コミットをやり直す、コミット・メッセージを変更する
  4. チェンジセットを消す
  5. チェンジセットを打ち消す
  6. チェンジセットの内容を変更する
  7. 複数のチェンジセットを一つにまとめる
  8. (4)(6)(7)とチェンジセットの入れ替えを手軽に行なう
  9. 「中止: 作業領域の変更が未コミットです」を回避する
  10. pushしたのを無かったことにする
  11. 履歴をさかのぼって特定のファイルを削除する
  12. 履歴をさかのぼってファイル名を変換する
  13. コミットしている著者名を変更する

1. リポジトリへの追加登録を取り消す標準コマンド

間違ってhg-addした場合は、hg-revertで構成管理へのファイルの追加登録を取り消す事ができます。

~/Repository$ hg revert example.cpp

登録後にコミット済みのファイルを、次回以降のコミットから除外するにはhg-forgetを用いてください。

~/Repository$ hg forget example.cpp

2. 編集を取り消し、あるチェンジセットの状態に戻す

簡単にワーキングツリーの状態を、チェンジセットの状態に戻すことができます。

2.1. hg revert標準コマンド戻す

特定もしくは全体のファイルを、あるチェンジセットの状態に戻せます。ワーキングツリー全体に影響を与えなくて済みます。

example.cppを最新のチェンジセットの状態に戻すときは、以下のようにコマンドを打ちます。

~/Repository$ hg revert example.cpp

-r [リビジョン番号]で、どのチェンジセットから戻すかを選択できます。

2.2. hg update -C標準コマンドペアレント変更切り替え

チェンジセットを切り替えるコマンドで、ワーキングツリー全体に影響が及びます。また、コミット時の親チェンジセットも変化します。

リビジョン番号42のチェンジセットに切り替える場合は、以下のように入力します。

~/Repository$ hg update -C 42
ファイル状態: 更新数 5、 マージ数 0、 削除数 0、 衝突未解決数 0

hg-updateで古いチェンジセットを指定した後にコミットを行うと、そのチェンジセットの子孫としてチェンジセットが作られるので注意してください。

3. コミットをやり直す、コミット・メッセージを変更する

3.1. hg rollback標準コマンドリポジトリ変更ロールバック

1回分だけコミットを取り消せます。ワーキングツリーは維持されます。

コミット・メッセージを書き換えたいとき、コミットに追加するファイルを忘れたとき、誤ってpullしたとき、誤ってpushされたときに使えます。

~/Repository$ hg rollback
リビジョン 43 へ巻き戻し中 (commit の取り消し)

4. チェンジセットを消すmqリポジトリ変更ストリップ

特定のチェンジセットと、その子孫を消す事ができます。

標準では無効になっている、Mercurial Queues Extensionを有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。

[extensions]
mq =

使い方は簡単です。リビジョン42とその子孫のチェンジセットを消去します。

~/Repository$ hg strip 42
ファイル状態: 更新数 5、 マージ数 0、 削除数 0、 衝突未解決数 0
バックアップのバンドルを /home/user/Repository/.hg/strip-backup/000c73753833-backup.hg に保存

間違って消した場合は、バックアップ・ファイルから復元する事ができます。

~/Repository$ hg unbundle .hg/strip-backup/000c73753833-backup.hg
チェンジセットを追加中
マニフェストを追加中
ファイルの変更を追加中
2 のチェンジセット(0 の変更を 0 ファイルに適用)を追加(-2個のヘッド)
(作業領域の更新は 'hg update')

5. チェンジセットを打ち消す標準コマンドリポジトリ変更バックアウト

共有リポジトリにpush後は、コミットを取り消したり、チェンジセットを消したりは原則としてできません。チェンジセットの更新内容を打ち消すチェンジセットを作る事になります。

リビジョン39を打ち消すチェンジセットを作るには、以下のように入力します。

~/Repository$ hg backout 39
deleated.cpp の復旧中
ファイル状態: 更新数 6、 マージ数 0、 削除数 0、 衝突未解決数 0

自動でコミットはされません。

6. チェンジセットの内容を変更するmqリポジトリ変更

何回かコミットした後でも、マージや分岐の発生前でpush前であれば、チェンジセットの内容を変更することができます。

標準では無効になっている、Mercurial Queues Extensionを有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。

[extensions]
mq =

まずは現在のチェンジセットのうち、変更対象から最新版までをパッチに変換します。リビジョン34~36までが対象とすると、以下のようになります。

~/Repository$ hg qimport -r 34:tip

変換したパッチを、いったんワーキングツリーに適応します。

~/Repository$ hg qapplied
34.diff
35.diff
36.diff

変更したいリビジョンまでのパッチがワーキングツリーに適応されている状態にします。

~/Repository$ hg qgoto 34.diff
36.diff の適用解除
35.diff の適用解除
適用中の最上位パッチは 34.diff です

変更したいリビジョンの状態になっているので、変更を加えます。

ワーキングツリーに対してでは無く、パッチに対しての編集になるので、変更後、パッチの内容を更新します。

~/Repository$ hg qrefresh -m "古いチェンジセットを修正。"

全てのパッチを適応します。

~/Repository$ hg qpush -a
35.diff を適用中
36.diff を適用中
適用中の最上位パッチは 36.diff です

全てのパッチをワーキングツリーに適応した状態にして、パッチ処理を終了します。

~/Repository$ hg qfinish -a

これで、チェンジセットの改編は終わりです。

7. 複数のチェンジセットを一つにまとめる

マージや分岐の発生前でpush前であれば、後述するMQ Extensionで複数のチェンジセットをまとめて一つにできます。オーソドックスな方法と、強引な方法と、後の節で説明する楽な方法の三種類があります。

7.1. MQ Extensionを使うmqリポジトリ変更

標準では無効になっている、Mercurial Queues Extensionを有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。

[extensions]
mq =

まずは現在のチェンジセットのうち、変更対象から最新版までをパッチに変換します。以下の例では、リビジョン34を指定しています。

~/Repository$ hg qimport -r 34:tip

変換したパッチを、いったんワーキングツリーに適応します。

~/Repository$ hg qapplied
34.diff
35.diff
36.diff

合成するチェンジセットのうち、最も古いチェンジセットに対応するパッチを選択します。

~/Repository$ hg qgoto 34.diff
36.diff の適用解除
35.diff の適用解除
適用中の最上位パッチは 34.diff です

パッチを合成します。

~/Repository$ hg qfold -m 'チェンジセットをまとめる。' 35.diff 36.diff

全てのパッチをワーキングツリーに適応した状態にして、パッチ処理を終了します。

~/Repository$ hg qfinish -a

これで、チェンジセットの合成は終わりです。

7.2. hg archive & hg update -C & hg clone標準コマンドリポジトリ変更

マージや分岐を含めてチェンジセットを統合する荒業もあります。

まずは、テンポラリ・ディレクトリに最新版のアーカイブを吐き出します。テンポラリ・ディレクトリは空フォルダであれば、任意の場所で問題ないでしょう。

~/Repository$ hg archive -r tip /var/tmp/Repository

38~tipをまとめるので、リビジョン37にワーキングディレクトリを切り替えます。

~/Repository$ hg update -r 37

テンポラリ・ディレクトリの最新版のファイルを、ワーキングディレクトリにコピーします。

~/Repository$ cp -r /var/tmp/Repository/* .

増えたファイルをトラッキングします。

~/Repository$ hg add

コミットを行います。これで、リビジョン37から昔の枝と、新しい枝が分岐した状態になります。

~/Repository$ hg commit -m '複数チェンジセットを統合。'

古い枝の消去はhg-stripを使うのが容易ですが、hg-cloneでリビジョン番号を指定しても消すことができます。

~/Repository$ cd ..
~/Repository$ hg clone -r tip Repository NewRepository

最後に、新しいリポジトリで、古いリポジトリを置き換えれば完了です。

~/Repository$ mv NewRepository Repository

8. (4)(6)(7)とチェンジセットの入れ替えを手軽に行なうHistedit

見てきたようにチェンジセットをまとめるのは手間暇ですが、作業を簡略化してくれるHistedit Extensionと言うのがあります。

8

標準では無効になっている、Histedit Extensionを有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。

[extensions]
histedit =

あとは、例えばリビジョン34からtipまでを編集する場合は、

~/Repository$ hg histedit -r 34:tip

と入力すると、git rebase --iと同様に、テキストエディタでチェンジセットの編集を行なうことができます。書かれている通りに編集をして保存をすると、それにそってチェンジセットをまとめたり、消したり、入れ替えたりしてくれます。

変更時はテキストエディタで edit を指定したチェンジセットに移動するので、ファイルを更新し、

~/Repository$ hg histedit --continue

と、再度、histeditを用います。

9. 「中止: 作業領域の変更が未コミットです」を回避する標準コマンド

ワーキングツリーにコミット前の編集中ファイルが残っている場合、「中止: 作業領域の変更が未コミットです」とエラーが出て履歴改変ができませんが、

~/Repository$ hg shelve

として未コミットのファイルを退避すれば利用できます。履歴改変後に、

~/Repository$ hg unshelve

して戻しましょう。なお、shelveはMercurialのバージョン5.1で標準になったので、それ以前の(しかし2.8以降の)バージョンを利用している場合は、

[extensions]
shelve=

とする必要があります。

10. pushしたのを無かったことにする戻す標準コマンド

一度、サーバーにpushすると履歴改変ができなくなりますが、それを管理しているフェーズを変更することで可能になります。以下の例では、リビジョン34からtipまでのフェーズをdraftに戻すことでサーバーへのpushを可能にしています。

~/Repository$ hg phase -d -r 34:tip --force

11. 履歴をさかのぼって特定のファイルを削除するConvertリポジトリ変更

標準では無効になっている、ConvertExtension有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。

[extensions]
hgext.convert=

以下のような、除外するファイル名を含んだファイルを作成します。

以下の例では、ftp_account_information.txtを除外します。パス区切りはWindowsでも、常に / となっています。また、ワイルドカード(e.g. *.cpp)を利用する事もできます。

exclude "ftp_account_information.txt"

作成したファイル名は、exclude.txt としましょう。--filemapオプションでexclude.txtを指定して、hg-convertを行います。

~/Repository$ cd ..
~/Repository$ hg convert --filemap exclude.txt Repository Repository2

最後に、新しいリポジトリで、古いリポジトリを置き換えれば完了です。

~/Repository$ mv NewRepository Repository

なお、上記の例では除外するファイルを指定していますが、includeで含むファイルを指定したり、includeとexcludeを組み合わせることも可能です。

12. 履歴をさかのぼってファイル名を変換するConvertリポジトリ変更

標準では無効になっている、ConvertExtension有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。

[extensions]
hgext.convert=

以下のような、除外するファイル名を含んだファイルを作成します。

以下の例では、old_filename.txtをnew_filename.txtに変換します。パス区切りはWindowsでも、常に / となっています。

rename "old_filename.txt" "new_filename.txt"

作成したファイル名は、exclude.txt としましょう。--filemapオプションでexclude.txtを指定して、hg-convertを行います。

~/Repository$ cd ..
~/Repository$ hg convert --filemap exclude.txt Repository Repository2

最後に、新しいリポジトリで、古いリポジトリを置き換えれば完了です。

~/Repository$ mv NewRepository Repository

なお、ファイルの削除と同時に行う事ができます。

13. コミットしている著者名を変更するConvertリポジトリ変更

標準では無効になっている、ConvertExtension有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。

[extensions]
hgext.convert=

除外するファイル名を含んだファイルを作成します。以下の例では、uncorrelatedをuncorrelated zombie <uncorrelated@yahoo.co.jp>に変換します。

uncorrelated=uncorrelated zombie <uncorrelated@yahoo.co.jp>

作成したファイル名は、authors.txtとしましょう。--authorsオプションでauthors.txtを指定して、hg-convertを行います。

~/Repository$ cd ..
~/Repository$ hg convert --authors authors.txt Repository Repository2

最後に、新しいリポジトリで、古いリポジトリを置き換えれば完了です。

~/Repository$ mv NewRepository Repository