Jakie są różnice między podwójnymi kropkami „..” i potrójnymi kropkami „…” w zakresach zatwierdzania różnic Git diff?

190

Jakie są różnice między następującymi poleceniami?:

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

Podręcznik diff mówi o tym:

Porównywanie gałęzi

$ git diff topic master    <1>
$ git diff topic..master   <2>
$ git diff topic...master  <3>
  1. Zmiany między wskazówkami tematu i gałęziami wzorcowymi.
  2. Tak samo jak powyżej.
  3. Zmiany, które wystąpiły w gałęzi głównej od momentu uruchomienia gałęzi tematu.

ale nie jest dla mnie całkowicie jasne.

chrisjlee
źródło
Choć ta kwestia nie jest duplikatem, to odpowiedź pokazuje graficznie rozumieniu ..i ...w git diffi ich różne znaczenia w git log.
Mark Longair

Odpowiedzi:

335

Ponieważ już stworzyłem te obrazy, pomyślałem, że warto je wykorzystać w innej odpowiedzi, chociaż opis różnicy między ..(kropka-kropka) a ...(kropka-kropka-kropka) jest zasadniczo taki sam jak w odpowiedzi manojldsa .

Polecenie git diffzazwyczaj pokazuje tylko różnicę między stanami drzewa między dokładnie dwoma punktami na wykresie zatwierdzenia. Te ..i ...notacje w git diffmają następujące znaczenie:

Ilustracja różnych sposobów określania zatwierdzeń dla git diff

Innymi słowy, git diff foo..barjest dokładnie taki sam jakgit diff foo bar ; oba pokażą różnicę między końcami dwóch gałęzi fooi bar. Z drugiej strony git diff foo...barpokaże Ci różnicę między „bazą scalającą” dwóch gałęzi a wierzchołkiem bar. „Baza scalania” jest zwykle ostatnim wspólnym zatwierdzeniem między tymi dwiema gałęziami, więc to polecenie pokaże ci zmiany, które wprowadziła twoja praca bar, ignorując wszystko, co zostało zrobione foow międzyczasie.

To wszystko, co trzeba wiedzieć o ..i ...notacje w git diff. Jednak...


... częstym źródłem zamieszania jest tutaj .. i ...myśli subtelnie różne rzeczy, gdy używany w poleceniu takich jak git log, który oczekuje zestaw zobowiązuje jak jeden lub więcej argumentów. (Wszystkie te polecenia kończą się git rev-listna analizie listy zatwierdzeń z ich argumentów).

Znaczenie ..i... dla git logmożna przedstawić graficznie, jak poniżej:

Ilustracja różnych sposobów określania zakresów zatwierdzeń dla dziennika git

Tak, git rev-list foo..barpokazuje wszystko na oddział bar, który nie jest również na oddziale foo. Z drugiej strony git rev-list foo...barpokazuje wszystkie zatwierdzenia, które są w jednym foo lub bar , ale nie w obu . Trzeci diagram pokazuje tylko, że jeśli wypiszesz dwie gałęzie, otrzymasz zatwierdzenia, które są w jednym lub obu z nich.

Cóż, w każdym razie wydaje mi się to trochę mylące i myślę, że diagramy wykresów zatwierdzania pomagają :)

¹ Mówię tylko „zwykle”, ponieważ na przykład przy rozwiązywaniu konfliktów scalania git diffwyświetli się trójstronne połączenie.

Mark Longair
źródło
1
Lubię twoje diagramy. Jakiś czas temu wymyśliłem też własne . Mam kilka pomysłów na własne git diffdiagramy, które przygotuję później.
34
Czy ktoś zauważył? Efekty ..i ...odczucia odwrócone w git diff(w porównaniu do git rev-list)!
Robert Siemer
2
Miałeś mnie w „To wszystko, co musisz wiedzieć [...]. Jednak ...”. :-) Git jest pełen takich rzeczy, w których podobna notacja i terminologia oznaczają różne rzeczy w różnych kontekstach; dziękuję za tak dobre wyjaśnienie.
ShreevatsaR
Dzięki za wzmiankę o liście rev. Natknąłem się na to pytanie, szukając sposobu na to, co robi rev-list poprzez rev-pars.
Szalony fizyk
„Innymi słowy, git diff foo..barjest dokładnie taki sam jak git diff foo bar; oba pokażą różnicę między końcami dwóch gałęzi foo i paska”. Co dokładnie rozumiesz przez „różnicę między końcami dwóch gałęzi”?
Asad Moosvi
60

Moja skonsolidowana wersja .. vs ... z diff vs log

Diff vs Log & .. vs ..

DolphinDream
źródło
3
byłoby to bardzo dobre, gdyby nie miał tak wielu różnych kolorów i ustawiał operacje pomieszane z ../ ...stuff. Na przykład log A...Bnie jest jasne, czy polecenie zwraca przecięcie (biała część diagramu), czy resztę związku AB (zielony). Byłoby to bardziej do rzeczy bez żadnych ustawionych argumentów i tylko z jednym kolorem.
xealits
1
Czy to naprawdę powinno być diff A..B<—> log A...B, czyli czy naprawdę różni się 2 kropkami, odpowiada logowi z 3 (!) Kropkami? Czy na zdjęciu jest literówka. Patrząc na to, jak kropki są oznaczone kolorami, wydaje mi się, że na zdjęciu jest literówka. Lewy dolny róg: log A...Bpowinien być log A..B, prawy (?). I log tylko w prawo powinno być ...nie ...
KajMagnus
1
Cześć DolphinDream, dzięki za twoją figurę. Używam go jako odniesienia tutaj: gitlab.com/tortoisegit/tortoisegit/issues/3427#note_227200695
Yue Lin Ho
1
@ KajMagnus w rzeczywistości kolory czerwony / niebieski są po prostu używane do rozróżnienia między 2 i 3 kropkami (niezależnie od tego, czy są używane z diff czy log). Schemat jest poprawny. W pierwszej kolumnie wynik różnicy z 2 kropkami jest podobny do logu z 3 kropkami (stąd cały schemat celu na początek). Różnica z 2 kropkami podaje zmiany kodu w obu obrotach w dół do punktu dywergencji (zilustrowane zielonymi bąbelkami wokół commits i zielonych części diagramów van), podczas gdy log z 3 kropkami daje dzienniki zmian (komunikaty zatwierdzeń) w obu obrotach do punktu dywergencji.
DolphinDream,
28

git diff foo master Różnica między górnymi (główkami) zatwierdzeniami foo i master.

git diff foo..master Kolejny sposób na zrobienie tego samego.

git diff foo...masterRóżni się od wspólnego przodka ( git merge-base foo master) foo i master do tip mistrza. Innymi słowy, pokazuje tylko zmiany, które gałąź master wprowadziła od swojego wspólnego przodka z foo.

Ten przykład z GitHub wyjaśnia, kiedy użyć dwóch:

Na przykład, jeśli utworzysz gałąź „dev” i dodasz funkcję do pliku, to wróć do swojej gałęzi „master” i usuń wiersz z README, a następnie uruchom coś takiego:

$ git diff master dev

Poinformuje cię, że funkcja została dodana z pierwszego pliku i linia została dodana do README. Czemu? Ponieważ w gałęzi README nadal ma oryginalną linię, ale w „master” ją usunąłeś - więc bezpośrednie porównanie migawek wygląda tak, jakby „dev” ją dodało.

To, co naprawdę chcesz porównać, to to, co „dev” zmieniło od czasu rozejścia się twoich gałęzi. Aby to zrobić, Git ma ładny krótki skrót:

$ git diff master...dev
manojlds
źródło
2
git diff foo ... główne zmiany, które wprowadził gałąź master, ponieważ jest to wspólny przodek z foo
0fnt
@manojlds ok, więc inne pytanie, czy jesteś w gałęzi dewelopera i zatwierdzasz zmiany (funkcję) i wpychasz zmiany do zdalnej gałęzi deweloperów, czy to oznacza, że ​​widoczna zmiana to tylko funkcja lub funkcja i plik readme?
David
Jeśli się nie mylę, diff żądania pobierania GitHub używa potrójnej kropki. Czy to prawda?
Shaun Luttin
Uszkodzony link do przykładowej strony GitHub.
K.-Michael Aye
6
git diff foo master

pokaże różnice między tematem a gałęzią master w danym momencie

git diff foo..master

pokaże to również różnice między tematem a gałęzią master w tym momencie

git diff foo...master

pokaże to wszystkie różnice między momentem utworzenia tematu z oddziału a później

więc pierwsze 2 polecenia są takie same, a ostatnie pokazuje po prostu szerszy widok w historii różnic

italiano40
źródło
1

drzewo dziennika git

Górne zdjęcie odpowiada drzewku dolnego wykresu

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

Obraz jest wart tysiąca słów, różnica między nimi .. ... ^jest pokazana poniżej.

$ 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
źródło