tipos - ¿Cuál es la diferencia entre ''git merge'' y ''git rebase''?
que hace el merge en git (6)
Git rebase está más cerca de una fusión. La diferencia en rebase es:
- Los compromisos locales se eliminan temporalmente de la rama.
- corre el tirón git
- Inserta nuevamente todos tus compromisos locales.
Eso significa que todas sus confirmaciones locales se mueven al final, después de todas las confirmaciones remotas. Si tienes un conflicto de fusión, tienes que resolverlo también.
¿Cuál es la diferencia entre git merge
y git rebase
?
Personalmente, no encuentro que la técnica de diagramación estándar sea muy útil: las flechas siempre parecen indicar el camino equivocado para mí. (En general, apuntan hacia el "padre" de cada compromiso, que termina siendo atrasado en el tiempo, lo que es extraño).
Para explicarlo en palabras:
- Cuando vuelves a colocar la rama en su sucursal, le dices a Git que parezca que verificaste su sucursal limpiamente y luego hiciste todo tu trabajo a partir de ahí. Eso hace un paquete de cambios limpio y conceptualmente simple que alguien puede revisar. Puede repetir este proceso nuevamente cuando haya nuevos cambios en su rama, y siempre terminará con un conjunto limpio de cambios "en la punta" de su rama.
- Cuando combina su rama en su rama, une las dos historias de ramas en este punto. Si vuelve a hacer esto más tarde con más cambios, comenzará a crear un hilo intercalado de historias: algunos de sus cambios, algunos de mis cambios, algunos de sus cambios. Algunas personas encuentran esto desordenado o indeseable.
Por razones que no entiendo, las herramientas GUI para Git nunca han hecho un gran esfuerzo para presentar las historias de fusión de manera más limpia, abstrayendo las fusiones individuales. Así que si quieres un "historial limpio", necesitas usar rebase.
Me parece recordar haber leído publicaciones de blog de programadores que solo usan rebase y otras que nunca usan rebase.
Ejemplo
Intentaré explicar esto con un ejemplo de palabras justas. Digamos que otras personas en su proyecto están trabajando en la interfaz de usuario, y usted está escribiendo documentación. Sin rebase, su historia podría ser algo como:
Write tutorial
Merge remote-tracking branch ''origin/master'' into fixdocs
Bigger buttons
Drop down list
Extend README
Merge remote-tracking branch ''origin/master'' into fixdocs
Make window larger
Fix a mistake in howto.md
Es decir, las fusiones y las confirmaciones de UI en medio de sus confirmaciones de documentación.
Si rebasara su código en el maestro en lugar de fusionarlo, se vería así:
Write tutorial
Extend README
Fix a mistake in howto.md
Bigger buttons
Drop down list
Make window larger
Todas sus confirmaciones están en la parte superior (las más nuevas), seguidas por el resto de la rama master
.
( Descargo de responsabilidad: soy el autor de la publicación de "10 cosas que odio de Git" que se menciona en otra respuesta )
Realmente me encanta este extracto de 10 cosas que odio sobre git (da una breve explicación de rebase en su segundo ejemplo):
3. Documentación de mierda
Las páginas del manual son un todopoderoso "f *** you" 1 . Describen los comandos desde la perspectiva de un científico informático, no de un usuario. Caso en punto:
git-push – Update remote refs along with associated objects
Aquí hay una descripción para los humanos:
git-push – Upload changes from your local repository into a remote repository
Actualización, otro ejemplo: (gracias cgd)
git-rebase – Forward-port local commits to the updated upstream head
Traducción:
git-rebase – Sequentially regenerate a series of commits so they can be applied directly to the head node
Y luego tenemos
git-merge - Join two or more development histories together
que es una buena descripción
1. sin censura en el original
Supongamos que originalmente había 3 confirmaciones, A
, B
, C
:
Luego el desarrollador Dan creó commit D
, y el desarrollador Ed creó commit E
:
Obviamente, este conflicto debe resolverse de alguna manera. Para esto, hay 2 formas:
MERGE :
Ambos confirmaciones D
y E
aún están aquí, pero creamos una confirmación de fusión M
que hereda los cambios tanto de D
como de E
Sin embargo, esto crea una forma de diamante , que mucha gente encuentra muy confusa.
REBASE :
Creamos commit R
, cuyo contenido de archivo real es idéntico al de merge commit M
anterior. Pero, nos deshacemos de cometer E
, como si nunca hubiera existido (denotado por puntos - línea que desaparece). Debido a esta anulación, E
debería ser local para el desarrollador Ed y nunca debería haber sido enviado a ningún otro repositorio. La ventaja de la rebase es que se evita la forma de diamante , y la historia sigue siendo agradable en línea recta.
Si bien la respuesta aceptada y la más votada es excelente, adicionalmente me parece útil tratar de explicar la diferencia solo con palabras:
unir
- "Bien, tenemos dos estados desarrollados de manera diferente de nuestro repositorio. Vamos a fusionarlos. Dos padres, un hijo resultante ".
rebase
- “Dar los cambios de la rama principal (cualquiera que sea su nombre) a mi rama de función. Hágalo simulando que mi trabajo con características comenzó más tarde, de hecho, en el estado actual de la rama principal ".
- "Reescriba el historial de mis cambios para reflejar eso" (necesidad de forzarlos, porque normalmente el control de versiones se trata de no alterar el historial)
- "Probablemente, si los cambios que cometí tienen poco que ver con mi trabajo, la historia en realidad no cambiará mucho, si miro mis compromisos diff por diff (también puede pensar en ''parches'')".
Resumen: cuando es posible, rebase es casi siempre mejor. Facilitando la reintegración en la rama principal.
¿Porque? Work su trabajo de características se puede presentar como un gran ''archivo de parche'' (también conocido como diff) con respecto a la rama principal, sin tener que ''explicar'' varios padres: al menos dos, provenientes de una combinación, pero probablemente muchos más, si existen Hubo varias fusiones. A diferencia de las combinaciones, las múltiples bases no se suman. (otra gran ventaja)