Next: , Previous: , Up: Files   [Contents][Index]


18.10 Diffモード

Diffモードは、M-x diffや他の同様なコマンドの出力のために使用されるメジャーモードです。この種の出力はpatchと呼ばれます。なぜならそれが特定の変更を自動的に適用するために、patchコマンドに渡されるからです。手動でDiffモードを選択するには、M-x diff-modeとタイプします。

パッチに指定された変更は、hunk(欲張り)にグループ化されます。これは変更された行を1行以上含むテキストと、それに隣接するテキストです。hunksもまた、変更のコンテキストを提供するために、変更されていない行も含みます。それぞれのhunkにはhunkヘッダーが前についていて、これはhunkの変更が発生した、古い行番号と、新しい行番号が指定されます。Diffモードは実際のhunkの内容と区別するため、hunkヘッダーをハイライトします。

パッチ内の最初のhunkの前にはファイルヘッダーがあり、それはそのファイルの新たなバージョンと古いバージョンの名前と、それらのタイムスタンプを示します。パッチが複数ファイルの変更を表す場合、各ファイルがそのファイルの変更の最初のhunkの前にそのようなヘッダーをもつことになります。

他のバッファーと同様に、Diffモードのバッファーを編集することができます(もし読み込み専用の場合、最初にそれを書き込み可にする必要があります。Misc Bufferを参照のこと)。hunkを編集すると、Diffモードはpatchを正しい状態に保ち、patchにより正しく適用できるように、hunkヘッダーの行番号を自動的に修正しようと試みます。自動的な行番号の修正を無効にするには、変数diff-update-on-the-flynilに変更してください。

Diffモードは、C-x `やエラーメッセージを処理する他のコマンドによりコンパイラーのエラーメッセージとして扱われるようにhunkをアレンジします(Compilation Modeを参照)。したがって、対応するソースの位置をvisitするために、Compilationモードのコマンドを使用できます。

それに加えてDiffモードは、移動、操作、patchの一部を適用するために、以下のコマンドを提供します:

M-n

次のhunk-startに移動します(diff-hunk-next)。プレフィクス引数を指定した場合は、次のn番目のhunkに前方へ移動します。

このコマンドには副作用があります。これは移動先のhunkをrefines(不純物を取り除く)して、よりよい粒度で変更をハイライトします。この機能を無効にするにはM-x diff-auto-refine-modeとタイプして、マイナーモードのDiff Auto-Refineモードをオフに切り替えます。デフォルトでDiff Auto-Refineモードを無効にするには、以下をinitファイルに追加します(Hooksを参照してください):

(add-hook 'diff-mode-hook
          (lambda () (diff-auto-refine-mode -1)))
M-p

前のhunkが開始される位置に移動します(diff-hunk-prev)。プレフィクス引数を指定した場合は、前のn番目のhunkに後方へ移動します。これはM-nと同様、Diff Auto-Refineモードが無効でなければ、移動先のhunkをrefiningする副作用があります。

M-}

複数ファイルへのpatchで、次のファイルが開始される位置に移動します(diff-file-next)。プレフィクス引数を指定した場合は、次のn番目のファイルの先頭へ、前方に移動します。

M-{

複数ファイルへのpatchで、前のファイルが開始される位置に移動します(diff-file-prev)。プレフィクス引数を指定した場合は、前のn番目のファイルの先頭へ、後方に移動します。

M-k

ポイントがある位置のhunkをkillします(diff-hunk-kill)。

M-K

複数ファイルへのpatchで、現在のファイル部分をkillします(diff-file-kill)。

C-c C-a

そのhunkを、ターゲットファイルに適用します(diff-apply-hunk)。C-uによるプレフィクス引数を与えた場合は、このhunkをリバート(“新しい”バージョンを“古い”バージョンに変更するリバースhunkを適用する)します。diff-jump-to-old-fileが非nilなら、かわりにsのhunkを“古い”バージョンに適用します。

C-c C-b

ポイント位置のhunkの変更を、よりよい粒度でハイライトします(diff-refine-hunk)。これにより変更された各行について実際に変更された箇所を確実に見ることができます。

C-c C-c

そのhunkに対応するソースファイルの該当行にジャンプします(diff-goto-source)。デフォルトでは、ファイルヘッダーの最初に示される、“新しい”バージョンのファイルにジャンプします。プレフィクス引数を与えた場合は、かわりに“古い”バージョンにジャンプします。diff-jump-to-old-fileが非nilなら、このコマンドはデフォルトで“古い”バージョンにジャンプし、プレフィクス引数の意味も逆になります。プレフィクス引数が8より大(たとえばC-u C-u C-c C-cとタイプした場合)なら、このコマンドは次回呼び出しにたいしてdiff-jump-to-old-fileのセットも行います。

C-c C-e

このパッチでEdiffセッションを開始します。Ediff in The Ediff Manualを参照してください。

C-c C-n

表示を現在のhunkに制限します(diff-restrict-view)。Narrowingを参照してください。プレフィクス引数を指定すると、複数ファイルへのpatchで、表示を現在のファイルに制限します。制限を解除するには、C-x n w (widen)を使います。

C-c C-r

バッファー全体にたいする比較方向を逆転します(diff-reverse-direction)。プレフィクス引数を与えた場合は、カレントリージョンの内部でのみ方向を逆転します(Markを参照)。方向の逆転とは、hunkとファイル冒頭のヘッダーを、“新しい”バージョンから“古い”バージョンにするパッチを生成するように変更することを意味します。

C-c C-s

ポイント位置でhunkを2つの別個のhunkに分割します(diff-split-hunk)。これはhunkヘッダーの挿入ち、カレントhunkのヘッダーの変更を行います。これは手動でpatchを編集するために有用で、diffプログラムに-uまたは--unifiedオプションを指定して生成された、unified diff format(統一diffフォーマット)だけで機能します。diff-cまたは--contextオプションを指定して生成された、context diff format(コンテキストdiffフォーマット)のhunkを分割するには、最初にC-c C-uで、バッファーをunified diff formatに変換する必要があります。

C-c C-d

バッファー全体を、context diff formatに変換します(diff-unified->context)。プレフィクス引数を指定すると、リージョンのhunkだけを変換します。

C-c C-u

バッファー全体をunified diff formatに変換します(diff-context->unified)。プレフィクス引数を指定すると、unified formatからcontext formatに変換します。マークがアクティブのときは、リージョンのhunkだけを変換します。

C-c C-w

空白文字の変更を無視して、カレントhunkを再生成します(diff-ignore-whitespace-hunk)。

C-x 4 A

それぞれのhunkについて、C-x 4 aが行うようにChangeLog(Change Logを参照してください)のエントリーを生成します(diff-add-change-log-entries-other-window)。これは、あとで実際に変更の説明を記入できるように、変更ログの雛形を作ります。DiffモードでのC-x 4 a自体は、現在のhunkのファイルのためのものですが、関数名はpatch自体から取得します。これはpatchにより削除される関数のための、ログエントリーを作るのに有用です。

patchには変更された行の行末に、無意識に入力された望んでいない空白文字が含まれている場合があります。この問題を扱うには2つの方法があります。1つ目はDiffバッファーでWhitespaceモード(Useless Whitespaceを参照してください)を有効にする方法で、これは自動的に変更された行の行末にある空白文字をハイライトします。2つ目はコマンドM-x diff-delete-trailing-whitespaceを使う方法で、patchにより変更された行の行末の空白文字を検索して、patchとpatchされたソースファイルの両方からそれを取り除きます。このコマンドは変更を保存しないので、ユーザーが変更を保存するか決定することができます(変更されたファイルはエコーエリアに表示されます)。プレフィクス引数を指定すると、patchされた(“新しい”)ファイルではなく、元の(“古い”)ソースファイルを変更しようと試みます。