¿Cuáles son las diferencias entre el doble punto "..." y el triple punto "..." en los rangos de confirmación de Git diff?

190

¿Cuáles son las diferencias entre los siguientes comandos ?:

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

El manual de diferencias habla de ello:

Comparar ramas

$ git diff topic master    <1>
$ git diff topic..master   <2>
$ git diff topic...master  <3>
  1. Cambios entre los consejos del tema y las ramas maestras.
  2. Lo mismo que arriba.
  3. Cambios que ocurrieron en la rama maestra desde que se inició la rama del tema.

Pero no está totalmente claro para mí.

chrisjlee
fuente
Si bien la pregunta no es un duplicado, esta respuesta muestra gráficamente el significado de ..y ...en git diffy sus diferentes significados en git log.
Mark Longair

Respuestas:

335

Como ya había creado estas imágenes, pensé que valdría la pena usarlas en otra respuesta, aunque la descripción de la diferencia entre ..(punto-punto) y ...(punto-punto-punto) es esencialmente la misma que en la respuesta de manojlds .

El comando git difftípicamente¹ solo muestra la diferencia entre los estados del árbol entre exactamente dos puntos en el gráfico de confirmación. Las anotaciones ..y ...en git difftienen los siguientes significados:

Una ilustración de las diferentes formas de especificar commits para git diff

En otras palabras, git diff foo..bares exactamente lo mismo que git diff foo bar; ambos le mostrarán la diferencia entre las puntas de las dos ramas fooy bar. Por otro lado, git diff foo...barle mostrará la diferencia entre la "base de fusión" de las dos ramas y la punta de bar. La "base de fusión" suele ser la última confirmación en común entre esas dos ramas, por lo que este comando le mostrará los cambios que barha introducido su trabajo , mientras ignora todo lo que se ha hecho mientras footanto.

Eso es todo lo que necesita saber sobre las anotaciones ..y . Sin embargo......git diff


... una fuente común de confusión aquí es eso ..y ...significa cosas sutilmente diferentes cuando se usa en un comando como el git logque espera un conjunto de confirmaciones como uno o más argumentos. (Todos estos comandos terminan usando git rev-listpara analizar una lista de confirmaciones de sus argumentos).

El significado de ..y ...para git logse puede mostrar gráficamente de la siguiente manera:

Una ilustración de las diferentes formas de especificar rangos de confirmaciones para git log

Entonces, git rev-list foo..barte muestra todo en la rama barque no está también en la rama foo. Por otro lado, git rev-list foo...barmuestra todos los commits que están en uno foo o bar , pero no en ambos . El tercer diagrama solo muestra que si enumera las dos ramas, obtiene las confirmaciones que están en una o en ambas.

Bueno, creo que todo es un poco confuso, de todos modos, y creo que los diagramas de gráficos de confirmación ayudan :)

¹ Solo digo "típicamente" ya que al resolver conflictos de fusión, por ejemplo, git diffle mostrará una fusión de tres vías.

Mark Longair
fuente
1
Me gustan tus diagramas. Se me ocurrió el mío hace un tiempo también . Tengo algunas ideas para mis propios git diffdiagramas que haré más adelante.
34
¿Alguien se dio cuenta? ¡Los efectos ..y la ...sensación se invierten en git diff( en comparación con git rev-list)!
Robert Siemer
2
Me tenías en "Eso es todo lo que necesitas saber [...]. Sin embargo ...". :-) Git está lleno de cosas como esta donde la notación y la terminología similares significan cosas diferentes en diferentes contextos; gracias por aclarar esto tan bien
ShreevatsaR
Gracias por mencionar rev-list. Encontré esta pregunta mientras buscaba una forma de hacer lo que hace rev-list a través de rev-parse.
Físico loco
"En otras palabras, git diff foo..bares exactamente lo mismo que git diff foo bar; ambos le mostrarán la diferencia entre las puntas de las dos ramas foo y bar". ¿Qué quiere decir exactamente con la "diferencia entre las puntas de las dos ramas"?
Asad Moosvi
60

Mi versión consolidada de .. vs ... con diff vs log

Diferencia vs Log & .. vs ..

DolphinDream
fuente
3
esto sería muy bueno, si tan solo no tuviera tantos colores diferentes y operaciones de configuración mezcladas con ../ ...stuff. Por ejemplo, en log A...Bno está claro si el comando devuelve la intersección (parte blanca del diagrama) o el resto de la unión AB (verde). Sería más adecuado sin operandos establecidos y con solo 1 color.
xealits
1
¿Debería ser esto realmente diff A..B<—> log A...B, es decir, realmente difiere con 2 puntos, corresponde al registro con 3 (!) Puntos? ¿O hay un error tipográfico en la imagen? Al observar cómo los puntos están codificados por colores, me parece que hay un error tipográfico en la imagen. La esquina inferior izquierda: log A...Bdebe ser log A..B, derecha (?). Y registro justo a la derecha debe ser ...no ...
KajMagnus el
1
Hola DolphinDream, gracias por tu figura. Lo uso como referencia aquí: gitlab.com/tortoisegit/tortoisegit/issues/3427#note_227200695
Yue Lin Ho
1
@KajMagnus en realidad los colores rojo / azul solo se usan para distinguir entre 2 puntos y 3 puntos (independientemente de que se usen con diff o log). El diagrama es correcto. En la primera columna, el resultado de diff con 2 puntos es similar al registro con 3 puntos (de ahí el diagrama de propósito completo para empezar). El diff con 2 puntos da los cambios de código en ambas revoluciones hasta el punto de divergencia (ilustrado por las burbujas verdes alrededor de los commits y las partes verdes de los diagramas van) mientras que log con 3 puntos da los registros de cambios (mensajes de commit) en ambas revoluciones hasta el punto de divergencia.
DolphinDream
28

git diff foo master Diferencia entre los compromisos superiores (cabeza) de foo y master.

git diff foo..master Otra forma de hacer lo mismo.

git diff foo...masterDifiere del ancestro común ( git merge-base foo master) de foo y master a tip of master. En otras palabras, muestra solo los cambios que la rama maestra ha introducido desde su ancestro común con foo.

Este ejemplo de GitHub explica cuándo usar los dos:

Por ejemplo, si crea una rama 'dev' y agrega una función a un archivo, luego regrese a su rama 'maestra' y elimine una línea del archivo README, y luego ejecute algo como esto:

$ git diff master dev

Le indicará que se agregó una función desde el primer archivo y se agregó una línea al archivo README. ¿Por qué? Porque en la rama, el archivo README todavía tiene la línea original, pero en 'maestro' la ha eliminado, por lo que comparar directamente las instantáneas parece que 'dev' la agregó.

Lo que realmente quiere comparar es qué 'dev' ha cambiado desde que sus ramas divergieron. Para hacer eso, Git tiene una pequeña taquigrafía:

$ git diff master...dev
manojlds
fuente
2
git diff foo ... cambios maestros que la rama maestra ha introducido ya que es un ancestro común con foo
0fnt
@manojlds ok, una pregunta muy diferente, si estás en la rama de desarrollo y confirma tus cambios (la función) y empujas los cambios a una rama de desarrollo remota, ¿significa esto que el cambio visible es solo la función o la función y el archivo Léame?
David
Si no me equivoco, la solicitud de extracción de GitHub usa el punto triple. ¿Está bien?
Shaun Luttin
Enlace roto a la página de ejemplo de GitHub.
K.-Michael Aye
6
git diff foo master

mostrará las diferencias entre el tema y la rama maestra en ese momento

git diff foo..master

esto también mostrará las diferencias entre el tema y la rama maestra en ese momento

git diff foo...master

Esto mostrará todas las diferencias entre cuándo se hizo el tema desde la rama y después

así que los primeros 2 comandos son los mismos y el último solo muestra una vista más amplia en el historial de diferencias

italiano40
fuente
1

árbol de registro de git

La imagen superior es equivalente al árbol gráfico inferior.

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

Una imagen vale más que mil palabras, la diferencia entre .. ... ^se muestra a continuación.

$ 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
fuente