2

git diffvs. git rev-listorの表記の違いの根拠 (ある場合) を理解しようとしていgit logます。

説明:

以下で説明するように、各コマンドの機能を理解しています。Git が 2 つの異なるコマンドで同じ表記法を使用して、一方が直感的に (IHO) 他方と反対になる理由についての説明を探しているだけです。

git ログ/リビジョン リスト

logやrev-listで、分岐した枝の両側(左右対称)を見たい場合は、ドット3つ( ...)で表記します。例えば、

$ git log --oneline --boundary a...b
* aaaaa Commit to Branch a
| * bbbbb Commit to branch b
|/
o 000000

2 つの点 ( ..) は右側 (非対称) のみを示します。例えば、

$ git log --oneline --boundary a..b
* bbbbb Commit to branch b
o 000000

git差分

ただし、git diff では、2 つのドット ( ..) は対称的な diff (私の言葉) を示します。つまり、リストされている 2 つの正確なコミット間の差分を示します。

git diff a..b

aaaaa と bbbbb のツリー間の差分を示します。

3 つのドット ( ...) は非対称差分を示します。つまり、2 つのコミットのマージベースと 2 番目のコミットの間の差分を示します。例えば、

git diff a..b 

00000 と bbbbb のツリーの差分を表示します。

4

2 に答える 2

0

のドット表記はgit-log、いわゆるリビジョン範囲を指定します。これはまさにその名前が示すものであり、例で説明したものです。git-logコミットのリスト (範囲) を表示することが目的であるため、使用されます。

git-diffリビジョン範囲も使用しますが、今引用させてください:

ただし、「差分」は範囲ではなく 2 つのエンドポイントの比較に関するものであり、範囲表記 (「..」および「...」) は、gitrevisions[7] の「SPECIFYING RANGES」セクションで定義されている範囲を意味しません。

git-diff のドキュメントから。

于 2015-12-17T17:41:45.990 に答える
0

TL;DR の答え: git diff単純に対称差を実行しません (セットもまったく実行しません)。コミットのペアを見つけて、そのペアを比較するだけです。

最初に(余談ですが、さまざまな訪問者が「対称差」の「差」という言葉とほとんど関係のないコマンドを比較して答えを見つけた場合の明確化のために)、対称差を参照git diffすることに注意してください。to は、グラフ理論の対称差、つまり集合集合から集合交点を引いたものです。この場合、和集合と交差する 2 つのセットは、2 つの名前付きコミットのいずれかから到達可能なすべてのコミットのセットです。コミット ID を取得するために解析し、そのコミットから到達可能なすべてのコミットを見つけます。同様に解析および処理します。交差はマージ ベース自体から始まり、履歴をさかのぼります。git rev-listgit rev-list a...bab

あなたの例では、これにより、2 つのブランチ ヒント コミットのみが残ります。これを取得するために、分岐点コミット (2 つの履歴が集合の交差点の先端で結合する場所) を含める--boundary原因を追加しました。git rev-list

$ git log --oneline --graph --boundary a...b
* aaaaa Commit to Branch a
| * bbbbb Commit to branch b
|/
o 000000

それがなければ--boundarycommit を省略oします (--oneline --graph役に立たないものにします)。

もちろん、2 つのドット を使用すると、到達可能で到達不可能a..bなコミットを取得することbも正しいです(通常、これはそれ自体で識別されるコミットも省略しますが、再び結果セットに戻します)。aa--boundary

git diff は異なります

git logおよびgit rev-listコマンドは、コミットの完全なセットで動作します。たとえば、75 個のコミットのセットを見ている場合、git log75 個のコミットすべてが表示されます ( で制限しない限り-n)。

git diffコマンドが違います。2 つのコミットの比較 (差分) を生成し、マージ コミットにのみ適用される「結合された差分」を無視する限り、2 つのコミットのみを調べます。与えられた:

$ git diff HEAD~5 HEAD

これが commitHEAD~5と commit を比較していることは明らかですが、 5 つ以上の1 つのコミットに名前が付けHEADられていても、次のようになります。HEAD~5..HEAD

$ git diff HEAD~5..HEAD

HEAD~5に対して、同じ 2 つのコミットを比較するだけHEADです。

(ご了承ください:

$ git diff HEAD..HEAD~5

同じ2つのコミットを比較しますが、コミットを変更してHEADコミットを生成するHEAD~5方法と、より一般的な「変更HEAD~5して生成する方法」を示していHEADます。したがって、順序は重要ですが、基本的にgit diffは、ここでは 2 つのドットをスペースに置き換えるだけです.)

このgit diffコマンドは、同様に 3 ドット表記を引き継ぎます。それでも 2 つのコミットしか確認しないため、3 つのドット表記を指定すると、通常どおりマージベースのコミットが検出されますが、入力を変更して、単純に左側と右側のコミットに別々に名前を付けたふりをする代わりに、入力を変更して、左側にマージベース、右側に右側のコミットという名前を付けたふりをします。

実際の対称差 (集合演算) では、オペランドの順序は関係ありません。しかしgit diff、ペアを見つけて左のオペランドをマージベースに置き換え、それを右のオペランドと比較するため、ここでの順序重要です。「最終結果」のコミット名を右側にgit diff配置します。左の通り。


HEAD~5..HEADHEADから到達可能で、 から到達可能ではないすべてのコミットを生成しHEAD~5ます。線形構造では、それは 5 つのコミットです。

... - HEAD~5 - HEAD~4 - HEAD~3 - HEAD~2 - HEAD~1 - HEAD
- excluded -    -------- included: five commits ---------

ただし、ブランチ アンド マージ構造では、追加のコミットが次のセットに含まれます。

                       HEAD~3
                      /      \
... - HEAD~5 - HEAD~4         HEAD~2 - HEAD~1 - HEAD
                     \       /
                      HEAD~2^2

たとえば、この構造の結果セットには 6 つのコミットがあります。

于 2015-12-17T17:44:38.233 に答える