Mercurial初心者が絶対にブックマークすべきページ
『Mercurial の使い方のチュートリアル』を一読しておけば、日常作業に困る事は無いと思います。しかし、たまにはリポジトリに間違ったコミットをしてしまうものですし、最初は誰でも間違いがちです。そこで間違えたときに打つべきコマンドの覚え書きとして、以下のコマンド入力例を公開します。
ワーキングツリーにカレント・ディレクトリを移動している状態を前提にした操作例なので注意してください。また、各コマンドの詳細なオプションは hg help [コマンド] を見て確認してください。なお、Mercurialはバージョン1.7.36.1.3で動作確認しています。
- リポジトリへの追加登録を取り消す
- 編集を取り消し、あるリビジョンの状態に戻す
- 編集済み変更の一部だけをコミットする
- コミットをやり直す、コミット・メッセージを変更する
- ファイル編集後、親リビジョンを変更してコミットする
- チェンジセットを消す
- チェンジセットを打ち消す
- チェンジセットの内容を変更する
- 複数のチェンジセットを一つにまとめる
- (6)から(9)とチェンジセットの入れ替えを手軽に行なう
- 「中止: 作業領域の変更が未コミットです」を回避する
- pushしたのを無かったことにする
- pullすると同時に、ブランチヘッドを作業領域の親に する
- 履歴をさかのぼって特定のファイルを削除する
- 履歴をさかのぼってファイル名を変換する
- コミットしている著者名を変更する
1. リポジトリへの追加登録を取り消す標準コマンド
間違ってhg-addした場合は、hg-revertで構成管理へのファイルの追加登録を取り消す事ができます。
登録後にコミット済みのファイルを、次回以降のコミットから除外するにはhg-forgetを用いてください。
2. 編集を取り消し、あるリビジョンの状態に戻す
簡単にワーキングツリーの状態を、リビジョンの状態に戻すことができます。
2.1. hg revert標準コマンド戻す
特定もしくは全体のファイルを、あるリビジョンの状態に戻せます。ワーキングツリー全体に影響を与えなくて済みます。
example.cppを最新リビジョンの状態に戻すときは、以下のようにコマンドを打ちます。
-r [リビジョン番号]で、どのリビジョンから戻すかを選択できます。
2.2. hg update -C標準コマンドペアレント変更切り替え
リビジョンを切り替えるコマンドで、ワーキングツリー全体に影響が及びます。また、コミット時の親リビジョンも変化します。
リビジョン番号42に切り替える場合は、以下のように入力します。
ファイル状態: 更新数 5、 マージ数 0、 削除数 0、 衝突未解決数 0
hg-updateで古いリビジョンを指定した後にコミットを行うと、そのリビジョンの子孫としてリビジョンが作られるので注意してください。
リビジョン番号の他に、16進コミットハッシュ値の先頭からの一部もしくは全部,タグ,tip(ブランチの先頭),null(最初のコミット前のリビジョン),.(ドット; 現在のリビジョン)が指定できます。また、これらの前に^(ハット)を書くことで、これらの一つ前を指定することができます。例えばtip^を指定すると、ブランチの先頭のリビジョンの親リビジョンが指定されます。^は.^^^と言うように複数続けることができ、またマージにより2つの親リビジョンがあるときは、^2でマージ先を指定することができます。.^2^は、現在のリビジョンがマージしたリビジョンの親リビジョンになります。
3. 編集済みの変更の一部だけをコミットする標準コマンド
複数の機能を同一のチェンジセットで追加すると、あとで混乱を招くときがあります。コミットを分割して整理整頓するように心がけましょう。
3.1. hg commit ${filename(s)}標準コマンド
hg-commitの引数にファイル名を与えると、それらのファイルの変更だけをコミットに加えます。
3.2. hg commit --interactive標準コマンド
同一ファイルに複数の変更がある場合は、対話モードで変更箇所のチャンクを指定してコミットすることができます。
-iは省略形です。
4. コミットをやり直す、コミット・メッセージを変更する
4.1. hg rollback標準コマンドリポジトリ変更ロールバック
1回分だけコミットを取り消せます。ワーキングツリーは維持されます。
コミット・メッセージを書き換えたいとき、コミットに追加するファイルを忘れたとき、誤ってpullしたとき、誤ってpushされたときに使えます。
リビジョン 43 へ巻き戻し中 (commit の取り消し)
4.2. hg commit --amend標準コマンドリポジトリ変更
hg-commitに--amendをつけることで、前回コミットに追記ができます。バージョン2.2で追加されました。
5. ファイル編集後、親リビジョンを変更してコミットする標準コマンド
hg-summaryでコミット時の親リビジョンを確認できますが、うっかりファイル編集後に親リビジョンを間違えていることに気づくことがあります。この場合は、hg-shelveで待避したあとに、hg-updateで親リビジョンの変更をし、hg-unshelveをすればよいです。
変更内容を default という名前で退避
ファイルの更新数 1、 マージ数 0、 削除数 0、 衝突未解消数 0
~/Repository$ hg update -C -r tip
~/Repository$ hg unshelve
退避情報 'default' を復旧中
退避した変更の移動 (rebase) 中
~/Repository$ hg commit -m "update a file"
現在およびhg-update先のリビジョンで、まだ管理対象外の新規ファイルを追加した場合は、hg-update -Cで消されることはないので、待避しなくても大丈夫です。
現在の親リビジョンでは管理対象外で、hg-update先では管理対象のファイルの場合は、hg-shelveができない一方、hg-updateで消されてしまうので、一時ファイルにコピーするなどする必要があります。
6. チェンジセットを消すmqリポジトリ変更ストリップ
特定のチェンジセットと、その子孫を消す事ができます。
標準では無効になっている、Mercurial Queues Extensionを有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。
mq =
使い方は簡単です。リビジョン42とその子孫のチェンジセットを消去します。
ファイル状態: 更新数 5、 マージ数 0、 削除数 0、 衝突未解決数 0
バックアップのバンドルを /home/user/Repository/.hg/strip-backup/000c73753833-backup.hg に保存
間違って消した場合は、バックアップ・ファイルから復元する事ができます。
チェンジセットを追加中
マニフェストを追加中
ファイルの変更を追加中
2 のチェンジセット(0 の変更を 0 ファイルに適用)を追加(-2個のヘッド)
(作業領域の更新は 'hg update')
7. チェンジセットを打ち消す標準コマンドリポジトリ変更バックアウト
共有リポジトリにpush後は、コミットを取り消したり、チェンジセットを消したりは原則としてできません。チェンジセットの更新内容を打ち消すチェンジセットを作る事になります。
リビジョン39を打ち消すチェンジセットを作るには、以下のように入力します。
deleated.cpp の復旧中
ファイル状態: 更新数 6、 マージ数 0、 削除数 0、 衝突未解決数 0
自動でコミットはされません。
8. チェンジセットの内容を変更するmqリポジトリ変更
何回かコミットした後でも、マージや分岐の発生前でpush前であれば、チェンジセットの内容を変更することができます。
標準では無効になっている、Mercurial Queues Extensionを有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。
mq =
まずは現在のチェンジセットのうち、変更対象から最新版までをパッチに変換します。リビジョン34~36までが対象とすると、以下のようになります。
変換したパッチを、いったんワーキングツリーに適応します。
34.diff
35.diff
36.diff
変更したいリビジョンまでのパッチがワーキングツリーに適応されている状態にします。
36.diff の適用解除
35.diff の適用解除
適用中の最上位パッチは 34.diff です
変更したいリビジョンの状態になっているので、変更を加えます。
ワーキングツリーに対してでは無く、パッチに対しての編集になるので、変更後、パッチの内容を更新します。
全てのパッチを適応します。
35.diff を適用中
36.diff を適用中
適用中の最上位パッチは 36.diff です
全てのパッチをワーキングツリーに適応した状態にして、パッチ処理を終了します。
これで、チェンジセットの改編は終わりです。
9. 複数のチェンジセットを一つにまとめる
マージや分岐の発生前でpush前であれば、後述するMQ Extensionで複数のチェンジセットをまとめて一つにできます。オーソドックスな方法と、強引な方法と、後の節で説明する楽な方法の三種類があります。
9.1. MQ Extensionを使うmqリポジトリ変更
標準では無効になっている、Mercurial Queues Extensionを有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。
mq =
まずは現在のチェンジセットのうち、変更対象から最新版までをパッチに変換します。以下の例では、リビジョン34を指定しています。
変換したパッチを、いったんワーキングツリーに適応します。
34.diff
35.diff
36.diff
合成するチェンジセットのうち、最も古いチェンジセットに対応するパッチを選択します。
36.diff の適用解除
35.diff の適用解除
適用中の最上位パッチは 34.diff です
パッチを合成します。
全てのパッチをワーキングツリーに適応した状態にして、パッチ処理を終了します。
これで、チェンジセットの合成は終わりです。
9.2. hg archive & hg update -C & hg clone標準コマンドリポジトリ変更
マージや分岐を含めてチェンジセットを統合する荒業もあります。
まずは、テンポラリ・ディレクトリに最新版のアーカイブを吐き出します。テンポラリ・ディレクトリは空フォルダであれば、任意の場所で問題ないでしょう。
38~tipをまとめるので、リビジョン37にワーキングディレクトリを切り替えます。
テンポラリ・ディレクトリの最新版のファイルを、ワーキングディレクトリにコピーします。
増えたファイルをトラッキングします。
コミットを行います。これで、リビジョン37から昔の枝と、新しい枝が分岐した状態になります。
古い枝の消去はhg-stripを使うのが容易ですが、hg-cloneでリビジョン番号を指定しても消すことができます。
~/Repository$ hg clone -r tip Repository NewRepository
最後に、新しいリポジトリで、古いリポジトリを置き換えれば完了です。
10. (6)から(9)とチェンジセットの入れ替えを手軽に行なうHistedit
見てきたようにチェンジセットをまとめるのは手間暇ですが、作業を簡略化してくれるHistedit Extensionと言うのがあります。
標準では無効になっている、Histedit Extensionを有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。
histedit =
あとは、例えばリビジョン34からtipまでを編集する場合は、
と入力すると、git rebase --iと同様に、テキストエディタでチェンジセットの編集を行なうことができます。書かれている通りに編集をして保存をすると、それにそってチェンジセットをまとめたり、消したり、入れ替えたりしてくれます。
変更時はテキストエディタで edit を指定したチェンジセットに移動するので、ファイルを更新し、
と、再度、histeditを用います。
11. 「中止: 作業領域の変更が未コミットです」を回避する標準コマンド
ワーキングツリーにコミット前の編集中ファイルが残っている場合、「中止: 作業領域の変更が未コミットです」とエラーが出て履歴改変ができませんが、
として未コミットのファイルを退避すれば利用できます。履歴改変後に、
して戻しましょう。なお、shelveはMercurialのバージョン5.1で標準になったので、それ以前の(しかし2.8以降の)バージョンを利用している場合は、
shelve=
とする必要があります。
12. pushしたのを無かったことにする戻す標準コマンド
一度、サーバーにpushすると履歴改変ができなくなりますが、それを管理しているフェーズを変更することで可能になります。以下の例では、リビジョン34からtipまでのフェーズをdraftに戻すことでサーバーへのpushを可能にしています。
12. pullすると同時に、ブランチヘッドを作業領域の親にするリポジトリ変更
編集競合が無い場合でも、並行してリポジトリに変更が加えられた場合は、pullしたあとのコミットは分岐します。作業領域の親チェンジセットがブランチヘッドでは無いからです。分岐するのが嫌な場合はrebase拡張を有効にして、hg-pullに--rebaseオプションをつけるか、hg-pull後にhg-rebaseをします。
rebase =
14. 履歴をさかのぼって特定のファイルを削除するConvertリポジトリ変更
標準では無効になっている、ConvertExtension有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。
hgext.convert=
以下のような、除外するファイル名を含んだファイルを作成します。
以下の例では、ftp_account_information.txtを除外します。パス区切りはWindowsでも、常に / となっています。また、ワイルドカード(e.g. *.cpp)を利用する事もできます。
作成したファイル名は、exclude.txt としましょう。--filemapオプションでexclude.txtを指定して、hg-convertを行います。
~/Repository$ hg convert --filemap exclude.txt Repository Repository2
最後に、新しいリポジトリで、古いリポジトリを置き換えれば完了です。
なお、上記の例では除外するファイルを指定していますが、includeで含むファイルを指定したり、includeとexcludeを組み合わせることも可能です。
15. 履歴をさかのぼってファイル名を変換するConvertリポジトリ変更
標準では無効になっている、ConvertExtension有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。
hgext.convert=
以下のような、除外するファイル名を含んだファイルを作成します。
以下の例では、old_filename.txtをnew_filename.txtに変換します。パス区切りはWindowsでも、常に / となっています。
作成したファイル名は、exclude.txt としましょう。--filemapオプションでexclude.txtを指定して、hg-convertを行います。
~/Repository$ hg convert --filemap exclude.txt Repository Repository2
最後に、新しいリポジトリで、古いリポジトリを置き換えれば完了です。
なお、ファイルの削除と同時に行う事ができます。
16. コミットしている著者名を変更するConvertリポジトリ変更
標準では無効になっている、ConvertExtension有効にしている必要があり、%USERPROFILE%¥Mercurial.iniか、~/.hgrcに以下の内容を追加する必要があります。
hgext.convert=
除外するファイル名を含んだファイルを作成します。以下の例では、uncorrelatedをuncorrelated zombie <uncorrelated@yahoo.co.jp>に変換します。
作成したファイル名は、authors.txtとしましょう。--authorsオプションでauthors.txtを指定して、hg-convertを行います。
~/Repository$ hg convert --authors authors.txt Repository Repository2
最後に、新しいリポジトリで、古いリポジトリを置き換えれば完了です。