日本語 ▾ トピック ▾ 最新バージョン ▾ git-range-diff 最終更新: 2.48.0

名称

git-range-diff - 2つのコミット範囲(例: ブランチの2つのバージョン)を比較する

書式

git range-diff [--color=[<when>]] [--no-color] [<diff-options>]
	[--no-dual-color] [--creation-factor=<factor>]
	[--left-only | --right-only] [--diff-merges=<format>]
	[--remerge-diff]
	( <range1> <range2> | <rev1>…​<rev2> | <base> <rev1> <rev2> )
	[[--] <path>…​]

説明

このコマンドは、パッチシリーズの2つのバージョン、またはより一般的には2つのコミット範囲(マージコミットは無視)間の差分を表示します。

<path> 引数がある場合、これらのコミット範囲はそれに従って制限されます。

そのため、まず両方のコミット範囲から相互に対応するコミットのペアを見つけます。2つのコミットは、それらのパッチ(つまり、作者情報、コミットメッセージ、コミット差分)間の差分がパッチのサイズと比較して合理的に小さい場合に対応すると言われます。詳細については、以下の「アルゴリズム」を参照してください。

最後に、一致するコミットのリストは2番目のコミット範囲の順序で表示され、一致しないコミットはすべての祖先が表示された直後に挿入されます。

コミット範囲を指定する方法は3つあります

  • <range1> <range2>: どちらのコミット範囲も <base>..<rev>, <rev>^!, または <rev>^-<n> の形式で指定できます。詳細については、gitrevisions[7]SPECIFYING RANGES を参照してください。

  • <rev1>…​<rev2>. これは <rev2>..<rev1> <rev1>..<rev2> と同等です。

  • <base> <rev1> <rev2>: これは <base>..<rev1> <base>..<rev2> と同等です。

オプション

--no-dual-color

コミットの差分が異なる場合、git range-diff は元の差分の色を再現し、外側の -/+ 差分マーカーを**背景**が赤/緑になるように追加して、例えば追加された正確な行に変更があった場合などを見やすくします。

さらに、最初のコミット範囲にのみ存在するコミット差分行は「薄く」表示され(これは color.diff.<slot> 設定で上書き可能で、<slot>contextDimmedoldDimmednewDimmed のいずれかです)、2番目のコミット範囲にのみ存在するコミット差分行は太字で表示されます(これは color.diff.<slot> 設定で上書き可能で、<slot>contextBoldoldBoldnewBold のいずれかです)。

これは range-diff では「デュアルカラーリング」として知られています。--no-dual-color を使用すると、すべての行を外側の差分マーカーに従って色付けし(色に関しては内側の差分を完全に無視し)ます。

--creation-factor=<percent>

作成/削除コストのファッジファクターを <percent> に設定します。デフォルトは60です。git range-diff が大きな変更を誤って完全な書き換え(あるコミットの削除と別のコミットの追加)と見なす場合、より大きな値を試してください。逆の場合はより小さな値を試してください。これがなぜ必要であるかについては、以下の「アルゴリズム」セクションを参照してください。

--left-only

最初の指定された範囲(または <rev1>...<rev2> 形式を使用している場合の「左範囲」)に存在しないコミットを抑制します。

--right-only

2番目の指定された範囲(または <rev1>...<rev2> 形式を使用している場合の「右範囲」)に存在しないコミットを抑制します。

--diff-merges=<format>

マージコミットを無視する代わりに、git-log[1] の対応する --diff-merges=<format> オプションを使用してそれらの差分を生成し、比較に含めます。

注: 一般的なケースでは、remerge モードが最も自然な使用方法となります。これは、Gitのマージ機構が生成したものに加えての差分のみを表示するためです。言い換えれば、マージコミットが競合のない git merge の結果である場合、remerge モードはそれを空の差分として表現します。

--remerge-diff

便利なオプションで、--diff-merges=remerge と同等です。

--[no-]notes[=<ref>]

このフラグは、パッチを生成する git log プログラム(git-log[1] を参照)に渡されます。

<range1> <range2>

2つの範囲で指定されたコミットを比較します。ここで、<range1><range2> の古いバージョンと見なされます。

<rev1>…​<rev2>

<rev2>..<rev1><rev1>..<rev2> を渡すのと同等です。

<base> <rev1> <rev2>

<base>..<rev1><base>..<rev2> を渡すのと同等です。<base> がブランチの正確な分岐点である必要はありません。例: my-topic ブランチをリベースした後、git range-diff my-topic@{u} my-topic@{1} my-topic はリベースによって導入された差分を表示します。

git range-diff は、通常の diff オプション(git-diff[1] を参照)も受け入れます。特に --color=[<when>]--no-color オプションが顕著です。これらのオプションは「パッチ間の差分」を生成する際に使用されます。つまり、対応する古いコミットと新しいコミットの作者、コミットメッセージ、および差分を比較するために使用されます。現在、これらのパッチを生成する際に git log に渡される diff オプションのほとんどを調整する手段はありません。

出力の安定性

range-diff コマンドの出力は変更される可能性があります。これは人間が読めるポーセリン出力であり、Gitのバージョンをまたいでテキスト的に安定した range-diff を得るために使用できるものではありません(git-patch-id[1]--stable オプションのようなものとは対照的に)。また、range-diff には git-apply[1] に相当するものがなく、出力は機械可読であることを意図していません。

これは特に diff オプションを渡す場合に当てはまります。現在、--stat のような一部のオプションは、副次的な効果として、range-diff のコンテキストではかなり役に立たない出力を生成する可能性があります。将来の range-diff のバージョンでは、そのようなオプションを range-diff に固有の方法で解釈できるようになるかもしれません(例: --stat が diffstat がどのように変更されたかを要約する人間が読める出力を生成する)。

設定

このコマンドは diff.color.* および pager.range-diff 設定を使用します(後者はデフォルトで有効です)。git-config[1] を参照してください。

リベースでマージの競合を解決する必要があった場合、リベースによって導入された変更を直後に比較するには、以下を使用します。

$ git range-diff @{u} @{1} @

git range-diff の典型的な出力は次のようになります。

-:  ------- > 1:  0ddba11 Prepare for the inevitable!
1:  c0debee = 2:  cab005e Add a helpful message at the start
2:  f00dbal ! 3:  decafe1 Describe a bug
    @@ -1,3 +1,3 @@
     Author: A U Thor <author@example.com>

    -TODO: Describe a bug
    +Describe a bug
    @@ -324,5 +324,6
      This is expected.

    -+What is unexpected is that it will also crash.
    ++Unexpectedly, it also crashes. This is a bug, and the jury is
    ++still out there how to fix it best. See ticket #314 for details.

      Contact
3:  bedead < -:  ------- TO-UNDO

この例では、3つの古いコミットと3つの新しいコミットがあり、開発者は3番目を削除し、最初の2つの前に新しいものを追加し、2番目のコミットのコミットメッセージとその差分を修正しました。

出力がターミナルに出力される場合、通常の git diff の出力と同様に、デフォルトで色分けされます。さらに、最初の行(コミットの追加)は緑、最後の行(コミットの削除)は赤、2番目の行(完全に一致するもの)は git show の出力のコミットヘッダーのように黄色、3番目の行は古いコミットを赤、新しいコミットを緑、残りを git show のコミットヘッダーのように色付けします。

しかし、素朴な色分けされた差分同士の差分は、行全体が赤や緑に色付けされるため、実際には少し読みにくいです。たとえば、古いコミットで「What is unexpected」を追加した行は、古いコミットの意図が何かを追加することであったとしても、完全に赤色になっています。

それを助けるために、range はデフォルトで --dual-color モードを使用します。このモードでは、差分同士の差分は元の差分の色を保持し、行の先頭に背景が赤または緑の -/+ マーカーを付けて、差分自体がどのように変更されたかをより明確に示します。

アルゴリズム

一般的な考え方は次のとおりです。両方のコミット範囲内のコミット間にコスト行列を生成し、最小コストの割り当て問題を解きます。

コスト行列は次のように生成されます: 各コミットペアに対して、両方の差分が生成され、3つのコンテキスト行を持つ「差分同士の差分」が生成され、その差分内の行数がコストとして使用されます。

誤検知(例: パッチが削除され、同じパッチシリーズの2つのイテレーション間で無関係なパッチが追加された場合など)を避けるため、コスト行列は一括削除/追加のための固定コストエントリを追加することで、それを可能にするように拡張されます。

例: コミット 1--2 をパッチシリーズの最初のイテレーションとし、A--C を2番目のイテレーションとします。A2 の cherry-pick であり、C1 の cherry-pick であるが、小さな修正(例えば、タイプミス修正)があると仮定します。コミットを二部グラフとして視覚化します。

    1            A

    2            B

		 C

我々は、古い系列の観点から新しい系列の「最良の」説明を探しています。我々は「説明」をグラフのエッジとして表現できます。

    1            A
	       /
    2 --------'  B

		 C

この説明は変更がなかったため「無料」です。同様に、C1 を使用して説明できますが、修正のためにいくらかのコスト c>0 がかかります。

    1 ----.      A
	  |    /
    2 ----+---'  B
	  |
	  `----- C
	  c>0

数学的には、我々が探しているのはある種の最小費用二部マッチングです。1 はあるコストで C にマッチングされ、などです。基礎となるグラフは実際には完全二部グラフです。各エッジに関連付けるコストは、2つのコミットのパッチ間の差分のサイズです。新しいコミットも説明するために、両側にダミーノードを導入します。

    1 ----.      A
	  |    /
    2 ----+---'  B
	  |
    o     `----- C
	  c>0
    o            o

    o            o

エッジ o--C のコストは、C の差分のサイズを100%未満であるべきファッジファクターで修正したものです。エッジ o--o のコストは無料です。ファッジファクターは、1C に共通点がまったくない場合でも、いくつかの空行などを共有している可能性があり、1C に共通点がなくても 1--Co--o の割り当てが 1--oo--C よりもわずかに安くなる可能性があるため必要です。ファッジファクターを使用することで、パッチが対応していると見なすためには、はるかに大きな共通部分が必要になります。

このアルゴリズムを計算するために必要な全体時間は、n+m個のコミット差分を計算し、その後n*m個のパッチの差分を計算する時間と、n個とm個の差分間の最小コスト割り当てを計算する時間です。Gitは、割り当て問題を解決するためにヨンカー・フォルゲナントアルゴリズムの実装を使用しており、これは3次時間計算量です。この場合に見つかるマッチングは次のようになります。

    1 ----.      A
	  |    /
    2 ----+---'  B
       .--+-----'
    o -'  `----- C
	  c>0
    o ---------- o

    o ---------- o

関連項目

GIT

git[1] スイートの一部

scroll-to-top