日本語 ▾ トピック ▾ 最新バージョン ▾ 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>contextDimmed, oldDimmed, newDimmed のいずれかです)、2番目のコミット範囲にのみ存在するコミット差分行は太字で表示されます (これは設定 color.diff.<slot> を使用して上書きできます。ここで <slot>contextBold, oldBold, newBold のいずれかです)。

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

--creation-factor=<percent>

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

--left-only

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

--right-only

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

--diff-merges=<format>

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

注: 一般的なケースでは、Git のマージ機構が生成したものの上の差分のみを表示するため、remerge モードが最も自然な使用方法になります。つまり、マージコミットが競合のない 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 は割り当て問題を解決するために Jonker-Volgenant アルゴリズムの実装を使用しており、これは三次の実行時複雑度を持ちます。この場合に見つかるマッチングは次のようになります。

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

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

関連項目

GIT

git[1]スイートの一部

scroll-to-top