Diffモードは、M-x
diffやその他の同様のコマンドの出力に使用される主要なモードです。この種の出力は、patchコマンドに渡して指定した変更を自動的に適用できるため、パッチと呼ばれます。Diffモードを手動で選択するには、M-x
diff-modeと入力してください。
パッチで指定された変更はハンクとしてまとめられます。ハンクとは、1つ以上の変更行を含む連続したテキストの塊のことです。通常、変更のコンテキストを提供するために、変更のない行も含まれます。各ハンクの前にはハンクヘッダーがあり、そこではハンクの変更が発生した旧行番号と新行番号が指定されます。Diffモードでは、各ハンクヘッダーをハイライト表示し、ハンクの実際の内容と区別します。
パッチ内の最初のハンクの前にはファイルヘッダーがあり、そこにはファイルの新旧バージョンの名称とタイムスタンプが記載されています。パッチで複数のファイルの変更が示されている場合、各ファイルの変更内容の最初のハンクの前に、同様のヘッダーが配置されます。
Diffモードのバッファは、他のバッファと同様に編集できます。(読み取り専用の場合は、あらかじめ書き込み可能にする必要があります。各種バッファ操作を参照してください。)ハンクを編集するたびに、Diffモードはパッチの正確性を維持し、patchで引き続き適用できるように、ハンクヘッダー内の行番号を自動的に修正しようとします。行番号の自動修正を無効にするには、変数
diff-update-on-the-fly を nil に変更してください。
Diffモードでは、ハンクがM-g M-nやエラーメッセージを扱うその他のコマンドによってコンパイラのエラーメッセージとして処理されるようになります(コンパイルモードを参照)。これにより、コンパイルモードのコマンドを使用して、対応するソース箇所を参照できます。
さらに、Diffモードでは、パッチの一部を移動・操作・適用するための以下のコマンドが用意されています。
次のハンク開始位置 (diff-hunk-next) へ移動する。接頭辞引数 n を指定すると、n 番目の次のハンクへ移動する。
デフォルトでは、DiffモードはEmacsの表示に合わせてハンクを自動的に精緻化し、変更箇所をよりきめ細かくハイライトします。あるいは、diff-refineにシンボルnavigationを設定すれば、Diffモードはこのコマンドまたはdiff-hunk-prevで移動したハンクのみを精緻化します。最後に、diff-refineをnilに設定し、後述するC-c C-b (diff-refine-hunk)を用いて手動でハンクを精緻化することも可能です。
デフォルトでは、ハンクを何らかの方法でリファインすると、リファイン領域の始点または終点をより明確に示すため、リファイン領域の2つの端のいずれかにシャドウカーソルが表示されます。これは変数 smerge-refine-shadow-cursor をカスタマイズすることで制御可能です。
直前のハンク開始位置 (diff-hunk-prev) へ移動します。接頭辞引数 n を指定すると、n 番目の直前のハンクに戻ります。M-n と同様に、このコマンドは diff-refine
にシンボル navigation を設定することで、移動先のハンクを精緻化します。
複数ファイルパッチにおいて、次のファイル先頭へ移動します (diff-file-next)。接頭辞引数 n
を指定すると、その次の n 番目のファイル先頭へ移動します。
複数ファイルパッチにおいて、直前のファイル先頭へ移動します (diff-file-prev)。接頭辞引数 n
を指定すると、n 番目の直前ファイルの先頭に戻ります。
座標 (diff-hunk-kill)
にあるハンクを撃破する。領域が有効な場合は、その領域と重なるすべてのハンクを撃破する。
複数ファイルのパッチでは、現在のファイルパートを終了します。 (diff-file-kill)。
このハンクを対象ファイル(diff-apply-hunk)に適用します。プレフィックス引数にC-uを指定すると、このハンクを元に戻します。つまり、ハンクの逆操作を適用し、「新しい」バージョンを「古い」バージョンに変更します。diff-jump-to-old-fileがnil以外の場合は、代わりにファイルの「古い」バージョンにハンクを適用します。
diff-apply-hunk
は、ファイルの削除やバックアップファイルへのハンク適用の確認を求め、すでに適用済みのハンクを逆適用するオプションを提示します。ただし、リージョンがアクティブな場合は、確認を求めることなく、そのリージョンと重複するすべてのハンクを適用します。このモードでは、いずれかのハンクが正常に適用されなかった場合に単に失敗し、削除やバックアップファイルへのハンク適用の確認は行われません。
このハンクをリバートし、その後ディフからハンクを削除します (diff-revert-and-kill-hunk)。対象ファイルを参照しているバッファを保存します。リージョンがアクティブなとき、このコマンドはリージョンと重複するハンクを逆適用して破棄します。
このコマンドは、C-x v = および C-x v D によって生成されたバッファで有用です(旧リビジョンの確認と比較を参照)。これらのバッファでは行った変更の内容を確認でき、このコマンドを使用して、意図せず行った変更や、不要になった変更を取り消すことができます。
これは破壊的な操作であるため、デフォルトではこのコマンドは、本当にハンクを元に戻して破棄してよいかを確認するよう求めます。diff-ask-before-revert-and-kill-hunk
をカスタマイズすることで、この動作を制御できます。
バッファ (diff-apply-buffer)
内のすべてのハンクを適用します。リージョンがアクティブな場合は、そのリージョンと重なるすべてのハンクを適用し、そうでない場合はすべてのハンクを適用します。接頭辞引数が指定された場合は、ハンクを逆順に適用します。diffが正常に適用された場合は、変更されたバッファを保存します。
現在のハンク以外のハンクを削除します。リージョンがアクティブな場合は、そのリージョンが重なるハンクを削除し、そうでない場合は現在のハンク以外のすべてのハンクを削除します。このコマンドは、ハンクの削除にハンクのファイル名が指定されているバッファ領域へのアクセスが必要なため、狭められたバッファでは動作しません。
ポイントにおけるハンクの変更箇所を、より細かい粒度(diff-refine-hunk)で強調表示します。これにより、変更された各行のどの部分が実際に変更されたのかを正確に確認できます。デフォルトでは、ハンクを精緻化すると、精緻化領域の2つの端のいずれかに「シャドウカーソル」が表示されます。
デフォルトでは、DiffモードはEmacsの表示通りにハンクを整形するため、diff-refineをデフォルト以外の値にカスタマイズしている場合は、このコマンドが便利かもしれません。
このハンク (diff-goto-source)
に対応するソースファイルと行に移動します。デフォルトでは、ファイルヘッダーに最初に表示されるファイルの「新しい」バージョンにジャンプします。接頭辞引数を指定すると、代わりに「古い」バージョンにジャンプします。diff-jump-to-old-file が nil
以外の場合、このコマンドはデフォルトで「古い」ファイルにジャンプし、接頭辞引数の意味が反転します。接頭辞引数が 8 より大きい数値(例:C-u C-u C-c C-c と入力した場合)である場合、このコマンドは次回の実行時に向けて diff-jump-to-old-file も設定します。
ソースファイルがバージョン管理下にある場合(バージョン管理を参照)、デフォルトではワークファイルにジャンプします。プレフィックス引数を指定すると、次のように、diffの旧リビジョンまたは新リビジョンのいずれかに対応するソースコードにジャンプします。
vc-revision-other-window; 旧リビジョンの確認と比較 を参照) の方法で旧ソースファイルへジャンプします。
C-c C-cと同様ですが、diff-jump-to-old-fileは常にnon-nilとなります:旧ソースファイルの対応する行へジャンプします。ソースファイルがバージョン管理下にある場合は、上記と同様に、diffの旧リビジョンまたは新リビジョンのいずれかに対応するソースコードへジャンプします。
パッチ (diff-ediff-patch) で Ediff セッションを開始します。The Ediff Manual の Ediff
を参照してください。
表示範囲を現在のハンク (diff-restrict-view) に制限します。Narrowing
を参照してください。プレフィックス引数を指定すると、複数ファイルパッチの現在のファイルに表示範囲を制限します。再度範囲を広げるには、C-x n w (widen) を使用します。
バッファ全体(diff-reverse-direction)の比較方向を反転します。接頭辞引数を指定すると、現在のリージョン内のみで方向を反転します(マークとリージョンを参照)。方向を反転させるとは、ハンクとファイル開始ヘッダーを変更して、「new」バージョンを「old」バージョンに変更するパッチを生成することを意味します。
ハンクを点 (diff-split-hunk)
で2つの個別のハンクに分割します。これにより、ハンクヘッダーが挿入され、現在のハンクのヘッダーが変更されます。このコマンドはパッチを手動で編集する際に便利であり、diff プログラムの -u または --unified オプションで生成される unified diff
形式 でのみ動作します。diff の -c または --context
オプションで生成される context diff 形式 のハンクを分割する必要がある場合は、まず C-c C-u でバッファを unified diff 形式に変換してください。
バッファ全体をコンテキスト差分形式 (diff-unified->context)
に変換します。接頭辞引数を指定すると、指定した範囲内のハンクのみを変換します。
バッファ全体をユニファイド差分形式 (diff-context->unified)
に変換します。接頭辞引数を指定すると、ユニファイド形式をコンテキスト形式に変換します。マークが有効な場合は、リージョン内のハンクのみを変換します。
現在のハンク (diff-refresh-hunk) を再生成する。
Re-generate the current hunk, disregarding changes in whitespace. With a
non-nil prefix arg, re-generate all the hunks
(diff-ignore-whitespace-hunk). This calls diff-command with diff-ignore-whitespace-switches, which defaults to
‘-b’, meaning ignore changes in
whitespace only.
各ハンク (diff-add-change-log-entries-other-window)
に対して、C-x 4 a のように ChangeLog エントリを生成します(Change Logs
を参照)。これにより、後で実際の変更内容を記入できる変更ログの骨組みが作成されます。Diff モードにおける C-x
4 a
自体は、現在のハンクのファイルに代わって動作しますが、関数名はパッチ自体から取得します。これは、パッチによって削除された関数のログエントリを作成する際に有用です。
パッチには、意図しない望ましくない変更として、変更行の末尾に空白が含まれることがあります。この問題に対処する方法は2つあります。まず、DiffバッファでWhitespaceモードを有効にすると(Useless Whitespaceを参照)、変更行の末尾にある空白が自動的にハイライトされます。次に、コマンド M-x diff-delete-trailing-whitespace を使用すると、パッチによって変更された行の末尾にある空白を検索し、パッチとパッチ適用後のソースファイルの両方からその空白を削除します。このコマンドは行った変更を保存しないため、変更内容を保存するかどうかを判断できます(変更されたファイルの一覧はechoエリアに表示されます)。接頭辞引数を指定すると、パッチ適用後の(「new」)ソースファイルではなく、元の(「old」)ソースファイルを変更しようとします。
diff-font-lock-syntax が nil でない場合、ハンク内のソースの断片は、適切なメジャーモードに従ってハイライトされます。