Rebasar y que se entiende por rebase empujado confirmaciones

109

A menudo se dice que no debes rebasar confirmaciones que ya hayas enviado. ¿Qué podría significar eso?

Hemant Kumar
fuente

Respuestas:

80

El libro ProGit tiene una buena explicación .

La respuesta específica a su pregunta se puede encontrar en la sección titulada " Los peligros de volver a basar ". Una cita de esa sección:

Cuando reabasteces cosas, estás abandonando las confirmaciones existentes y creando nuevas que son similares pero diferentes. Si empuja las confirmaciones en algún lugar y otros las bajan y basan el trabajo en ellas, y luego reescribe esas confirmaciones con git rebase y las sube de nuevo, sus colaboradores tendrán que volver a fusionar su trabajo y las cosas se complicarán cuando intente hacerlo. devolver su trabajo al suyo.

Actualización:
según su comentario a continuación, parece que tiene dificultades con su flujo de trabajo de Git. Aquí hay algunas referencias que pueden ayudar:

Tim Henigan
fuente
Gracias por la explicación. Entonces, solo para que mi comprensión sea más clara, después de presionar ciertos cambios, no debería usar git rebase(--interactive?) Para reescribir ese historial, esta es una receta segura para fallar. branch (desde el branch X) y empujarlo, es perfectamente normal volver a cambiar la base de datos después de que otro desarrollador cambie el branch de tema. Esencialmente, lo he estado usando mergedurante bastante tiempo, pero estamos en el mismo barco que darwinweb.net/articles/86 y el historial es casi inutilizable.
Hemant Kumar
@Hemant: Rebasar las confirmaciones después de presionar a un repositorio público es generalmente una mala idea. Dicho esto, el consejo del artículo de darwinweb que citó suena razonable si su flujo de trabajo se parece al de ellos. Consulte mi respuesta actualizada para obtener una lista de otras referencias que podrían ayudar.
Tim Henigan
Actualice un enlace a la página "ProGit" sobre "Equipo administrado privado" en git-scm.com/book/en/…
Eimantas
Entonces, técnicamente, las confirmaciones de git siguen siendo las mismas, pero "renunciar a las confirmaciones existentes y crear otras nuevas que son similares pero diferentes" ¿son las mismas confirmaciones con diferente id sha1? bueno, esa sería la única forma obvia en la que puedo pensar por qué los colaboradores tendrían que volver a fusionar su propio trabajo.
Ciasto piekarz
@Ciastopiekarz, esto se debe a que está reescribiendo el historial en el repositorio ascendente, y los repositorios locales de otros desarrolladores pueden indicarlo. Ahora sus punteros están obsoletos: el cliente de git no tiene otra alternativa que usar punteros más antiguos y confiar en el humano para resolver el resto. ¡Esta es una nueva fusión y puede ser MUY desordenada con muchos cambios confusos que deben resolverse manualmente! Por lo tanto, la recomendación de no reajustar nunca nada que ya se haya enviado a un repositorio ascendente. Este es un buen consejo y no debe ignorarse a menos que sea un experto con un conocimiento profundo.
Forbin
240

Para entender esto, necesitamos entender un poco cómo funciona git. Un repositorio de git es una estructura de árbol, donde los nodos del árbol son confirmaciones. Aquí hay un ejemplo de un repositorio muy simple: Cuando te bifurcas

tiene cuatro confirmaciones en la rama maestra y cada confirmación tiene un ID (en este caso, a, b, c y d). Notará que d es actualmente la última confirmación (o HEAD) de la rama maestra. ingrese la descripción de la imagen aquí

Aquí, tenemos dos ramas: master y my-branch. Puede ver que master y my-branch contienen las confirmaciones ayb, pero luego comienzan a divergir: master contiene cyd, mientras que my-branch contiene ey f. Se dice que b es la "base de fusión" de my-branch en comparación con master, o más comúnmente, solo la "base". Tiene sentido: puede ver que my-branch se basó en una versión anterior de master.

Entonces, digamos que my-branch se ha quedado obsoleto y desea actualizarlo con la última versión de master. Para decirlo de otra manera, my-branch debe contener cy d. Puede hacer una fusión, pero eso hace que la rama contenga confirmaciones de fusión extrañas que hacen que revisar la solicitud de extracción sea mucho más difícil. En su lugar, puede hacer un rebase.

ingrese la descripción de la imagen aquí

Cuando rebase, git encuentra la base de su rama (en este caso, b), encuentra todas las confirmaciones entre esa base y HEAD (en este caso, eyf), y vuelve a reproducir esas confirmaciones en el HEAD de la rama estás rebasando (en este caso, maestro). Git en realidad crea nuevas confirmaciones que representan cómo se ven sus cambios en la parte superior del maestro: en el diagrama, estas confirmaciones se denominan e ′ y f ′. Git no borra tus confirmaciones anteriores: eyf no se modifican, y si algo sale mal con la rebase, puedes volver a la forma en que solían ser.

Cuando muchas personas diferentes están trabajando en un proyecto de forma simulada, las solicitudes de extracción pueden quedarse obsoletas rápidamente. Una solicitud de extracción "obsoleta" es aquella que ya no está actualizada con la línea principal de desarrollo y debe actualizarse antes de poder fusionarse con el proyecto. La razón más común por la que las solicitudes de extracción se vuelven obsoletas se debe a los conflictos: si dos solicitudes de extracción modifican líneas similares en el mismo archivo y una solicitud de extracción se fusiona, la solicitud de extracción no fusionada ahora tendrá un conflicto. A veces, una solicitud de extracción puede quedarse obsoleta sin conflictos: tal vez los cambios en un archivo diferente en la base de código requieran los cambios correspondientes en su solicitud de extracción para ajustarse a la nueva arquitectura, o tal vez la rama se creó cuando alguien había fusionado accidentalmente pruebas unitarias fallidas con la rama maestra. Independientemente del motivo,

pseudoCoder
fuente
68

Rebasar reescribe la historia. Si nadie conoce esa historia, está perfectamente bien. Sin embargo, si esa historia se conoce públicamente, entonces reescribir la historia en Git funciona exactamente como lo hace en el mundo real: necesitas una conspiración.

Las conspiraciones son realmente difíciles de mantener juntas, por lo que es mejor que evite cambiar las ramas públicas en primer lugar.

Tenga en cuenta que no son ejemplos de éxito conspiraciones: la purama del repositorio git de Junio Hamano C. (el repositorio Git oficial del SMC) se reajusta con frecuencia. La forma en que esto funciona es que casi todos los que usan putambién están suscritos a la lista de correo de desarrolladores de Git, y el hecho de que la pusucursal tenga una nueva base se publicita ampliamente en la lista de correo y el sitio web de Git.

Jörg W Mittag
fuente
4
+1. Creo que la purama de git.git es un ejemplo extremadamente útil de cómo usar rebase en un flujo de trabajo (público). Para aquellos que no están familiarizados con él, la idea general es volver a establecer la base de las ramas de tema que no tienen ninguna confirmación next(la rama inestable justo antes de fusionarse con la maestra), luego reconstruir la purama restableciendo nexty fusionando todas las ramas de tema. (Fuente: Documentation / howto / keep-git.txt git.kernel.org/?p=git/git.git;a=blob;f=Documentation/howto/… )
Cascabel
25
+1 para "reescribir la historia en Git funciona exactamente como lo hace en el mundo real: necesitas una conspiración"
Sleeper Smith
"No es necesario un anuncio público ya que pu es una rama desechable, como se describió anteriormente". git-scm.com/docs/gitworkflows Hacemos algo similar en el trabajo, "TEMP-something-latest" es una rama desechable que es una combinación de los últimos cambios, podría ser una combinación de varias ramas de funciones, puede eliminarse y recreado en cualquier momento y no debe desarrollarse.
pilkch
6

Una rebase altera el historial de su repositorio. Si envía confirmaciones al mundo, es decir, las pone a disposición de otros, y luego cambia su vista del historial de confirmaciones, se vuelve difícil trabajar con cualquiera que tenga su historial anterior.

Rebase considerado dañino es una buena descripción general, creo.

dsolimano
fuente