Differences between revisions 3 and 9 (spanning 6 versions)
Revision 3 as of 2008-12-28 17:54:58
Size: 14778
Editor: mossari
Comment: translate some sections
Revision 9 as of 2009-09-14 12:55:01
Size: 16587
Comment: Inserted partially-translated "I committed a large binary file/files how do I delete them permanently?"
Deletions are marked like this. Additions are marked like this.
Line 5: Line 5:
[:Parent:parent] コマンドを使いましょう[:TutorialClone] 使用例を見れます [[Parent|parent]] コマンドを使いましょう。 ([[JapaneseTutorialClone]] 使用例があります。)
Line 11: Line 11:
=== ユーザ名を変更するには? ===

コミット時にhgが'''No username found, using 'user@hostname instead''''と出力するようなら、ユーザ名設定を行う必要があります。詳細は [[JapaneseQuickStart|クィックスタート]] を参照してください。
Line 19: Line 23:
 * Mercurialのリモート [:Repository:リポジトリ] 指定文法は、rsync, cvsといった他のよく知られたプログラムとは異なります。それらはどちらとも、 {{{USER@REMOTE}}} とパス指定部分との区切りに`:`文字を使います。  * Mercurialのリモート [[Repository|リポジトリ]] 指定文法は、rsync, cvsといった他のよく知られたプログラムとは異なります。それらはどちらとも、 {{{USER@REMOTE}}} とパス指定部分との区切りに`:`文字を使います。
Line 57: Line 61:
{{{hg status}}} は、ファイルの '''内容''' または '''フラグ'''が、'''いずれかの''' [:Parent:parent]と比較して変更が有った時に出力を行います。{{{hg diff}}}は、'''内容'''が最初のparentと比較して変更が有った時のみ出力を行います。 {{{hg status}}} は、ファイルの '''内容''' または '''フラグ'''が、'''いずれかの''' [[Parent|parent]]と比較して変更が有った時に出力を行います。{{{hg diff}}}は、'''内容'''が最初のparentと比較して変更が有った時のみ出力を行います。
Line 62: Line 66:
{{{hg diff}}}や{{{hg export}}}、{{{hg log}}}が出力する[:Diff:diff]は、一貫性を保つ為に、常に最初の[:Parent:parent]に対しての差分を表示します。 {{{hg diff}}}や{{{hg export}}}、{{{hg log}}}が出力する[[Diff|diff]]は、一貫性を保つ為に、常に最初の[[Parent|parent]]に対しての差分を表示します。
Line 81: Line 85:
もし[:Commit:コミット]したばかりで、その後まだ他のいかなるコミットや[:Pull:pull]を実行していないのなら、最後のコミットトランザクションを取り消す為に[:Rollback:rollback]コマンドを使う事が出来ます。 もし[[Commit|コミット]]したばかりで、その後まだ他のいかなるコミットや[[Pull|pull]]を実行していないのなら、最後のコミットトランザクションを取り消す為に[[Rollback|rollback]]コマンドを使う事が出来ます。
Line 94: Line 98:
[:MqExtension:mq extension]の中のstripコマンドも、この場面での操作では有用でしょう。 [[MqExtension|mq extension]]の中のstripコマンドも、この場面での操作では有用でしょう。
Line 98: Line 102:
もし既に公開[:Repository:リポジトリ]に変更をpushしてしまっていて、みんながそこから[:Clone:clone]してしまったのなら、魔物は瓶から解き放たれました。落とし前を付けられるといいですね。 もし既に公開[[Repository|リポジトリ]]に変更をpushしてしまっていて、みんながそこから[[Clone|clone]]してしまったのなら、魔物は瓶から解き放たれました。落とし前を付けられるといいですね。
Line 103: Line 107:

=== デカいバイナリファイルをコミットしてしまいました。どうすれば完全に消せますか? ===
追加してはいけなかったファイルを削除したければ、 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}}}.

別の方法については、一つ前の質問を参照ください。
Line 111: Line 122:
=== コミットしたときにメールを出い ===

CommitHookてください。
=== コミットにメールして欲しい ===

NotifyExtension使ってください。
Line 139: Line 150:
リモート[:Repository:リポジトリ]の.hg/hgrcにこう書くとうまくいきます。 リモート[[Repository|リポジトリ]]の.hg/hgrcにこう書くとうまくいきます。
Line 154: Line 165:
出来ません。 Mercurialが-Rオプションで受け付けるのは、ローカル[:Repository:リポジトリ]だけです({{{hg help -v log}}}参照)。 出来ません。 Mercurialが-Rオプションで受け付けるのは、ローカル[[Repository|リポジトリ]]だけです({{{hg help -v log}}}参照)。
Line 161: Line 172:
正しいやり方は、リモートリポジトリを手元のマシンに[:Clone:clone]して、ローカルに{{{hg log}}}する事です。 正しいやり方は、リモートリポジトリを手元のマシンに[[Clone|clone]]して、ローカルに{{{hg log}}}する事です。
Line 167: Line 178:
リモート[:Repository:リポジトリ]に有る [:Tip:最先端]な[:ChangeSet:チェンジセット]の[:ChangeSetID:チェンジセットid]を取得するにはこうします。 リモート[[Repository|リポジトリ]]に有る [[Tip|最先端]]な[[ChangeSet|チェンジセット]]の[[ChangeSetID|チェンジセットid]]を取得するにはこうします。
Line 178: Line 189:
[:PruningDeadBranches:死にブランチの枝刈り]を見ましょう。

=== The clone command is returning the wrong version in my workspace! ===

[:Clone] checks out the tip of the default (aka unnamed) branch (see NamedBranches). Ergo, you probably want to keep your main branch unnamed.

=== Any way to track ownership and permissions? ===

If you're using Mercurial for config file management, you might want to track file properties (ownership and permissions) too. Mercurial only tracks the executable bit of each file.

Here is an example of how to save the properties along with the files (works on Linux if you've the ''acl'' package installed):
[[PruningDeadBranches|死にブランチの枝刈り]]を見ましょう。

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

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

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

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

これはプロパティをファイルと共に保存する方法の一例です(''acl''パッケージがインストールされていれば、Linux上で動作します)。
Line 195: Line 206:
This is far from perfect, but you get the idea. For a more sophisticated solution, check out ''etckeeper''.


=== I get a "no space left" or "disk quota exceeded" on push ===
I get a "no space left" or "disk quota exceeded" on push, but there is plenty of space or/and I have no quota limit on the device where the remote hg repository is.

The problem comes probably from the fact that mercurial uses {{{/tmp}}} (or one of the directory define by environment variables {{{$TMPDIR, $TEMP}}} or {{{$TMP}}}) to uncompress the bundle received on the wire. The decompression may then reach device limits.

You can of course set {{{$TMPDIR}}} to another location on remote in the default shell configuration file, but it will be potentially used by other processes than mercurial.
Another solution is to set a hook in a global [:hgrc:.hgrc] on remote. See the description of how to set a [:Hook#tmpdirhook:hook for changing tmp directory] on remote when pushing.
この方法は完璧からは程遠いですが、着想点にはなります。さらに洗練されたソリューションを求める場合は、''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|.hgrc]]でフックを設定する事です。push時にリモート側で [[Hook#tmpdirhook|テンポラリディレクトリを変更する為のフック]]を設定する方法の説明を見てください。

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

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)!というエラーメッセージが出てきたのなら、あなたは次の項目を知っておくべきでしょう。

  • Mercurialのリモート リポジトリ 指定文法は、rsync, cvsといった他のよく知られたプログラムとは異なります。それらはどちらとも、 USER@REMOTE とパス指定部分との区切りに:文字を使います。

  • リモートリポジトリのパスは USER$HOME からの相対パスとして扱われます。即ち、上の例では  ~USER/path/to/repo  です。

    • 訳注: もし絶対パスで指定するのを意図していたのなら、この例は  hg clone ssh://USER@REMOTE//path/to/repo  となります。

  • hg -v clone ssh://USER@REMOTE/path/to/repo を使って、sshチャネル経由で実行されるリモート側のコマンドを監視する事も忘れないでください。

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

  • ~/.hgrc[ui]セクションで、remotecmdhgコマンドへの正確なパスを設定します。

  • サーバ上で、適切なPATHを定義する~/.ssh/environmentファイルを作成し、/etc/sshd_configPermitUserEnvironment yesを加えます。

変更を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つも持たないディレクトリは取り扱えません。からっぽのディレクトリはそう便利というものでもなく、実装が複雑になりかねないのですぐに修正するつもりはありません。以下のような解決策を用いてください:

  • "this-dir-intentionally-left-blank" のようなファイルを追加する
  • Makefileなどのビルドプロセスでディレクトリを生成する

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

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)