Was sind die Unterschiede zwischen Doppelpunkt ".." und Dreifachpunkt "..." in Git Diff Commit-Bereichen?

188

Was sind die Unterschiede zwischen den folgenden Befehlen?:

git diff foo master   # a 
git diff foo..master  # b
git diff foo...master # c

Das Diff-Handbuch spricht darüber:

Branchen vergleichen

$ git diff topic master    <1>
$ git diff topic..master   <2>
$ git diff topic...master  <3>
  1. Änderungen zwischen den Tipps des Themas und den Hauptzweigen.
  2. Das gleiche wie oben.
  3. Änderungen, die seit dem Start des Themenzweigs im Hauptzweig aufgetreten sind.

ist mir aber nicht ganz klar.

Chrisjlee
quelle
Während die Frage kein Duplikat ist, zeigt diese Antwort grafisch die Bedeutung von ..und ...in git diffund ihre unterschiedlichen Bedeutungen in git log.
Mark Longair

Antworten:

333

Da ich diese Bilder bereits erstellt hatte, dachte ich, dass es sich lohnen könnte, sie in einer anderen Antwort zu verwenden, obwohl die Beschreibung des Unterschieds zwischen ..(Punkt-Punkt) und ...(Punkt-Punkt-Punkt) im Wesentlichen dieselbe ist wie in der Antwort von manojlds .

Der git diffBefehl¹ zeigt normalerweise nur den Unterschied zwischen den Zuständen des Baums zwischen genau zwei Punkten im Festschreibungsdiagramm an. Die ..und ...Notationen in git diffhaben folgende Bedeutung:

Eine Illustration der verschiedenen Arten der Angabe von Commits für git diff

Mit anderen Worten, git diff foo..barist genau das gleiche wie git diff foo bar; beide zeigen Ihnen den Unterschied zwischen den Spitzen der beiden Zweige foound bar. Auf der anderen Seite git diff foo...barwird Ihnen der Unterschied zwischen der "Zusammenführungsbasis" der beiden Zweige und der Spitze von angezeigt bar. Die "Zusammenführungsbasis" ist normalerweise das letzte gemeinsame Commit zwischen diesen beiden Zweigen. Dieser Befehl zeigt Ihnen also die Änderungen an, an denen Ihre Arbeit vorgenommen barhat, und ignoriert alles, was fooin der Zwischenzeit vorgenommen wurde.

Das ist alles, was Sie über die ..und ...Notationen in wissen müssen git diff. Jedoch...


... eine häufige Quelle der Verwirrung ist, dass ..und ...bedeutet subtil unterschiedliche Dinge, wenn sie in einem Befehl verwendet werden git log, der eine Reihe von Commits als ein oder mehrere Argumente erwartet. (Diese Befehle werden alle verwendet git rev-list, um eine Liste von Commits anhand ihrer Argumente zu analysieren.)

Die Bedeutung von ..und ...für git logkann wie folgt grafisch dargestellt werden:

Eine Illustration der verschiedenen Möglichkeiten zum Festlegen von Commit-Bereichen für das Git-Protokoll

So git rev-list foo..barzeigt Ihnen alles , was auf dem Zweig bar, der nicht auch auf einem Ast ist foo. git rev-list foo...barZeigt Ihnen andererseits alle Commits an, die in einem foo oder bar , aber nicht in beiden enthalten sind . Das dritte Diagramm zeigt nur, dass Sie, wenn Sie die beiden Zweige auflisten, die Commits erhalten, die sich in einem oder beiden befinden.

Nun, ich finde das sowieso alles ein bisschen verwirrend und ich denke, die Commit-Diagramme helfen :)

¹ Ich sage nur "typisch", da beim Lösen von Zusammenführungskonflikten beispielsweise git diffeine Drei-Wege-Zusammenführung angezeigt wird.

Mark Longair
quelle
1
Ich mag deine Diagramme. Ich habe mir vor einiger Zeit auch meine eigenen ausgedacht . Ich habe einige Ideen für meine eigenen git diffDiagramme, die ich später machen werde.
34
Hat es jemand bemerkt? Die Auswirkungen von ..und ...Gefühl umgekehrt in git diff( im Vergleich zu git rev-list)!
Robert Siemer
2
Sie hatten mich bei "Das ist alles, was Sie wissen müssen [...]. Jedoch ...". :-) Git ist voll von solchen Dingen, bei denen ähnliche Notation und Terminologie unterschiedliche Dinge in unterschiedlichen Kontexten bedeuten. Danke, dass du das so gut geklärt hast.
ShreevatsaR
Vielen Dank für die Erwähnung der Rev-Liste. Ich bin auf diese Frage gestoßen, als ich nach einer Möglichkeit gesucht habe, das zu tun, was die Rev-Liste per Rev-Parse macht.
Mad Physicist
"Mit anderen Worten, git diff foo..barist genau das gleiche wie git diff foo bar; beide zeigen Ihnen den Unterschied zwischen den Spitzen der beiden Zweige foo und bar." Was genau meinst du mit dem "Unterschied zwischen den Spitzen der beiden Zweige"?
Asad Moosvi
59

Meine konsolidierte Version des .. vs ... mit diff vs log

Diff vs Log & .. vs ..

DolphinDream
quelle
3
Das wäre sehr gut, wenn es nicht so viele verschiedene Farben und Set-Operationen hätte, die mit ../ ...stuff verwechselt wurden. Zum Beispiel log A...Bist darin nicht klar, ob der Befehl den Schnittpunkt (weißer Teil des Diagramms) oder den Rest der AB-Vereinigung (grün) zurückgibt. Ohne festgelegte Operanden und mit nur einer Farbe wäre es mehr auf den Punkt.
Xealits
1
Sollte dies wirklich sein diff A..B<-> log A...B, das heißt, nicht wirklich diff mit 2 Punkten, entsprechen log (!) Mit 3 Punkten? Oder gibt es einen Tippfehler im Bild. Wenn ich sehe, wie die Punkte farbcodiert sind, scheint mir ein Tippfehler im Bild zu sein. Die untere linke Ecke: log A...Bsollte log A..Brechts sein (?). Und loggen Sie sich einfach rechts ...nicht ein ...
KajMagnus
1
Hallo DolphinDream, danke für deine Figur. Ich benutze es hier als Referenz: gitlab.com/tortoisegit/tortoisegit/issues/3427#note_227200695
Yue Lin Ho
1
@KajMagnus Tatsächlich werden die rot / blauen Farben nur verwendet, um zwischen 2-Punkten und 3-Punkten zu unterscheiden (unabhängig davon, ob sie mit diff oder log verwendet werden). Das Diagramm ist korrekt. In der ersten Spalte ähnelt das Ergebnis von diff mit 2 Punkten dem Protokoll mit 3 Punkten (daher zunächst das gesamte Zweckdiagramm). Das Diff mit 2 Punkten gibt die Codeänderungen in beiden Umdrehungen bis zum Divergenzpunkt an (dargestellt durch die grünen Blasen um die Commits und die grünen Teile der Van-Diagramme), während das Protokoll mit 3 Punkten die Änderungsprotokolle (Commit-Meldungen) liefert. in beiden Umdrehungen bis zum Divergenzpunkt.
DolphinDream
28

git diff foo master Unterschied zwischen den obersten (Kopf-) Commits von foo und master.

git diff foo..master Eine andere Art, dasselbe zu tun.

git diff foo...masterUnterscheiden Sie sich vom gemeinsamen Vorfahren ( git merge-base foo master) von foo und master bis zur Spitze des Masters. Mit anderen Worten, zeigt nur die Änderungen an, die der Hauptzweig seit seinem gemeinsamen Vorfahren mit foo vorgenommen hat.

In diesem Beispiel von GitHub wird erklärt, wann die beiden zu verwenden sind:

Wenn Sie beispielsweise einen 'dev'-Zweig erstellen und einer Datei eine Funktion hinzufügen, kehren Sie zu Ihrem' master'-Zweig zurück, entfernen Sie eine Zeile aus der README-Datei und führen Sie Folgendes aus:

$ git diff master dev

Hier erfahren Sie, dass eine Funktion aus der ersten Datei hinzugefügt und der README eine Zeile hinzugefügt wurde. Warum? Da in der Verzweigung die README-Datei immer noch die ursprüngliche Zeile enthält, Sie sie jedoch in 'master' entfernt haben. Wenn Sie also die Snapshots direkt vergleichen, sieht es so aus, als hätte 'dev' sie hinzugefügt.

Was Sie wirklich vergleichen möchten, ist, was sich 'dev' geändert hat, seit Ihre Zweige auseinander gegangen sind. Dazu hat Git eine nette kleine Abkürzung:

$ git diff master...dev
Manojlds
quelle
2
Git Diff Foo ... Master-Änderungen, die Master-Zweig eingeführt hat, seit es gemeinsame Vorfahren mit Foo
0fnt
@manojlds ok, also andere Frage: Wenn Sie sich im Entwicklungszweig befinden und Ihre Änderungen (die Funktion) festschreiben und die Änderungen in einen Remote-Entwicklungszweig übertragen, bedeutet dies, dass die sichtbare Änderung nur die Funktion oder die Funktion und die Readme-Datei ist?
David
Wenn ich mich nicht irre, verwendet GitHubs Pull Request Diff den Tripelpunkt. Ist das richtig?
Shaun Luttin
Defekter Link zur GitHub-Beispielseite.
K.-Michael Aye
6
git diff foo master

zeigt die Unterschiede zwischen dem Thema und dem Hauptzweig zu diesem Zeitpunkt

git diff foo..master

Dies zeigt auch die Unterschiede zwischen dem Thema und dem Hauptzweig zu diesem Zeitpunkt

git diff foo...master

Dies zeigt alle Unterschiede zwischen dem Zeitpunkt, zu dem das Thema aus dem Zweig erstellt wurde, und danach

Die ersten beiden Befehle sind also gleich und der letzte zeigt nur eine breitere Ansicht im Diff-Verlauf

italiano40
quelle
1

Git Log Tree

Das obere Bild entspricht dem unteren Diagrammbaum

A0 <- A1 <- A2 <- A3 (master)
   \
    C0 <- C1 (test)

Ein Bild sagt mehr als tausend Worte, der Unterschied zwischen .. ... ^ist unten dargestellt.

$ git log master..test
# output C0 C1

$ git log ^master test
# output C0 C1

$ git log master…test
# output A1 A2 A3 C0 C1
Yanhaijing
quelle