Quali sono le differenze tra il punto doppio ".." e il punto triplo "..." negli intervalli di commit diff Git?


190

Quali sono le differenze tra i seguenti comandi ?:

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

Il manuale diff ne parla:

Confronto di rami

$ git diff topic master    <1>
$ git diff topic..master   <2>
$ git diff topic...master  <3>
  1. Cambiamenti tra i suggerimenti dell'argomento e i rami principali.
  2. Come sopra.
  3. Modifiche apportate al ramo principale da quando il ramo argomento è stato avviato da esso.

ma non è del tutto chiaro per me.


Mentre la domanda non è un duplicato, questa risposta mostra graficamente il significato di ..e ...in git diffe i loro diversi significati in git log.
Mark Longair,

Risposte:


335

Dato che avevo già creato queste immagini, ho pensato che valesse la pena usarle in un'altra risposta, sebbene la descrizione della differenza tra ..(punto-punto) e ...(punto-punto-punto) sia essenzialmente la stessa della risposta di manojlds .

Il comando in git diffgenere¹ mostra solo la differenza tra gli stati dell'albero tra esattamente due punti nel grafico di commit. Le note ..e ...in git diffhanno i seguenti significati:

Un'illustrazione dei diversi modi di specificare commit per git diff

In altre parole, git diff foo..barè esattamente lo stesso di git diff foo bar; entrambi ti mostreranno la differenza tra le punte dei due rami fooe bar. D'altra parte, git diff foo...barti mostrerà la differenza tra la "base di unione" dei due rami e la punta di bar. La "base di unione" è in genere l'ultimo commit in comune tra questi due rami, quindi questo comando ti mostrerà i cambiamenti che il tuo lavoro barha introdotto, ignorando tutto ciò che è stato fatto foonel frattempo.

Questo è tutto ciò che devi sapere sul ..e sulle ...annotazioni git diff. Però...


... una fonte comune di confusione qui è quella ..e ...significa cose leggermente diverse quando usate in un comando come quello git logche si aspetta un insieme di commit come uno o più argomenti. (Tutti questi comandi finiscono per utilizzare git rev-listper analizzare un elenco di commit dai loro argomenti.)

Il significato di ..e ...per git logpuò essere mostrato graficamente come di seguito:

Un'illustrazione dei diversi modi di specificare intervalli di commit per git log

Quindi, git rev-list foo..barti mostra tutto sul ramo barche non è anche sul ramo foo. D'altra parte, git rev-list foo...barti mostra tutti i commit che sono in uno foo o bar , ma non in entrambi . Il terzo diagramma mostra solo che se si elencano i due rami, si ottengono i commit che si trovano in uno o entrambi.

Bene, trovo che sia un po 'confuso, comunque, e penso che i diagrammi del grafico di commit aiutino :)

¹ Dico solo "tipicamente" poiché, ad esempio, quando si risolvono i conflitti di unione, git diffviene mostrata un'unione a tre vie.


1
Mi piacciono i tuoi schemi. Mi è venuto in mente anche un po 'di tempo fa . Ho alcune idee per i miei git diffdiagrammi che farò in seguito.

34
Qualcuno l'ha notato? Gli effetti di ..e ...tatto invertiti in git diff(rispetto a git rev-list)!
Robert Siemer,

2
Mi avevi in ​​"Questo è tutto ciò che devi sapere [...]. Comunque ...". :-) Git è pieno di cose come questa in cui notazione e terminologia simili significano cose diverse in contesti diversi; grazie per aver chiarito così bene.
ShreevatsaR,

Grazie per aver menzionato rev-list. Mi sono imbattuto in questa domanda mentre cercavo un modo per fare ciò che fa rev-list tramite rev-parse.
Fisico pazzo,

"In altre parole, git diff foo..barè esattamente lo stesso di git diff foo bar; entrambi ti mostreranno la differenza tra le punte dei due rami foo e bar." Cosa intendi esattamente con "differenza tra le punte dei due rami"?
Asad Moosvi,

60

La mia versione consolidata di .. vs ... con diff vs log

Diff vs Log & .. vs ..


3
questo sarebbe molto buono, se solo non avesse avuto così tanti colori diversi e operazioni impostate mescolate con ../ ...stuff. Ad esempio, log A...Bnon è chiaro se il comando restituisce l'intersezione (parte bianca del diagramma) o il resto dell'unione AB (verde). Sarebbe più al punto senza alcun operando impostato e con solo 1 colore.
Xealits,

1
Dovrebbe davvero essere diff A..B<—> log A...B, cioè, differisce davvero con 2 punti, corrisponde al registro con 3 (!) Punti? O c'è un refuso nell'immagine. Guardando come i punti sono colorati, mi sembra che ci sia un refuso nell'immagine. L'angolo in basso a sinistra: log A...Bdovrebbe essere log A..B, a destra (?). E log appena a destra dovrebbe essere ...non ...
KajMagnus,

1
Ciao DolphinDream, grazie per la tua figura. Lo uso come riferimento qui: gitlab.com/tortoisegit/tortoisegit/issues/3427#note_227200695
Yue Lin Ho

1
@KajMagnus in realtà i colori rosso / blu sono solo usati per distinguere tra 2 punti e 3 punti (indipendentemente dal fatto che vengano usati con diff o log). Lo schema è corretto Nella prima colonna, il risultato di diff con 2 punti è simile al registro con 3 punti (da cui l'intero diagramma degli scopi per cominciare). Il diff con 2 punti fornisce le modifiche del codice in entrambi i giri fino al punto di divergenza (illustrato dalle bolle verdi attorno ai commit e dalle parti verdi dei diagrammi del furgone) mentre il log con 3 punti fornisce i log delle modifiche (messaggi di commit) in entrambi i giri fino al punto di divergenza.
DolphinDream

28

git diff foo master La differenza tra la parte superiore (testa) commette foo e master.

git diff foo..master Un altro modo di fare la stessa cosa.

git diff foo...masterDiff dal comune antenato ( git merge-base foo master) di foo e master a punta di master. In altre parole, mostra solo i cambiamenti che il ramo master ha introdotto dal suo antenato comune con foo.

Questo esempio di GitHub spiega quando usare i due:

Ad esempio, se si crea un ramo "dev" e si aggiunge una funzione a un file, si torna al ramo "principale" e si rimuove una riga da README, quindi si esegue qualcosa del genere:

$ git diff master dev

Ti dirà che una funzione è stata aggiunta dal primo file e una riga è stata aggiunta al file README. Perché? Perché sul ramo, README ha ancora la linea originale, ma su "master" l'hai rimossa, quindi confrontando direttamente le istantanee sembra che "dev" l'abbia aggiunta.

Quello che vuoi davvero confrontare è ciò che 'dev' è cambiato da quando i tuoi rami sono divergenti. Per farlo, Git ha una bella stenografia:

$ git diff master...dev

2
git diff foo ... cambiamenti master che il ramo master ha introdotto dal momento che è antenato comune con foo
0

@manojlds ok, domanda così diversa, se sei nel ramo dev e commetti le tue modifiche (la funzione) e trasferisci le modifiche in un ramo dev remoto significa che la modifica visibile è solo la funzione o la funzione e il readme?
David,

Se non sbaglio, la richiesta pull di GitHub diff utilizza il punto triplo. È giusto?
Shaun Luttin,

Collegamento interrotto alla pagina di esempio di GitHub.
K.-Michael Aye,

6
git diff foo master

mostrerà le differenze tra l'argomento e il ramo principale in quel momento

git diff foo..master

questo mostrerà anche le differenze tra l'argomento e il ramo principale in quel momento

git diff foo...master

questo mostrerà tutte le differenze tra quando l'argomento è stato fatto dal ramo e dopo

quindi i primi 2 comandi sono gli stessi e l'ultimo mostra solo una visione più ampia nella cronologia delle differenze


1

git log tree

L'immagine in alto equivale all'albero grafico in basso

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

Un'immagine vale più di mille parole, la differenza tra .. ... ^è mostrata di seguito.

$ git log master..test
# output C0 C1

$ git log ^master test
# output C0 C1

$ git log master…test
# output A1 A2 A3 C0 C1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.