コミット
========

.. module:: commit.dialog
	:synopsis: コミットを実行するダイアログ

.. warning::
	win32text 拡張機能はハンク選択で問題を引き起こす可能性があります。この問題は
	Mercurial 1.3 と TortoiseHg 0.8 において解決されましたが、適切な設定が
	必要です。詳しくは
	`issue #82 <https://bitbucket.org/tortoisehg/thg/issue/82/>`_
	をご覧ください。

コミットツールは TortoiseHg に2つある主要アプリケーションのうちの1つです。
リポジトリエクスプローラ (別名: チェンジログビューア) と共にこれら2つのツールは
TortoiseHg が実装しているほぼすべての機能にアクセスできます。

コミットツールは変更点をコミットするだけではなく、作業ディレクトリの状態の確認や、
その他にも様々な作業 (新規ファイルの追加、名前変更の記録、
リポジトリの無視フィルタの編集、など) もコミットツール上で行なえます。

.. figure:: figures/commit.png
	:alt: コミットダイアログ

	コミットダイアログ

機能
----

コミットツールの一番上にはバージョン 0.9 から導入されたメニューバーがあります。

	:guilabel:`ツール`
		TortoiseHg の各種ツールを別プロセスで起動します。
	:guilabel:`表示`
		オプション機能の表示切り替えと、作業ディレクトリの表示内容を再読み込みします。
	:guilabel:`操作`
		ツールバーのボタンと同じ操作を実行できます。
	:guilabel:`ヘルプ`
		システム既定のウェブブラウザでコミットツールに関するヘルプを開きます。
		また TortoiseHg のバージョン情報を表示します。

その下のツールバーにあるボタンを左から順に見ていきます：

	:guilabel:`コミット`
		チェックされたファイルの選択されたハンクをコミットします。
	:guilabel:`取り消し`
		直前のコミットを取り消します。入力したコミットメッセージは
		:guilabel:`最近コミットしたメッセージ` の一覧に追加されるため、
		コミットミスを修正した後に同じメッセージでコミットできます。
	:guilabel:`差分`
		チェックされているファイルを GUI 差分ツールで表示します。
	:guilabel:`元に戻す`
		チェックされているファイルを変更を加える前の状態に戻します。
		その変更がマージの場合はどちらの親リビジョンに戻すか選択できます。
	:guilabel:`追加`
		チェックされている不明ファイル '?' または無視ファイル 'I' を追加します。
	:guilabel:`移動`
		チェックされているファイルを指定されたディレクトリに移動します。
	:guilabel:`削除`
		チェックされているファイルを削除します。
	:guilabel:`破棄`
		チェックされている管理済みファイルを破棄します。
	:guilabel:`再読み込み`
		作業ディレクトリの状態を再読み込みします。
		再読み込み後もチェックボックスの選択状態は保たれます。
	:guilabel:`MQ`
		MQ パネルの表示を切り替えます。このボタンは MQ 拡張機能がユーザによって
		有効化されているときのみ表示されます。

ツールバーの下にはいくつかの便利なウィジェットがあります：

	:guilabel:`ブランチダイアログ`
		作業ディレクトリの現在のブランチ名を表示します。通常はブランチ名の表示のみですが、
		このボタンを押すとブランチ操作のためのダイアログが表示されます。
		この機能は Mercurial の
		`名前付きブランチ <https://www.mercurial-scm.org/wiki/NamedBranches>`_
		を理解している場合のみ使用してください。
	:guilabel:`最近コミットしたメッセージ`
		最近のコミットメッセージ 10 件のドロップダウンリストです。
		このリストは最初に開いた時にコミットメッセージが読み込まれます。
	:guilabel:`QNew`
		MQ 拡張機能を使用している場合、新しいパッチ名を入力するためのテキストボックスが
		表示されます。パッチ名を入力するとコミットツールは 'QNew' モードに切り替わります。


ファイル一覧には4つの列があります：

	1) 各種操作のためにそのファイルが選択されているかどうかを示すチェックボックス。
	   ツールバーボタンによる操作はチェックされているファイルにのみ行なわれます。
	   部分選択状態のファイルについては特殊なチェック状態となります。
	   この列のヘッダを使えばすべてのファイルをチェックしたりチェックを外したりできます。
	2) :guilabel:`状態` 列には Mercurial の status コマンドで使用されている
	   ファイル状態を示す 'MARD?IC' のうちの1つが表示されます。'S'
	   は未コミットの変更を含むサブリポジトリを意味します。
	3) :guilabel:`マージ` 列はそのファイルのマージ状態を示しており、Mercurial の
	   resolve コマンドで使用されている ' RU' のうちどれか1つが表示されます。
	4) リポジトリルートを基準としたファイルパスが表示されます。

.. note::
	コミットツールがファイルパターンまたは特定のファイルを選択した状態で起動された場合、
	ファイル一覧の下にそれらのフィルタを削除して作業ディレクトリにおける変更すべてを
	表示するためのボタンが表示されます。

ファイル一覧の下に並んだチェックボックスは
{M:変更, A:追加, R:削除, !:削除, ?:不明, C:クリーン, I:無視}
のファイル状態ごとにファイル一覧に表示するかどうかを設定できます。
このチェックボックスはコミットツールからファイルまたはディレクトリを指定された場合には
無効になります。

*R:削除* は管理済みファイルが Mercurial の管理から外されたことを示しています。
一方で *!:削除* は管理済みファイルが見当たらず、Mercurial がそのファイルを
追跡できなくなったことを意味しています。例えば管理済みファイルの名前をエクスプローラで
変更したとき、コミットツールのファイル一覧には元のファイル名が *!:削除* として表示され、
新しいファイル名が *?:不明* として表示されます。新しいファイル名の右クリックメニューから
名前変更推定ダイアログを起動すればファイル内容の比較によって名前変更を検出し、
古いファイルを *R:削除* とマークし、新しいファイルを *A:追加* とマークすることができます。

*?:不明* は Mercurial によって管理されておらず、かつ、設定されている
無視ファイルフィルタにマッチしないファイルに表示されます。リビジョン管理に
追加する必要のあるファイルなどはデフォルトで不明ファイルとして表示されます。
無視ファイルフィルタを最新に保つことは良い習慣です。不明ファイルの
右クリックメニューには無視ファイルフィルタを編集するツールを開くコマンドがあります。

*C:クリーン* は変更が加えられていない管理済みのファイルです。
一方で *I:無視* は設定されている無視ファイルフィルタに該当する管理外のファイルです。
どちらのファイルもエクスプローラでの選択に含めるか、
コマンドラインからそのファイル名を指定して起動しない限りデフォルトでは表示されません。

.. figure:: figures/parentbar.png
	:alt: 親リビジョンバー

	コミットツールの親リビジョンバー

ファイル一覧と差分表示パネルの下には *親リビジョンバー* があります。
ここには現在の作業ディレクトリの親にあたるチェンジセットが表示され、
コミットによって新しくヘッドが作成されるかどうか見ることができます。
このバーは :guilabel:`表示` メニューから非表示にできます。

ファイル一覧の右側は差分表示パネルになります。バージョン 0.9 から差分表示パネルが
タブ表示になりました。

	:guilabel:`テキスト差分`
		選択しているファイルの差分をテキストで表示します。
	:guilabel:`ハンク選択`
		バージョン 0.7 から 0.8 まではこのタブは単純に内容を表示するだけでしたが、
		0.8 からはハンク選択機能が実装され、変更点の一部を選択してコミットできる
		ようになりました。このタブには選択されているファイルの差分ハンクが表示されますが、
		バイナリファイルは表示されません。内容の確認は :guilabel:`テキスト差分`
		タブで行ってください。
	:guilabel:`コミットプレビュー`
		このタブにはすべての選択されたハンクが表示されます。実質的にこのプレビューには
		コミットボタンを押したときに何がコミットされるかが表示されます。
	:guilabel:`パッチ内容`
		コミットツールがパッチ更新モードのときにのみ表示されます。
		ここには現在のパッチ内容が表示されます。

.. figure:: figures/advancedbar.png
	:alt: 詳細設定バー

	コミットツールの詳細設定バー

:guilabel:`表示` メニュー で :guilabel:`詳細設定` を有効にした場合、
ツールバーとコミットログ履歴の間に詳細設定バーが挿入されます。このバーには:

	:guilabel:`コミッタ`
		コミットに使用するユーザ名です。この値は通常 Mercurial.ini ファイルから
		読み込まれますが、コマンドラインやパッチファイルから読み込んで指定すること
		もできます。直接入力することで異なるユーザを指定することも可能です。
	:guilabel:`自動的に含む`
		ファイルにチェックを入れたかどうかに関わらず、常にコミットに含めたい
		ファイルをカンマ区切りで指定するためのテキストボックスです。
		この機能はリポジトリの pre-commit フックによってコミット時に自動更新される
		ファイル (例えば changelog ファイル) などを常にコミットに含めたい、
		というときに便利です。
	:guilabel:`コミット後にプッシュ`
		コミットが正常に完了した後、デフォルトの URL にプッシュするかどうかを
		設定するチェックボックスです。


変更点の選択
------------

さて、「チェックされたファイルの選択されたハンクをコミットする」と言ったとき、
それは何を意味しているのでしょうか？ TortoiseHg のコミットツールには
変更点の一部のみをコミットする機能が標準で備わっているため、
単純にそれを使うという意味になります。
つまり、管理下に置かれたファイルに対するすべての変更箇所は、どの部分をコミットに含めて、
どの部分をコミットせずに (作業ディレクトリに) 残すのか個別に選択することができます。
darcs バージョン管理システム、または Mercurial の record 拡張機能のユーザであれば
すぐに分かるはずです。

どんなとき必要になるのか？
^^^^^^^^^^^^^^^^^^^^^^^^^^

関連性の低い複数の変更が作業ディレクトリにあり、それらを個別のチェンジセットとして
コミットしたいとします。この場合、コミット時にファイル一覧を指定することでうまく
対処できるケースもありますが、同じソースコードに変更点が混ざり合っているケースでは
コミットする変更点を選択する機能が必要不可欠になります。

どうやって使うのか？
^^^^^^^^^^^^^^^^^^^^

差分表示パネルの :guilabel:`ハンク選択` タブでチェンジハンクをダブルクリックすることで
そのハンクの選択状態を切り換えることができます。
*厳密には選択状態はアクティベート操作によって切り替わるため、ダブルクリックでは
なくスペースキーを押すことでも可能です。* ハンクが選択解除されると差分パネルの
色分け表示が無効になり、背景色がグレーになります。それと同時にファイルの差分ヘッダ
が更新され、現在選択されているハンクの数と行数が表示されます。もう一度
ダブルクリックしてハンクを選択することでコミットにその変更を含めることができます。

ファイル内の変更が部分的に選択されているとき、ファイル一覧に表示されるそのファイルの
チェックボックス表示がラジオボタンのようになります。これにより、次のコミットで
各ファイルの全体がコミットされるのか、部分的にコミットされるのか一目で分かります。

コミットするとどうなるのか？
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

簡単に言ってしまえば、チェックの入ったファイル内の選択されたハンクがリポジトリに
コミットされ、選択されなかった変更点は作業ディレクトリに残り、次のコミットに
持ち越されます。

実際には少々複雑なことをしています。その裏側で何が起こっているのかというと、
選択されなかったハンクのバックアップを安全な場所に作成した後、作業ディレクトリの
内容が最新リビジョンの状態に戻し、クリーンな状態にします。そして選択された変更点
のみが作業ディレクトリに書き戻されて、この状態でコミットされます。
最後にバックアップから選択されなかったハンクが作業ディレクトリに復元されます。
ハンク選択されなかったファイルは *バックアップ、書き戻し、コミット、復元* の
一連の処理はされません。

このハンク選択機能の内部処理に関する記述は、不運にも処理に失敗したときに役に立つ
かもしれません (Windows ではその可能性がゼロであると言い切れないため)。
何らかのプログラム (アンチウイルスソフト、コンパイラなど) が処理の過程で生成された
一時ファイルをロックしてしまった場合、書き戻しに失敗したというエラーが発生する
かもしれません。しかしこれらのエラーは修復できます。リポジトリにある :file:`.rej`
ファイルを削除してからもう一度コミットを試みてください。


キーボードショートカット
------------------------

:kbd:`Ctrl-Enter`
	コミットを実行します
:kbd:`Ctrl-C`
	差分表示パネルでこのショートカットを押すと、ハイライト (選択ではない) されている
	ハンクの内容がクリップボードにコピーされます。作業ディレクトリの変更から任意の
	変更点をテキストとしてどこかにペーストするのに使えます。
:kbd:`Alt-Q`
	カーソルのある段落(空行で区切られた行)を空白で連結して1行にします。このショートカット
	を使用するにはフォーマットポリシーの設定が必要です。

クリップボードにコピーされるハンクは気が利いていて、差分のヘッダ情報が付加されます。
つまり、クリップボードの内容はいつでも正しいパッチとして使えるというわけです。


ファイルの右クリックメニュー
----------------------------

ファイル一覧のファイルの上で右クリックすると、選択されたファイルに対する
コマンドを含むメニューが表示されます。

不明ファイル **?** の右クリックメニューには名前変更を検出するコマンド
(不明ファイルが管理下にあったファイルのコピーまたは名前変更されたものだと
考えられる場合) や、リポジトリの無視フィルタを編集するするコマンド
(その不明ファイルを今後もリビジョン管理することはなく、Mercurial にそれを
無視して欲しい場合) が提供されます。


マージ作業
----------

マージ状態のリポジトリを開いたとき (正確には現在の作業ディレクトリが2つの
親リビジョンを持っているとき) コミットツールは特別なモードに切り替わります。
ファイル一覧にはチェックボックスが表示されず、差分表示パネルの
:guilabel:`ハンク選択` タブは非表示になります。
マージ後に作業ディレクトリ全体をコミットしなければならないため、
基本的にコミットマニフェストは不変です。

このモードではマージ状態を示す *ms* 列が特に役に立ちます。この *ms* 列で
*R* というマークが付いたファイルは Mercurial またはユーザによって2つの
親リビジョンから正しくマージ (衝突の解決) されたファイルです。 *U* マーク
付いたファイルは未解決のファイルです。そのファイルのマージ作業を再開するには
右クリックメニューの *衝突の解決* メニューを選択するか、 *編集* メニューで
ファイルを開いて手動で衝突を解決します。 *衝突の解決* メニューからマージ作業を
開始すると、その都度マージツールを変更できるため、ファイルごとに適切な
マージツールを使用することができます。衝突を解決したら *解決済みとしてマーク*
メニューを選択してファイルのマージ状態を手動で *R* に変更します。

Mercurial は1つでもマージ状態が *U* となっているファイルがあるとコミットを
中止します。

*ローカル* はマージを始めたときにチェックアウトされていたリビジョンで、
*他のリビジョン* はマージ対象のリビジョンです。

失敗したマージ作業を取り消すには2つ目の親リビジョンによる変更点を作業リポジトリ
から削除するために Mercurial に知らせなければなりません。
これは通常1つ目の親リビジョンへのクリーンな (ローカルでの変更を上書き) 更新を
意味します。マージツールにはまさにその操作のための :guilabel:`取り消し`
ボタンがあります。これはリカバリツールの :guilabel:`クリーン` ボタンを
押しても同じ結果になります。

作業ディレクトリをどちらかの親リビジョンに戻せば再びマージ作業を始めることが
できます。


コミットメッセージパネル
------------------------

コミットメッセージパネルは以下の特別な右クリックメニューがあります:

	:guilabel:`ファイル名を貼り付け`:
		チェックの入っているファイル名ををコミットメッセージのカーソル位置に
		貼り付けます。
	:guilabel:`フォーマットポリシーの適用`:
		設定されたメッセージの折り返しポリシーを現在のメッセージに適用します。
	:guilabel:`フォーマットポリシーの設定`:
		設定ダイアログの :guilabel:`コミット` ページを開きます。

プロジェクトにコミットメッセージのルールがある場合はそれらを設定ダイアログで
変更できます。コミットツールは設定されたポリシーをコミット時にチェックし、
コミット前でもポリシーに沿ったメッセージになっているか確認できます。
設定ダイアログの :guilabel:`コミット` ページにはコミットメッセージポリシーの
設定項目が2つあります:

	:guilabel:`要約行最大文字数:`
		コミットログ最初の行 (要約行) の最大文字数。これが設定された場合、
		要約行が長すぎる、もしくは要約行とそれ以降のログが空行で区切られていないときに
		警告が表示されます。デフォルト：0 (制限しません)。

	:guilabel:`コミットログ折り返し文字数:`
		コミットログの折り返し文字数。これが設定された場合、コミットログ中の1行でも
		設定文字数を上回っていると警告が表示され、その文字数で強制的に折り返すための
		ポップアップメニューが表示されます。デフォルト：0 (制限しません)。


MQ パッチ
---------

多くの Mercurial 上級者はパッチの管理に MQ 拡張機能を使っていることでしょう。
コミットツールはパッチが適用されているとき *パッチ更新* モードに切り替わります。
ダイアログのタイトルは "パッチ更新 *パッチ名*" となり、コミットメッセージパネル
にはそのパッチのコメントが表示されます。

差分表示パネルの :guilabel:`パッチ内容` タブには現在のパッチ内容がすべて表示されます。
:guilabel:`テキスト差分` と :guilabel:`ハンク選択` タブにはパッチ内容に加えて
作業ディレクトリでの変更点も合わせて表示されます。ハンク選択機能を使えば現在の
パッチから変更点の一部を別のパッチに移動 (またその逆も) することができます。

これは実質的に :command:`qdiff` コマンドを実行したときの内容が表示されます。
コマンドラインから実行する :command:`hg diff` のように作業ディレクトリに
おける変更点のみを表示する方法はありませんが、新しいパッチ名を入力する
テキストボックスに何か1文字でも入力すれば *パッチ作成* モード (後述) に
切り替わるので、作業ディレクトリにおける変更のみを見ることは一応できます。

:guilabel:`コミット` ボタンを押すことで (パッチ更新モードではラベルが
:guilabel:`パッチ更新` に変化します) は現在のパッチ内容を選択されている変更点に
コミットメッセージと共に更新 (qrefresh) します。更新後も除外した変更点は
作業ディレクトリに残り、ファイル一覧や差分表示パネルに表示される内容は何も
変化しないため、最初は少し戸惑うかもしれません。


QNew モード
-----------

コミットツールから MQ のパッチを作成できます。 MQ 拡張機能が有効になっている場合、
ブランチボタンとコミットメッセージ履歴のドロップダウンリストの間にテキストボックスが
表示されます。このテキストボックスにパッチ名を入力し始めるとコミットツールは *コミット*
または *パッチ更新* モードから *パッチ作成* モードに切り替わり、差分表示パネルには
現在の作業ディレクトリにおける変更点が表示されます。正常にモードが切り替わると
:guilabel:`コミット` ボタンが :guilabel:`QNew` ボタンに変化するので一目瞭然です。

:guilabel:`QNew` ボタンが押されると選択されている変更点のハンクが入力された
名前の新しいパッチに書き込まれ、ダイアログが再読み込みされます。これにより、
少なくとも1つ適用済みのパッチが存在するため、ダイアログは *パッチ更新* モード
に切り替わります。

パッチのコミットメッセージは *パッチ作成* モードのときに入力することもできますし、
作成後の *パッチ更新*  モードで更新することもできます。

パッチ作成時に変更点の一部を除外した場合、その変更点も差分表示パネルの新しいパッチ
の中に表示されますが、これは前述の通り *パッチ更新* モードが現在のパッチ内容と
作業ディレクトリの変更点をまとめて表示するためです。ここで再びテキストボックスに
パッチ名の入力を始めるとコミットツールは再度 *パッチ作成* モードに移行し、
差分表示パネルには作業ディレクトリに残った (先ほどのパッチ作成で除外した)
変更点が表示されます。


オプション設定
--------------

:menuselection:`コミット --> ユーザ名`
	コミットに関連付けるユーザ名を設定します (:doc:`quick`)
:menuselection:`コミット --> 要約文字数`
	要約行の文字数を制限するポリシーを設定します
:menuselection:`コミット --> メッセージ文字数`
	コミットメッセージ各行の文字数を制限するポリシーを設定します

これに加えて上級者向けの3つのオプションがあります。

:menuselection:`コミット --> コミット後にプッシュ`:
	True にすることで *コミット後にプッシュ* チェックボックス	の初期値として
	使用されます。
:menuselection:`コミット --> 自動コミットファイル`:
	コミットに自動的に含めたいファイルをカンマ区切りで指定します。
	通常はユーザ設定ではなくリポジトリ設定で使用します。
:menuselection:`コミット --> 自動除外ファイル`:
	ステータス、コミット、シェルフツールにおいて自動的にチェックを外したい
	ファイルをカンマ区切りで指定します。

:menuselection:`TortoiseHg --> 差分を画面下部に表示`
	差分表示パネルをファイル一覧の右側から下に切り替えます
:menuselection:`TortoiseHg --> 最大差分サイズ`
	表示する差分の上限サイズを設定します

外部ツールの設定はバージョン 0.9 で廃止されました。


コマンドラインからの実行
------------------------

コミットツールはコマンドラインから起動することもできます： ::

	hgtk commit [OPTIONS] [FILE]...

	aliases: ci

	commit tool

	options:

	 -u --user  record user as committer
	 -d --date  record datecode as commit date

	use "hgtk -v help commit" to show global options

日付の書式は： ::

	hg help dates

から見ることができます。

.. vim: noet ts=4
