自分がチェックアウトしたリビジョンが分からなくなりました

parent コマンドを使いましょう。 (JapaneseTutorialClone に使用例があります。)

Mercurialで設定を変えられるのはどこですか?

MercurialIni を見てください。

ユーザ名を変更するには?

コミット時にhgがNo username found, using 'user@hostname instead'と出力するようなら、ユーザ名設定を行う必要があります。詳細は クィックスタート を参照してください。

ssh経由でリモートリポジトリをcloneしようとしたらエラーが出ます

もし、こんな風にしてリモートリポジトリをcloneしたとして、

  hg clone ssh://USER@REMOTE/path/to/repo

そして、sshの認証に成功した後でremote: abort: There is no Mercurial repository here (.hg not found)!というエラーメッセージが出てきたのなら、あなたは次の項目を知っておくべきでしょう。

一方、もしエラーメッセージがremote: bash: line 1: hg: command not foundなら、問題はsshによって使用される環境でPATHhgコマンドが無い事です。この問題に対処するには次の2つの方法があります。

変更をpushしようとしたら、"ssl required"というエラーメッセージが出ます

ネットワーク経路が信頼出来る場合は、次の内容を<リポジトリ名>/.hg/hgrcに加えて解決出来ます。

[web]
push_ssl = false

しかしながら、SSLが必要とされるのはそれなりの理由があります。使用しているネットワーク経路が信頼出来ないのなら、この変更を行わないでください。

hg pullとしたのにワーキングディレクトリはからっぽのままです

Mercurialというシステムにはリポジトリとワーキングディレクトリの2つの概念があります。hg pull はリモートリポジトリでの変更をローカルリポジトリに引っ張ってきますがワーキングディレクトリは変更しません。

そのおかげで引っ張ってきた変更をまだマージできずに作業中の状態がめちゃくちゃになるのを防げます。マージもやりやすくなります。

ワーキングディレクトリを更新するには、hg updateを実行してください。pullをするときにワーキングディレクトリも更新したい場合はhg pull -uとします。こうした場合はローカルでの変更をマージしたり上書きしたりはしません。

古いバージョンに戻したいのですが、どうすればよいですか?

hg update -C <version>で最新版が上書きされ指定したバージョンに移動します。

hg revert <version>とするとワーキングディレクトの内容は指定したバージョンにまで戻ってしまいますが、次のコミットでのparentは変化しません。revertは現在のバージョンの変更をなかったことにするために使うもので、古いバージョン上で作業するためには使えません。

(訳注:hg update -Cではワーキングディレクトリの内容とparentの両方が変化しますが、hg revert <version>ではワーキングディレクトリの内容は変わりますがparentはもとのままです)

hg statusで見ると変更有りなのに、hg diffだと変更無しです!

hg status は、ファイルの 内容 または フラグが、いずれかの parentと比較して変更が有った時に出力を行います。hg diffは、内容が最初のparentと比較して変更が有った時のみ出力を行います。 hg diff--gitオプションを付けるとフラグ情報を見れますし、-rオプションで他のparentとの差分も見る事が出来ます。

hg exportやlog -pが、私が行ったマージについておかしなdiffを出力します!

hg diffhg exporthg logが出力するdiffは、一貫性を保つ為に、常に最初のparentに対しての差分を表示します。 また、両方のparentに対して変更の有ったファイルだけが列挙されます。

(マージのdiffは本当に常に最初のparentと比較されるのでしょうか? hg exportには--switch-parentオプションが有るのでは? hg diffhg logにそのオプションが無い論理的根拠がドキュメントに示されていれば良かったのですが。)

revertでワーキングディレクトリを戻したのですが完全には戻りません

多分hg update -mをしたのでしょう。つまりhg parentsで見られるparentが2つになっていませんか。hg revertではワーキングディレクトリをprimary parentに戻すので、2つの親の間で異なる部分は戻されません。hg update -Cで完全に戻ります。

リビジョン間を移動したい場合はきっとhg update -Cが有用でしょう。

からっぽのきれいなワーキングディレクトリが欲しい

一番簡単な方法はhg clone -Uを使うことです。こうすると新しい複製を作りますがワーキングディレクトリ上には何も置かれません。

: hgrcをもとのリポジトリからコピーしたほうが良いかもしれません。

核攻撃を行うコードを含んだ変更をコミットしてしまいました。それを恒久的に削除するにはどうしたらいいですか?

もしコミットしたばかりで、その後まだ他のいかなるコミットやpullを実行していないのなら、最後のコミットトランザクションを取り消す為にrollbackコマンドを使う事が出来ます。

$ hg rollback
rolling back last transaction

もし他のコミット等の変更を加えてしまっていたとしても、まだ世間に公開していないなら、次のような手が有ります。

$ hg clone -r <まだ汚染されていないリビジョン> 汚染されたリポジトリ 汚染されていないリポジトリ

mq extensionの中のstripコマンドも、この場面での操作では有用でしょう。

この操作を行えば、汚染された変更とそれに続く変更を取り除いた新しいリポジトリが得られます。hg exporthg importを使うか、 TransplantExtension を使って、汚染された後にコミットされた変更を取り込む事も出来ます。あと何が出来るかは、 TrimmingHistory を見ましょう。

もし既に公開リポジトリに変更をpushしてしまっていて、みんながそこからcloneしてしまったのなら、魔物は瓶から解き放たれました。落とし前を付けられるといいですね。

“Judge Tries to Unring Bell Hanging Around Neck of Horse Already Out of Barn Being Carried on Ship That Has Sailed.” - William G. Childs

さらに詳細は EditingHistory を見てください。

デカいバイナリファイルをコミットしてしまいました。どうすれば完全に消せますか?

追加してはいけなかったファイルを削除したければ、 ConvertExtension--filemap オプションを用いて Mercurial リポジトリを別の Mercurial リポジトリへ変換 "convert" してください。 You'll want to make sure that you set convert.hg.saverev=False if you want to keep in common the history prior to your removed file(s). If convert.hg.saverev=True, the conversion embeds the source revision IDs into the new revisions under an extra header, visible if via hg log --debug.

別の方法については、一つ前の質問を参照ください。

からっぽのディレクトリをaddしようとしたがうまくいきません

Mercurialではディレクトリの履歴を管理しません。ファイルのみ管理します。普通は問題ないのですが、ファイルを1つも持たないディレクトリは取り扱えません。からっぽのディレクトリはそう便利というものでもなく、実装が複雑になりかねないのですぐに修正するつもりはありません。以下のような解決策を用いてください:

コミット時にメールして欲しい

NotifyExtension を使ってください。

多くのファイルのあるディレクトリのなかで少数のファイルだけをMercurialの管理下に置きたい(例えば ~/ )が、diffやcommitに時間がかかる

printf "syntax: glob\n*\n" > .hgignore

とするか、もしくは 0.7 以降であれば

printf ".*\n" > .hgignore

としてもかまいません。

こうするとhgコマンドは明示的にファイルを追加しない限りすべてのファイルを無視します。

何故ファイルのmtimeがチェックアウト時に元に(訳注:コミット時のものに?)戻さないの?

makeやdistutilsのようなビルドツールを使う場合、古いリビジョンにupdateするとそれらのツールによるファイルの更新がうまくいかないかもしれないという問題があるからです。さらに新しいほうのチェンジセットのほうがタイムスタンプが古い可能性もあります、というのは他のリポジトリからのpullや人からのパッチをimportした場合、リポジトリから取り出した 新しいチェンジセットのせいでタイムスタンプが 古く なってしまうかもしれないからです。

(訳注:以下の訳はかなり怪しい) hg archiveを使うと、別のディレクトリにチェックアウトするようなことができます。これでタイムスタンプを制御できます。このディレクトリは新しく作られるので、後から別のチェンジセットに切り替えられたりすることがなく、上で挙げたような問題は生じません。

どうにかして、リモートサーバにhg pushすると自動的にhg updateされるようになりませんか?

[hooks]
changegroup = hg update >&2

リモートリポジトリの.hg/hgrcにこう書くとうまくいきます。 出力は標準エラー出力(か/dev/null)にリダイレクトされなければいけません。標準出力はデータのストリームに使われますので。

HTTPのログイン情報を一度設定すれば毎回適用されるように出来ませんか?

URLの中でユーザ名とパスワードを指定する事が出来ます。

http://user:password@mydomain.org

これをhgrcファイルの中のpathsセクションに新しいエントリとして追加します。

リモートリポジトリに対してhg logするには、どうやればいいの?

出来ません。 Mercurialが-Rオプションで受け付けるのは、ローカルリポジトリだけです(hg help -v log参照)。

> hg log -R http://www.selenic.com/repo/hello
abort: repository 'http://www.selenic.com/repo/hello' is not local

正しいやり方は、リモートリポジトリを手元のマシンにcloneして、ローカルにhg logする事です。

これはプロジェクトリーダーのMatt Mackall (mpm)氏による深慮の上の明確な設計意思決定です。その背後にある根拠については、 http://www.selenic.com/mercurial/bts/issue1025 も見てください。

リモートリポジトリに新しいチェンジセットが来ているかどうかは、どうやって調べるの?

リモートリポジトリに有る 最先端チェンジセットチェンジセットidを取得するにはこうします。

> hg id -i -r tip http://www.selenic.com/repo/hello
82e55d328c8c

この値が変われば、リモートリポジトリに新しいチェンジセットが来た事になります。

要らなくなったheadはどうしたらいいんでしょうか?

死にブランチの枝刈りを見ましょう。

cloneコマンドが誤ったバージョンを返します!

Clone コマンドはdefault(別名unnamed)ブランチのtipバージョンをチェックアウトします(NamedBranches 参照)。故に、あなたはきっとメインブランチをunnamedのままにしておきたいと思いますよね。

ファイルの所有者やパーミッションをバージョン管理する方法は?

もしMercurialを設定ファイルの管理に利用しているなら、ファイルのプロパティ(所有者やパーミッション)もバージョン管理したいと思うかもしれません。

これはプロパティをファイルと共に保存する方法の一例です(aclパッケージがインストールされていれば、Linux上で動作します)。

# cd /etc && getfacl -R . >/tmp/acl.$$ && mv /tmp/acl.$$ .acl
# hg commit

この方法は完璧からは程遠いですが、着想点にはなります。さらに洗練されたソリューションを求める場合は、etckeeperをチェックアウトしてください。

push実行時に、"no space left"とか"disk quota exceeded"とか出てきます

Q: push実行時に、"no space left"とか"disk quota exceeded"とかエラーメッセージが出てくるのですが、リモート側のhgリポジトリを置いている場所には十分な空き容量が有るし、クォータ制限も掛けていないのです。

A: この問題はおそらく、mercurialがネットワーク越しに受信したbundleデータを展開する為に/tmp(或いは $TMPDIR, $TEMP$TMP環境変数で定義されたディレクトリ)を使用する事に起因しています。おそらく、展開処理の中でデバイスの制限値に達するのでしょう。

もちろん、リモート側でデフォルトシェルの設定ファイルを書き換えて$TMPDIRを設定する事も出来ますが、それではmercurial以外のプロセスに影響を与える恐れが有ります。別解はリモート側のグローバル.hgrcでフックを設定する事です。push時にリモート側で テンポラリディレクトリを変更する為のフックを設定する方法の説明を見てください。

JapaneseFAQ/CommonProblems (last edited 2009-09-14 12:55:01 by YuyaNishihara)