Sé de algunas personas que usan git pull --rebase
por defecto y otras que insisten en nunca usarlo. Creo que entiendo la diferencia entre fusionar y rebase, pero estoy tratando de poner esto en el contexto de git pull
. ¿Se trata simplemente de no querer ver muchos mensajes de confirmación de fusión, o hay otros problemas?
806
Respuestas:
Deberías usar
git pull --rebase
cuandoDe hecho, ¿por qué no entonces? Es más claro y no impone una agrupación lógica en sus confirmaciones.
Ok, supongo que necesita alguna aclaración. En Git, como probablemente ya sabes, te animamos a ramificarte y fusionarte. Su rama local, en la que extrae los cambios, y la rama remota son, en realidad, diferentes ramas, y
git pull
se trata de fusionarlas. Es razonable, ya que presiona con poca frecuencia y generalmente acumula varios cambios antes de que constituyan una característica completa.Sin embargo, a veces, por cualquier motivo, cree que sería mejor si estos dos, remoto y local, fueran una sola rama. Como en SVN. Es aquí donde
git pull --rebase
entra en juego. Ya no se fusiona, se compromete en la parte superior de la rama remota . De eso se trata en realidad.Si es peligroso o no, es la cuestión de si está tratando la rama local y remota como una cosa inseparable. A veces es razonable (cuando sus cambios son pequeños, o si está al comienzo de un desarrollo robusto, cuando los pequeños compromisos introducen cambios importantes). A veces no lo es (cuando normalmente crearías otra rama, pero eras demasiado flojo para hacerlo). Pero esa es una pregunta diferente.
fuente
git config --global pull.rebase preserve
(preservar dice además de habilitar rebase, para tratar de preservar fusiones si ha realizado alguna localmente).Me gustaría ofrecer una perspectiva diferente sobre lo que realmente significa "git pull --rebase", porque a veces parece perderse.
Si alguna vez ha usado Subversion (o CVS), puede estar acostumbrado al comportamiento de "svn update". Si tiene cambios para confirmar y el compromiso falla porque los cambios se han realizado en sentido ascendente, "svn update". Subversion procede fusionando los cambios aguas arriba con los suyos, lo que puede generar conflictos.
Lo que Subversion acaba de hacer es esencialmente "pull --rebase". El acto de reformular sus cambios locales para que sean relativos a la versión más nueva es la parte de "rebase". Si había hecho "svn diff" antes del intento de confirmación fallido, y luego compara el diff resultante con la salida de "svn diff", la diferencia entre los dos diffs es lo que hizo la operación de rebase.
La principal diferencia entre Git y Subversion en este caso es que en Subversion, "sus" cambios solo existen como cambios no confirmados en su copia de trabajo, mientras que en Git tiene confirmaciones reales localmente. En otras palabras, en Git has bifurcado la historia; su historia y la historia aguas arriba han divergido, pero usted tiene un antepasado común.
En mi opinión, en el caso normal de que su rama local simplemente refleje la rama ascendente y realice un desarrollo continuo en ella, lo correcto es siempre "--rebase", porque eso es lo que está haciendo semánticamente . Usted y otros están pirateando la historia lineal prevista de una rama. El hecho de que alguien más haya empujado un poco antes de su intento de empuje es irrelevante, y parece contraproducente que cada accidente de tiempo resulte en fusiones en la historia.
Si realmente siente la necesidad de que algo sea una rama por cualquier razón, esa es una preocupación diferente en mi opinión. Pero a menos que tenga un deseo específico y activo de representar sus cambios en forma de fusión, el comportamiento predeterminado debería, en mi opinión, ser "git pull --rebase".
Considere a otras personas que necesitan observar y comprender la historia de su proyecto. ¿Desea que la historia esté plagada de cientos de fusiones por todo el lugar, o desea solo las pocas fusiones seleccionadas que representan fusiones reales de esfuerzos de desarrollo divergentes intencionales?
fuente
git config --global branch.autosetupmerge always
?Quizás la mejor manera de explicarlo es con un ejemplo:
git checkout master && git pull
. El maestro ya está actualizado.git checkout master && git pull
. El maestro ya está actualizado.git merge topic-branch-A
git merge topic-branch-B
git push origin master
antes de Alicegit push origin master
, lo cual es rechazado porque no es una fusión de avance rápido.git pull --rebase origin master
git push origin master
, y todos están felices de no tener que leer una confirmación de fusión inútil cuando miran los registros en el futuro.Tenga en cuenta que la rama específica en la que se fusiona es irrelevante para el ejemplo. Master en este ejemplo podría ser fácilmente una rama de lanzamiento o una rama de desarrollo. El punto clave es que Alice y Bob están fusionando simultáneamente sus sucursales locales en una sucursal remota compartida.
fuente
git co master && git pull; git checkout topic-branch-A; git rebase master; git checkout master; git merge topic-branch-A; git push origin master
repito si el impulso de otro para dominar ocurrió antes que el mío. Aunque puedo ver las sucintas ventajas en tu receta.Creo que deberías usarlo
git pull --rebase
cuando colaboras con otros en la misma rama. Está en su ciclo de trabajo → compromiso → trabajo → compromiso, y cuando decide empujar su trabajo, su empuje es rechazado, porque ha habido trabajo paralelo en la misma rama. En este punto siempre hago unpull --rebase
. No uso squash (para aplanar los commits), pero reescribo para evitar los commits adicionales de fusión.A medida que aumenta su conocimiento de Git, se encuentra mirando mucho más la historia que con cualquier otro sistema de control de versiones que haya utilizado. Si tiene un montón de pequeños compromisos de fusión, es fácil perder el enfoque de la imagen más grande que está sucediendo en su historia.
Esta es en realidad la única vez que hago un rebase (*), y el resto de mi flujo de trabajo se basa en la fusión. Pero siempre que sus confirmadores más frecuentes hagan esto, la historia se verá mucho mejor al final.
(*) Mientras enseñaba un curso de Git, hice que un estudiante me arrestara por esto, ya que también abogaba por rebasar ramas de características en ciertas circunstancias. Y había leído esta respuesta;) Tal rebase también es posible, pero siempre tiene que ser de acuerdo con un sistema preestablecido / acordado, y como tal no debe "siempre" aplicarse. Y en ese momento generalmente tampoco lo hago
pull --rebase
, que es de lo que se trata la pregunta;)fuente
No creo que haya una razón para no usarlo
pull --rebase
: agregué código a Git específicamente para permitir que migit pull
comando rebase siempre contra los commits ascendentes.Al mirar a través de la historia, nunca es interesante saber cuándo el chico / chica que trabaja en la función se detuvo para sincronizarse. Puede ser útil para el chico / chica mientras lo está haciendo, pero para eso
reflog
está. Solo agrega ruido para todos los demás.fuente
pull --rebase
siempre debe usarse, ¿por qué no lo hacepull
por defecto?.gitconfig
para hacer que algunas de las opciones hagan lo correcto. Creo que git rebase hace lo incorrecto de manera predeterminada, al igual que git tag, etc. Si no está de acuerdo, no necesita justificar su opinión.master
, y si la rama a la que llegas no se ha hecho pública (todavía). Si, por el contrario,master
pasa de una rama de características a otra, es más como al revés: nunca hay una razón para usar--rebase
, ¿verdad? Esa podría ser la razón por la cual no es por defecto. Encontré que las bases son cómo deben pasar los cambios desde la parte superior de la jerarquía hacia abajo y las fusiones son cómo fluyen hacia arriba. derekgourlay.com/blog/git-when-to-merge-vs-when-to-rebaseSolo recuerda:
Por lo tanto, elija la forma en que desea manejar su sucursal.
Será mejor que sepa la diferencia entre fusionar y rebase :)
fuente
Creo que se reduce a una preferencia personal.
¿Quieres ocultar tus errores tontos antes de impulsar tus cambios? Si es así,
git pull --rebase
es perfecto. Le permite luego aplastar sus commits a unos pocos (o uno) commits. Si tiene fusiones en su historial (no eliminado), no es tan fácil hacergit rebase
uno más tarde.Personalmente, no me importa publicar todos mis errores tontos, por lo que tiendo a fusionar en lugar de rebase.
fuente
git pull --rebase
puede ocultar una reescritura del historial de un colaboradorgit push --force
. Recomiendo usargit pull --rebase
solo si sabe que olvidó presionar sus confirmaciones antes de que otra persona haga lo mismo.Si no confirmó nada, pero su espacio de trabajo no está limpio, justo
git stash
antes de hacerlogit pull
. De esta forma, no reescribirá su historial en silencio (lo que podría dejar en silencio parte de su trabajo).fuente