2010-03-11 19 views
251

Soy nuevo en git y estoy tratando de entender la diferencia entre squash y rebase. Según lo entiendo, realizas una squash al hacer una rebase.En git, ¿cuál es la diferencia entre merge --squash y rebase?

+4

para su información: el nuevo ** ** rebase y combinar botón se comporta de forma diferente a la realización de un rebase la línea de comandos! La respuesta aceptada se refiere a ejecutar una rebase desde la línea de comando. Desde [aquí] (https://help.github.com/articles/about-pull-request-merges/#rebase-and-merge-your-pull-request-commits): _ El comportamiento de rebase y fusión en GitHub se desvía un poco de git rebase. Rebase y fusión en GitHub siempre actualizará la información del committer y creará nuevos SHA de confirmación, mientras que git rebase fuera de GitHub no cambiará la información del committer. – GrayedFox

Respuesta

271

Tanto git merge --squash como git rebase --interactive pueden producir un compromiso "aplastado".
Pero sirven para diferentes propósitos.

producirá una aplastado cometen en la rama de destino, sin marcar cualquier relación de mezcla.
(Nota: no produce una confirmación inmediata: se necesita un adicional git commit -m "squash branch")
Esto es útil si se quiere tirar la rama completamente de código, al pasar de (esquema tomado de SO question):

git checkout stable 

     X     stable 
    /     
a---b---c---d---e---f---g tmp 

a:

git merge --squash tmp 
git commit -m "squash tmp" 

     X-------------------G stable 
    /     
a---b---c---d---e---f---g tmp 

y borrar tmp rama.

repeticiones de algunos o todos sus compromete en una nueva base, lo que le permite al squash (o, más recientemente, "arreglar", vea este SO question), que van directamente a:

git checkout tmp 
git rebase -i stable 

     stable 
     X-------------------G tmp 
    /     
a---b 

Si elige aplastar todas las confirmaciones de tmp (pero, al contrario de merge --squash, puede optar por reproducir algunas y aplastar otras).

Así que las diferencias son:

  • merge no toca su sucursal fuente (tmp aquí) y crea una única confirmación en la que desea.
  • rebase que permite a seguir en la misma rama fuente (todavía tmp) con:
    • una nueva base
    • un historial limpio
+3

'G' es' c - d - e - f - g' aplastado juntos? –

+4

@Wayne: sí, G en esos ejemplos representa los commits 'tmp' aplastados juntos. – VonC

+0

¿No son los datos en 'G' exactamente los mismos que en' g'? Entonces, ¿eso significaría que 'G' es lo mismo que' g' excepto que tiene un padre diferente? –

67

Merge squash combina un árbol (una secuencia de confirmaciones) en una única confirmación. Es decir, aplasta todos los cambios realizados en n confirma en una única confirmación.

Rebase se basa en una nueva base, es decir, se elige una nueva base (confirmación principal) para un árbol. Tal vez el término mercurial para esto es más claro: lo llaman trasplante porque es solo eso: elegir un nuevo terreno (compromiso de los padres, raíz) para un árbol.

Al hacer una rebase interactiva, tiene la opción de aplastar, elegir, editar u omitir las confirmaciones que va a volver a establecer.

Espero que fuera claro!

+1

¿Cuándo debo volver a establecer la base de datos y cuándo debería hacerlo? –

+2

@MartinThoma https://lwn.net/Articles/328436/ –

31

Combinar compromete: retiene todos de las confirmaciones en su rama y las intercala con commits en la rama base enter image description here

Combinar Squash: conserva los cambios, pero omite el individuo se compromete de la historia enter image description here

Rebase: Esto mueve toda la rama de la característica para comenzar en la punta de la rama principal, la incorporación efectiva de todas las nuevas confirmaciones en master

enter image description here

Más sobre here

Cuestiones relacionadas