¿Por qué git pull realiza una combinación en lugar de una rebase de forma predeterminada?

68

Considera la siguiente situación:

  • Tienes un clon de un repositorio git
  • Tiene algunas confirmaciones locales (confirmaciones que aún no se han insertado en ninguna parte)
  • El repositorio remoto tiene nuevas confirmaciones que aún no ha reconciliado

Así que algo como esto:

Siejecutagitpullconlaconfiguraciónpredeterminada,obtendráalgocomoesto:

Estosedebeaquegitrealizóunafusión.

Sinembargo,hayunaalternativa.Puedesdecirleapullquehagaunarebase:

gitpull--rebase

yobtendrásesto:

Enmiopinión,laversiónrediseñadatienenumerosasventajasquesecentranprincipalmenteenmantenerelcódigoyelhistoriallimpios,porloquemesorprendeunpocoelhechodequegitsefusionedeformapredeterminada.Sí,loshashesdetuscompromisoslocalescambiarán,peroestopareceserunpequeñoprecioapagarporelhistorialmássimplequeobtienesacambio.

Sinembargo,deningunamaneraestoysugiriendoqueestoesdealgunamaneraundefectomalooincorrecto.Soloestoyteniendoproblemasparapensarenlasrazonesporlascualeslafusiónpodríaserpreferiblealpredeterminado.¿Tenemosalgunaideadeporquéfueelegido?¿Existenbeneficiosquelohaganmásadecuadocomopredeterminado?

Lamotivaciónprincipalparaestapreguntaesquemicompañíaestátratandodeestableceralgunosestándaresdereferencia(esperemosque,máscomodirectrices)sobrecómoorganizamosygestionamosnuestrosrepositoriosparafacilitaralosdesarrolladoreselaccesoaunrepositorioenelquenohantrabajado.conantesEstoyinteresadoenhaceruncasoenelquenormalmentedeberíamoscambiardebaseenestetipodesituación(yprobablementepararecomendaralosdesarrolladoresqueconfigurensuconfiguraciónglobalenrebasedeformapredeterminada),perosimeopusieraaeso,sindudamepreguntaríaporquénoserealizalarebase.Pordefecto,siestanbueno.Asíquemepreguntosihayalgoquemefalta.

Sehasugeridoqueestapreguntaesunduplicadode ¿Por qué tantos sitios web prefieren "git rebase" en lugar de "git merge ”? ; sin embargo, esa pregunta es en cierto modo la reversa de esta. Discute los méritos de la rebase sobre la fusión, mientras que esta pregunta se refiere a los beneficios de la fusión sobre la rebase. Las respuestas reflejan esto y se centran en los problemas de fusión y los beneficios de rebase.

    
pregunta jpmc26 11.01.2016 - 07:22

4 respuestas

55

Es difícil saber con seguridad por qué la fusión es el valor predeterminado sin escuchar a la persona que tomó la decisión.

Aquí hay una teoría ...

Git no puede suponer que está bien --rebalar cada movimiento. Escuche cómo suena. "Rebase cada tirón". simplemente suena mal si usas solicitudes de extracción o similares. ¿Te rebase en una solicitud de extracción?

En un equipo que no solo usa Git para el control de fuente centralizado ...

  • Puedes tirar de arriba y de abajo. Algunas personas hacen un montón de tirar desde el flujo descendente, desde los colaboradores, etc.

  • Puede trabajar en funciones en estrecha colaboración con otros desarrolladores, extrayendo de ellos o de una rama de tema compartido y aún así, ocasionalmente, se actualice desde arriba. Si siempre cambias de base, terminas cambiando el historial compartido, sin mencionar los ciclos de conflictos divertidos.

Git fue diseñado para un gran equipo altamente distribuido donde todos no tiran y empujan a un solo repositorio central. Así que el valor predeterminado tiene sentido.

  • Los desarrolladores que no saben cuándo se puede volver a realizar la fusión se fusionarán de forma predeterminada.
  • Los desarrolladores pueden cambiar de base cuando lo deseen.
  • Los comisionados que hacen muchos tirones y tienen muchos tirones obtienen el valor predeterminado que más les convenga.

Para evidencia de intención, aquí hay un enlace a un conocido correo electrónico de Linus Torvalds con sus puntos de vista sobre cuándo no deberían cambiar de base. correo electrónico de Dri-devel git pull

Si sigues todo el hilo, puedes ver que un desarrollador está tirando de otro desarrollador y Linus está tirando de ambos. Él hace 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 manera centralizada, donde todos los integrantes de un equipo pequeño solo extraen un repositorio central ascendente y lo empujan hacia el mismo control remoto. Este escenario evita algunas de las situaciones en las que una rebase no es buena, pero por lo general no las elimina.

Sugerencia: No establezca una política para cambiar el valor predeterminado. Cada vez que pones a Git junto con un gran grupo de desarrolladores, algunos de los desarrolladores no entenderán a Git tan profundamente (yo incluido). Ellos irán a Google, ASÍ, obtendrán consejos de cocina y luego se preguntarán por qué algunas cosas no funcionan, por ejemplo ¿Por qué git checkout --ours <path> obtiene la versión incorrecta del archivo? Siempre puede revisar su entorno local, hacer alias, etc. a su gusto.

    
respondido por el joshp 11.01.2016 - 10:28
15

Si leíste la página de manual de git para ver el rebase, dice :

  

Rebasar (o cualquier otra forma de reescritura) una rama que otros tienen   El trabajo basado en es una mala idea: cualquier persona que esté más abajo se vea obligada a   arregla manualmente su historia Esta sección explica cómo hacer la corrección.   desde el punto de vista de aguas abajo. La solución real, sin embargo, sería   para evitar volver a basar el flujo ascendente en primer lugar.

Creo que eso lo dice lo suficientemente bien como una razón para no utilizar el rebase, y mucho menos hacerlo automáticamente para cada tirón. Algunas personas consideran que la rebase es perjudicial . Quizás nunca debió haber sido puesto en git, ya que todo lo que parece hacer es pretender la historia, algo que no debería ser necesario en ningún SCM cuyo único trabajo esencial es preservar la historia.

Cuando dices 'mantener ... la historia limpia', piensa que estás equivocado. Puede parecer mejor, pero para una herramienta que está diseñada para mantener el historial de revisiones, es mucho más limpio mantener cada compromiso para que pueda ver lo que sucedió. Desinfectar la historia después es como pulir la pátina, hacer que una antigüedad rica parezca un repro brillante :-)

    
respondido por el gbjbaanb 11.01.2016 - 15:53
12

Tienes razón, asumiendo que solo tienes un repositorio local / modificado. Sin embargo, considera que hay una segunda PC local, por ejemplo.

Una vez que su copia local / modificada sea empujada en algún otro lugar, la redistribución de información irá a parar esas copias. Por supuesto, podrías forzar el empuje, pero eso se complica rápidamente. ¿Qué sucede si uno o más de estos tienen otro compromiso completamente nuevo?

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 coherente con el tiempo. Después de las rebases, es muy probable que las confirmaciones más antiguas sigan cambios más recientes, lo que hace que todo el historial y su flujo sean más difíciles de entender.

    
respondido por el Mario 11.01.2016 - 08:25
6

La gran razón es probablemente que el comportamiento predeterminado debería "simplemente funcionar" en repositorios públicos. Volver a cambiar la historia que otras personas ya han fusionado les causará problemas. Sé que estás hablando de tu repo privado, pero, en general, git no sabe ni se preocupa por lo que es privado o público, por lo que el valor predeterminado elegido será el predeterminado para ambos.

Utilizo bastante git pull --rebase en mi repositorio privado, pero incluso allí tiene una desventaja potencial, que es que el historial de mi HEAD ya no refleja el árbol, ya que realmente trabajé en él.

Entonces, para un gran ejemplo, supongamos que siempre hago pruebas y me aseguro de que pasen antes de hacer un compromiso. Esto tiene menos relevancia después de hacer un git pull --rebase , porque ya no es cierto que el árbol en cada una de mis confirmaciones haya pasado las pruebas. Siempre que los cambios no interfieran de ninguna manera, y el código que extraigo haya sido probado, entonces presumiblemente pasaría las pruebas, pero no lo sabemos porque nunca lo probé. Si la integración continua es una parte importante de su flujo de trabajo, entonces cualquier tipo de rebase en un repositorio que esté siendo CIed es preocupante.

Realmente no me importa esto, pero sí molesta a algunas personas: preferirían que su historial en git refleje el código en el que realmente trabajaron (o quizás para cuando lo presionen, una versión simplificada de la verdad). después de algún uso de "reparación").

No sé si este problema en particular es la razón por la que Linus optó por fusionarse en lugar de rebasar de forma predeterminada. Podría haber otras desventajas que no he encontrado. Pero como no es tímido para expresar su opinión en el código, estoy bastante seguro de que se trata de lo que él piensa que es un flujo de trabajo adecuado para las personas que no quieren pensar demasiado en esto (y especialmente en aquellos que trabajan en un público y no que un repo privado). Evitar líneas paralelas en el gráfico bonito, en favor de una línea recta limpia que no represente el desarrollo paralelo como sucedió, probablemente no sea su máxima prioridad aunque sea suya :-)

    
respondido por el Steve Jessop 11.01.2016 - 15:27

Lea otras preguntas en las etiquetas