¿Qué es Git Rebase y en qué se diferencia de merge?
La fusión y la reorganización logran objetivos similares, pero los logran de diferentes maneras. Ambos son útiles para administrar la colaboración con sucursales y la colaboración con varias personas, pero no son intercambiables y el cambio de base puede ser dañino si no se maneja correctamente.
¿Cuál es el uso de rebase?
Rebase es complejo, por lo quegit
Es importante entender cómo funciona detrás de escena si vamos a entenderlo.
Git almacena tu código como una serie de ediciones. Puedes pensar en ello como una cadena, trabajando hacia atrás. Cada edición o «confirmación» hace referencia al ID de la confirmación anterior e incluye los cambios desde la confirmación anterior. Esta cadena solo se almacena en su computadora;Su cliente de Git no se comunicará con ningún otro cliente de Git a menos que se esté ejecutandofetch
opush
(pull
en realidad solofetch + merge
con su sucursal local), e incluso entonces solo se comunicará con el repositorio remoto compartido.
Las ramas son más complicadas. Git almacena solo una cosa cuando se trata de ramas: la ID de confirmación al final de la rama. De esta forma, puede pensar en ellos como los cabezales de reproducción de un tocadiscos;Colocas el encabezado de la rama en una ubicación específica y vuelve a través de la cadena, «reproduciendo» tu código y llegando a la versión final. Cada vez que confirmes, tu cliente git local moverá automáticamente el cursor de reproducción hacia el nuevo compromiso.
Si desea fusionar funciones en el maestro, ejecutaría:
función de combinación de git checkout mastergit
Esto crea una nueva confirmación de fusión y, si hay algún conflicto, deberá resolverlo manualmente. Deberíagit merge
Comando para mover el cursor de reproducción principal a la nueva confirmación de combinación y eliminar los cursores de reproducción de características que ya no se necesitan.
Hay tres problemas con este método de combinación de código:
- Puede haber cambios en la rama principal que la rama de características quiera incluir, especialmente si la característica tarda un tiempo en desarrollarse.
- Es molesto verse obligado a pasar por el proceso de fusión cada vez que desea utilizar una rama.
- Los historiales de confirmación son desordenados, aunque se trata en gran medida de una cuestión estética.
Rebase intenta abordar estos problemas, con diversos grados de éxito. Vuelva a establecer los cambios donde inició la rama. La rama completa se promociona y se transfiere al final de la rama maestra actual, a la que está conectada. La rama maestra permanece sin cambios y puede continuar recibiendo confirmaciones.
Sin embargo, las confirmaciones no se mueven realmente porque las confirmaciones son inmutables. En su lugar, se copian, lo que da como resultado nuevos ID de confirmación. La confirmación anterior se archivó, se ocultó en su archivo Git, pero nunca se volvió a ver porque la cabeza lectora se movió a otro lugar.
Para realizar este procedimiento desde la línea de comandos, ejecutaría:
función de pago de git git pull git rebase master
Esto abrirá la rama, extraerá los cambios actuales al maestro y luego volverá a establecer la base de la rama de funciones en la rama maestra.
En este punto, el código en la rama de características ahora está actualizado, lo cual esgit rebase
. Rebase no fusiona ramas porque no crea ninguna confirmación de fusión ni mueve el cursor de reproducción del maestro.
Si quisiera fusionarse después de reorganizar, ejecutaría:
función de combinación de git checkout mastergit
Se ve así, con el cursor de reproducción maestro reemplazando el cursor de reproducción de función:
Por lo tanto, la reorganización no termina resolviendo el problema de manejar las fusiones, porque necesita fusionarse al final de todos modos para actualizar la rama maestra. Sin embargo, la realidad finalmerge
El comando debe ejecutarse sin problemas, ya que el proceso de cambio de base requiere que «fusiones» los cambios, lo que aún puede causar conflictos. Si aún desea continuar trabajando en su sucursal, aún debe «fusionar» los cambios.
No rebase las ramas compartidas
¿Recuerdas cómo el rebase copia compromisos y deja cabezas de reproducción varadas?Este es en realidad un problema importante si usa código compartido. Supongamos que crea una rama de características y la envía a su repositorio para que sus colegas puedan probarla. Eso está perfectamente bien, pero si uno de ellos quiere ramificarse fuera de tu rama, terminarás con esto cuando finalmente cambies de base:
La rama feature2 de su colega ahora hace referencia a la antigua cadena de confirmación. Su cliente Git no tiene forma de saber esto, porque la rama feature2 está almacenada en la computadora de su colega. Tampoco tienen forma de saber que se ha reorganizado hasta que introduzca los cambios.
Cuando rebasaste, no copió la rama de característica2 cuando copió todas las confirmaciones. Incluso si pudiera, no afectaría el repositorio Git local de su colega, desfasando todo. La solución aquí es cambiar la base de la función 2 a donde está la función, pero eso es complicado, aunque según los estándares de Git es un ejemplo muy simple.
La conclusión es, Si no estás trabajando localmente, no cambies de base.
¿Cuándo es mejor reorganizar que fusionar?
Si su rama tarda un tiempo en desarrollarse, el rebase resuelve el problema del «síndrome de la rama», donde su código está tan desactualizado para el maestro en funcionamiento que necesita actualizarlo para que siga funcionando. En general, debe intentar evitar este problema, pero cuando lo hace, rebase puede solucionarlo.
Si solo realiza cambios pequeños, incrementales y diarios, debe trabajar en su rama maestra local y usar solicitud de extracción Cuando esté listo para impulsar sus cambios. Estos utilizan un modelo de rama de tema, creado específicamente para almacenar su código hasta que se apruebe para una fusión.
Sin embargo, si su trabajo se extiende semanalmente y termina realizando varias solicitudes de extracción y fusionándolas varias veces, puede trabajar en el código durante períodos de tiempo más prolongados, reorganizar localmente para realizar actualizaciones y hacerlo al mismo tiempo para ejecutar una extracción. En última instancia, la solicitud reduce la cantidad de pruebas y conversaciones con los supervisores. El cambio de base es principalmente algo local, por lo que puede hacerlo en su rama provisional sin esperar la aprobación.
Si nadie más depende de su rama, puede volver a establecer la base antes de que la rama se fusione para que el historial de confirmación sea limpio y unidimensional. Aunque, se podría argumentar que las fusiones tradicionales, aunque ciertamente más feas, son más fáciles de rastrear y depurar porque las confirmaciones de fusión no tienen pérdidas. De cualquier manera, la reorganización debe realizarse antes de que se fusionen los cambios; de lo contrario, es posible que tenga problemas para actualizar Master antes de que se aprueben los cambios.