テキストの差分とマージ
2つのバージョンのテキストを貼り付けて、色付きの差分で行ごとに比較します。
比較結果
仕組み
- 2つのテキストを貼り付け: 左のパネルに元のテキスト、右のパネルに改訂テキストを入力します。
- 違いを確認: 変更された行が強調表示されます, 追加は緑、削除は赤、変更は黄色。
- 差分を閲覧: 色付きの変更をスクロールして、必要な部分をコピーまたはスクリーンショットで取得します。
Diffの簡単な歴史
現代のテキストdiffはBell Labsで始まりました。Douglas McIlroy(Unixパイプを発明したのと同じMcIlroy)とJames W. Huntは1970年代初頭にオリジナルのUnix diffを書きました; これは1974年のUnix第5版の一部として出荷されました。アルゴリズムはBell Laboratories Computing Science Technical Report #41(1976年6月)に「An Algorithm for Differential File Comparison」というタイトルの内部レポートとして文書化されました。Hunt-McIlroyアルゴリズムは最長共通部分列(LCS)問題の上に構築されています。両方の入力に順番に現れる最長の行のシーケンスを見つけ、そのシーケンスにないものはすべて削除または挿入のいずれかです。10年後、Eugene W. MyersはAlgorithmica第1巻第2号(1986年)で「An O(ND) Difference Algorithm and Its Variations」を発表しました。Myersは問題を「edit graph」上の最短経路探索として再構成し、それがO(ND)の時間と空間で解けることを示しました。ここでNは入力サイズ、Dは最小編集スクリプトのサイズです。典型的な入力、わずかな場所だけが異なるファイルでは、Dは小さいので、アルゴリズムは実用的には高速です。Myersの論文はより高速なUnix diff実装の基礎となり、前任者より2〜4倍速く実行され、より高品質な出力を生成しました。Patience diff(Bram Cohen、2008)はユニークなアンカー行に優先順位を付けるLCSの改良で、移動されたブロックの周りでより読みやすいdiffを生成します。現在のgit diffのデフォルトはLibXDiffのhistogramアルゴリズムで、一般にバニラMyersより高速であり、移動されたブロックがある場合により読みやすいdiffを生成すると見なされています(2016年11月29日にリリースされたGitの2.11でデフォルトになりました)。数学的基盤はさらに深く: Levenshtein距離(Vladimir Levenshtein、1965)はLCS問題の文字レベルのいとこであり、Wagner-Fischer動的計画法ソリューション(1974)はすべての「ファジーマッチ」ライブラリが今も内部で実装しているものです。
Diffがどのようにレンダリングされるか
diffを表示するための4つの一般的な視覚的慣習があります。サイドバイサイド、2つのカラム、左が元、右が変更後、対応する行が整列されています。一目で比較するのに良い; デスクトップ幅ではうまく機能しますが、狭いモバイルビューポートでは読みにくくなります。インライン統一diff、削除された行(通常-でプレフィックス、赤で色付け)、追加された行(+、緑)、変更されていないコンテキスト行(プレフィックスなし、プレーンテキスト)を表示する単一カラム。git diffがデフォルトで使用するレイアウト。モバイルにうまくスケールしますが、サイドバイサイドの空間的並列性を失います。単語レベルdiff、変更された行内で変更された単語のみを強調表示します。テキストのほとんどが変更されていないが特定のフレーズが編集された散文比較に便利です。文字レベルdiff、変更された各文字を個別に強調表示します。単語レベルでは全単語を強調表示する非常に小さな変更(タイポ修正、1桁の編集)に便利です。色の慣習はエコシステム全体で著しく一貫しています: 追加には緑、削除には赤、変更された値には黄色または琥珀色、変更されていないものには中立的なグレーまたはスタイルなし。このツールは変更された行内の文字レベルのハイライトを伴うインライン統一スタイルを使用しており、モバイルにうまくスケールしながら散文編集のための文字レベル比較の精度を維持するハイブリッドです。
3-way merge、2つのdiffが結合する必要がある場合
2-way diff(このツール)は、バージョンAとバージョンBの間で何が変わったかを教えてくれます。3-way mergeはより困難な質問に答えます: 共通の祖先と2つの分岐したリビジョンを与えられた場合、両方の変更セットを組み込む結合結果は何ですか?これはすべてのバージョン管理システムの中核操作です。2人の開発者が同じファイルを独立して編集し、1人が自分の作業をマージしようとすると、システムは両方のdiffを元のものに適用する必要があります。Khanna、Kunal、Pierce(2007)によって形式化されたdiff3アルゴリズムが基礎です。7文字の競合マーカー慣習、<<<<<<<、=======、>>>>>>>、自動マージが失敗したときにGitがファイルに挿入するものは、この系譜から直接来ています。モダンな視覚マージツール(VS Codeの3ペインマージエディタ、2022年6月の1.69からデフォルトオン; Scooter SoftwareのBeyond Compare、1996年以来; Meld; Black PixelによるmacOS向けKaleidoscope)は、3-wayマージを3つすべてのバージョンのサイドバイサイドレンダリングと提案されたマージ結果のための4番目のペインで処理します。このツールは2-way比較に焦点を当てています。3-wayマージは本物のバージョン管理ワークフローに属します。
一般的なユースケース
- コードレビュー。 関数やモジュールの2つのバージョンを貼り付けて変更を素早く特定する、特にGitワークフローの外で作業する場合(同僚のメールからのスニペット、Stack Overflowの回答対現在のコード)。
- 法律契約の比較。 弁護士と契約交渉者は、相手側が何を変更したかを確認するために契約の2つのバージョンを日常的に比較します。法務テック用語は「blackline」または「redline」比較; Draftableのような製品がこれに特化しています。
- 散文編集。 ライターのドラフトをエディタの改訂と比較したり、記事の2つのバージョンを比較したりします。Microsoft Wordの変更履歴は製品内でこれを行います; プレーンテキストまたはMarkdownのドラフトには、diffツールが同等です。
- 構成ドリフト。 本番環境の構成ファイルをソース管理のバージョンと比較する、そのギャップがドリフトです。環境固有の構成(dev対staging対production)についても同じワークフローです。
- ログ比較。 同じプロセスの異なる実行からの2つのログファイルのdiffを取って、分岐点を見つけます。
- ローカライゼーションレビュー。 翻訳者は、新しい英語ソースを以前のバージョンと頻繁にdiffして、何が新しいか、翻訳が必要かを正確に特定します。
2026年のdiffエコシステム
git diffとUnix diffを超えて、いくつかの特殊化されたdiffツールが言及に値します。Beyond Compare(Scooter Software、1996)は長年の商用フォルダおよびファイル比較ツールで、クロスマシンdiffのために開発者とIT専門家に人気です。Meld(オープンソース、GTKベース)はGNOMEのデフォルトです。Kaleidoscope(Black Pixel、macOS)はバージョン管理と統合され、多くのMac開発者にとって事実上の選択肢です。VS Codeの組み込みdiffエディタは2-wayおよび3-way比較をネイティブで処理します; 3ペインマージエディタは1.69(2022年6月)でデフォルトオンになりました。Mergely(Wayne Stidolph、2013、MITライセンス)はCodeMirror上に構築された正典的なブラウザベースの2-wayマージエディタです。jsdiff(Kevin Decker、約2010)は支配的なJavaScript diffライブラリで、貼り付けたことのあるすべてのブラウザベースのdiffツールで使用されています。diff-match-patch(GoogleのNeil Fraser、2006)はdiffing、ファジーマッチング、パッチ生成を単一のAPIで処理する代替ライブラリです; Google Docsのリビジョン履歴で使用されています。Diffcheckerは支配的なフリーミアムオンラインdiffサービスで、フル機能ですがプライバシーが有料(無料層は彼らのサーバーにテキストを送信します)。text-compare.comは最も長く運営されている純粋テキストWeb diffサイトで、UIは古いですが機能的です。
プライバシー: なぜここでブラウザのみが特に重要なのか
すべてのdiffは、2つのバージョン間で何が変わったかを正確に明らかにし、変わったものはしばしばどちらかのバージョン単独よりも機密です。これが鋭く重要となる3つの具体的なシナリオ。セキュリティパッチ: 関数の脆弱なバージョンをパッチされたバージョンとdiffすると、セキュリティバグの正確な場所と性質が明らかになります。パッチを見つけた攻撃者はパッチされていないバージョンの悪用を作成できます(USENIX Security 2017でTianらが文書化した「patch gap」攻撃)。セキュリティパッチをサーバーサイドdiffツールに貼り付けることは、本質的に脆弱性を公開することです。契約交渉: 契約の2つのバージョンをdiffすると、各側がどの条項を気にしているかが正確に明らかになります。これはまさに交渉中に相手側(またはネットワークを見ている誰か)に持ってほしくない情報です。公開前の編集決定: 編集前と編集後の原稿をdiffすると、著者と編集者が何を削除または変更することを決定したかが明らかになります。これはしばしば最終公開版より明らかにするものが多いです。サーバーサイドdiffツールは両方のバージョンをサードパーティにアップロードし、そこでログに残ります。このツールはJavaScriptを介してブラウザ内で完全に実行されます。Compareをクリックする間にDevToolsのネットワークタブで検証するか、ロード後にページをオフラインに(機内モードに)してもツールはまだ機能します。
よくある質問
コードファイルを比較できますか?
はい。コード、JSON、HTML、Markdown、プレーンテキストを含む任意のテキストを貼り付けます。差分は純粋にテキスト上であるため、任意の形式で機能します。
スペースの違いを無視しますか?
「スペースを無視」オプションを有効にして、スペースまたは行末のみの違いをスキップします。再フォーマットされたが実質的に変更されていないコードを比較するのに便利です。
これはどのアルゴリズムを使用しますか?
MyersのO(ND)アルゴリズム(Eugene Myers、Algorithmica第1巻第2号、1986)、GNU diffが何十年もデフォルトで使用していた同じアルゴリズム、そしてほとんどのテキストdiff実装の基礎です。Myersは最長共通部分列問題を編集グラフ上の最短経路探索として再構成し、わずかな場所だけが異なる入力に対して実用的に高速にしました。新しいhistogramアルゴリズム(2016年11月のv2.11以降のGitの現在のデフォルト)は移動されたブロックをわずかに良く処理しますが、このツールが処理する典型的な2貼り付けのユースケースにはやり過ぎです。
サイズ制限はありますか?
ハードリミットはありませんが、比較はJavaScriptを介してブラウザで実行されるので、実用的な上限はデバイスの利用可能なメモリです。何万行も快適に動作します。非常に大きな入力(マルチメガバイトのログファイル、完全な小説)は実行されますが、レンダリングに目立つ数秒かかる可能性があります。本当に巨大な入力にはコマンドラインのGitのdiffを使用してください。出力をストリームし、メモリプレッシャーなしで任意のサイズのファイルを処理します。
3-wayマージやパッチの適用はできますか?
現在はできません。このツールは2-way比較(A対B)に焦点を当てています。3-wayマージ(競合マーカー<<<<<<< / ======= / >>>>>>>を持つdiff3アルゴリズム)はGitがブランチをマージするときに使用する操作です; 共通の祖先と2つの分岐したバージョンが必要です。3-wayマージには、本物のバージョン管理システムまたはVS Codeの3ペインマージエディタ(2022年6月の1.69からデフォルトオン)のような専用ツールを使用してください。
私のテキストはアップロードされますか?
いいえ。比較はJavaScriptを介してブラウザ内で完全に実行されます。貼り付けるテキストは決してネットワークを越えません。Compareをクリックする間にDevToolsのネットワークタブで検証するか、ロード後にページをオフラインに(機内モードに)してもツールはまだ機能します。セキュリティパッチのdiff(diff自体が脆弱性を明らかにする)、契約改訂(diffが交渉ポジションを明らかにする)、または公開前の編集ドラフトには特に安全です。