Considere la siguiente situación:
- Tienes un clon de un repositorio git
- Tiene algunas confirmaciones locales (confirmaciones que aún no se han enviado a ninguna parte)
- El repositorio remoto tiene nuevas confirmaciones que aún no ha reconciliado.
Entonces algo como esto:
Si ejecuta git pull
con la configuración predeterminada, obtendrá algo como esto:
Esto se debe a que git realizó una fusión.
Sin embargo, hay una alternativa. Puedes decirle a pull que haga un rebase:
git pull --rebase
y obtendrás esto:
En mi opinión, la versión rebajada tiene numerosas ventajas que se centran principalmente en mantener limpios tanto el código como el historial, por lo que me sorprende un poco el hecho de que git se fusiona de forma predeterminada. Sí, los hash de sus confirmaciones locales cambiarán, pero esto parece un pequeño precio a pagar por el historial más simple que obtiene a cambio.
Sin embargo, de ninguna manera estoy sugiriendo que esto es de alguna manera un defecto malo o incorrecto. Solo tengo problemas para pensar en las razones por las que la fusión podría ser la preferida por defecto. ¿Tenemos alguna idea de por qué fue elegido? ¿Hay beneficios que lo hacen más adecuado por defecto?
La principal motivación para esta pregunta es que mi empresa está tratando de establecer algunos estándares de línea de base (con suerte, más como pautas) sobre cómo organizamos y gestionamos nuestros repositorios para que sea más fácil para los desarrolladores acercarse a un repositorio con el que no han trabajado antes. Estoy interesado en argumentar que, por lo general, deberíamos cambiar la base en este tipo de situación (y probablemente recomendar a los desarrolladores que configuren su configuración global para rebase de forma predeterminada), pero si me opusiera a eso, sin duda estaría preguntando por qué rebase no t por defecto si es tan genial. Así que me pregunto si hay algo que me falta.
Se ha sugerido que esta pregunta es un duplicado de ¿Por qué tantos sitios web prefieren "git rebase" sobre "git merge"? ; sin embargo, esa pregunta es algo inversa a esta. Discute los méritos de rebase sobre fusionar, mientras que esta pregunta pregunta sobre los beneficios de fusionar sobre rebase. Las respuestas allí reflejan esto, enfocándose en los problemas de fusión y los beneficios de rebase.
Respuestas:
Es difícil saber con certeza por qué la fusión es el valor predeterminado sin tener noticias de la persona que tomó esa decisión.
Aquí hay una teoría ...
Git no puede suponer que está bien --rebase cada tirón. Escucha cómo suena eso. "Rebase cada tirón". simplemente suena mal si usa solicitudes de extracción o similar. ¿Revocarías una solicitud de extracción?
En un equipo que no solo usa Git para el control de fuente centralizado ...
Puede tirar desde aguas arriba y aguas abajo. Algunas personas hacen muchos esfuerzos desde aguas abajo, desde contribuyentes, etc.
Puede trabajar en funciones en estrecha colaboración con otros desarrolladores, extrayéndolos de ellos o de una rama de temas compartidos y, de vez en cuando, actualizándolos de manera ascendente. Si siempre cambias de base, entonces terminas cambiando el historial compartido, sin mencionar los divertidos ciclos de conflicto.
Git fue diseñado para un gran equipo altamente distribuido en el que todos no se mueven y empujan a un único repositorio central. Entonces el valor predeterminado tiene sentido.
Como prueba de intención, aquí hay un enlace a un correo electrónico bien conocido de Linus Torvalds con sus puntos de vista sobre cuándo no deberían volver a redactar. Dri-devel git pull email
Si sigue todo el hilo, puede ver que un desarrollador está tirando de otro desarrollador y Linus está tirando de ambos. Él deja su opinión bastante clara. Dado que probablemente decidió los valores predeterminados de Git, esto podría explicar por qué.
Muchas personas ahora usan Git de forma centralizada, donde todos en un equipo pequeño solo extraen de un repositorio central ascendente y empujan a ese mismo control remoto. Este escenario evita algunas de las situaciones en las que un rebase no es bueno, pero generalmente no los elimina.
Sugerencia: no establezca una política de cambio del valor predeterminado. Cada vez que reúnes a Git con un gran grupo de desarrolladores, algunos de los desarrolladores no entenderán a Git tan profundamente (incluido yo mismo). Irán a Google, SO, recibirán consejos sobre libros de cocina y luego se preguntarán por qué algunas cosas no funcionan, por ejemplo, ¿por qué se
git checkout --ours <path>
obtiene la versión incorrecta del archivo? Siempre puede revisar su entorno local, crear alias, etc. a su gusto.fuente
Si lees la página de manual de git para rebase, dice :
Creo que eso lo dice lo suficientemente bien como una razón para no usar rebase en absoluto, y mucho menos hacerlo automáticamente para cada tirón. Algunas personas consideran que rebase es dañino . Quizás nunca debería haberse puesto en git, ya que todo lo que parece hacer es embellecer la historia, algo que no debería ser necesario en cualquier SCM cuyo único trabajo esencial es preservar la historia.
Cuando diga 'mantener limpia la historia', piense que está equivocado. Puede parecer más agradable, pero para una herramienta diseñada para mantener el historial de revisiones, es mucho más limpio mantener cada confirmación para que pueda ver lo que sucedió. Desinfectar la historia después es como pulir la pátina, haciendo que una antigüedad antigua parezca una reproducción brillante :-)
fuente
Tienes razón, suponiendo que solo tienes un repositorio local / modificado. Sin embargo, considere que hay una segunda PC local, por ejemplo.
Una vez que su copia local / modificada es empujada a otro lugar, el rebase arruinará esas copias. Por supuesto, podrías forzar a empujar, pero eso rápidamente se vuelve complicado. ¿Qué sucede si uno o más de estos tienen otra confirmación completamente nueva?
Como puede ver, es muy situacional, pero la estrategia base parece (para mí) mucho más práctica en casos no especiales / de colaboración.
Una segunda diferencia: la estrategia de fusión mantendrá una estructura clara y consistente en el tiempo. Después de los rebases, es muy probable que los commits más antiguos sigan los cambios más nuevos, haciendo que la historia completa y su flujo sean más difíciles de entender.
fuente
La gran razón es probablemente que el comportamiento predeterminado debería "funcionar" en repositorios públicos. Rebasar la historia de que otras personas ya se han fusionado les causará problemas. Sé que estás hablando de tu repositorio privado, pero en general, git no sabe ni le importa lo que es privado o público, por lo que el valor predeterminado elegido será el predeterminado para ambos.
Utilizo
git pull --rebase
mucho en mi repositorio privado, pero incluso allí tiene una desventaja potencial, que es que la historia de miHEAD
ya no refleja el árbol ya que realmente trabajé en él.Entonces, para un gran ejemplo, supongamos que siempre ejecuto pruebas y me aseguro de que pasen antes de realizar una confirmación. Esto tiene menos relevancia después de hacer un
git pull --rebase
, porque ya no es cierto que el árbol en cada uno de mis commits haya pasado las pruebas. Siempre y cuando los cambios no interfieren de ninguna manera, y el código de saco ha sido probado, es de suponer que sería pasar las pruebas, pero no sabemos porque nunca he probado. Si la integración continua es una parte importante de su flujo de trabajo, cualquier tipo de rebase en un repositorio que se está creando CI es problemático.Realmente no me importa esto, pero molesta a algunas personas: preferirían que su historial en git refleje el código en el que realmente trabajaron (o tal vez para cuando lo presionen, una versión simplificada de la verdad después de algún uso de "arreglo").
No sé si este problema en particular es la razón por la que Linus eligió fusionarse en lugar de rebase por defecto. Podría haber otras desventajas que no he encontrado. Pero dado que no tiene miedo de expresar su opinión en código, estoy bastante seguro de que se trata de lo que él cree que es un flujo de trabajo adecuado para las personas que no quieren pensar demasiado en ello (y especialmente aquellos que trabajan en público que un repositorio privado). Evitar líneas paralelas en el gráfico bonito, a favor de una línea recta limpia que no represente el desarrollo paralelo como sucedió, probablemente no sea su principal prioridad, aunque sea la suya :-)
fuente