tag repositorio remota ramas rama que para fusionar crear cambiar git git-branch git-merge fast-forward

repositorio - ¿Por qué git fast-forward se fusiona de forma predeterminada?



git tag (2)

Procedente de mercurial, utilizo ramas para organizar características. Naturalmente, quiero ver este flujo de trabajo en mi historia también.

Comencé mi nuevo proyecto usando git y terminé mi primera función. Al fusionar la función, me di cuenta de que git usa el avance rápido, es decir, aplica mis cambios directamente a la rama maestra si es posible y se olvida de mi rama.

Así que para pensar en el futuro: soy el único que trabaja en este proyecto. Si utilizo el enfoque por defecto de git (combinación de avance rápido), mi historial resultaría en una rama maestra gigante. Nadie sabe que usé una rama separada para cada función, porque al final solo tendré esa rama maestra gigante. ¿No se verá poco profesional?

Por este razonamiento, no quiero una fusión rápida y no puedo ver por qué es el valor predeterminado. ¿Qué tiene de bueno?


La combinación de avance rápido tiene sentido para las sucursales de corta duración, pero en una historia más compleja , la fusión de no avance rápido puede hacer que el historial sea más fácil de entender y hacer que sea más fácil revertir un grupo de confirmaciones.

Advertencia : el no avance rápido también tiene efectos secundarios potenciales. Revise https://sandofsky.com/blog/git-workflow.html , evite el ''no-ff'' con sus "confirmaciones de punto de control" que rompen bisecto o culpa, y considere cuidadosamente si debería ser su enfoque predeterminado para el master .


(De nvie.com , Vincent Driessen , publica " Un exitoso modelo de bifurcación de Git ")

Incorporando una característica terminada en desarrollo.

Las características terminadas se pueden combinar en la rama de desarrollo para agregarlas a la próxima versión:

$ git checkout develop Switched to branch ''develop'' $ git merge --no-ff myfeature Updating ea1b82a..05e9557 (Summary of changes) $ git branch -d myfeature Deleted branch myfeature (was 05e9557). $ git push origin develop

El indicador --no-ff hace que la combinación cree siempre un nuevo objeto de confirmación, incluso si la combinación se puede realizar con un avance rápido. Esto evita la pérdida de información sobre la existencia histórica de una rama de características y agrupa a todos los confirmaciones que juntas agregaron la característica.

Jakub Narębski también mentions la configuración merge.ff :

De forma predeterminada, Git no crea una confirmación de combinación adicional al fusionar una confirmación que es un descendiente de la confirmación actual. En cambio, la punta de la rama actual es de avance rápido.
Cuando se establece en false , esta variable le dice a Git que cree una confirmación de fusión adicional en tal caso (equivalente a dar la --no-ff desde la línea de comando).
Cuando se establece en '' only '', solo se permiten tales --ff-only avance rápido (equivalentes a dar la opción --ff-only desde la línea de comandos).

El avance rápido es el predeterminado porque:

  • Las sucursales de corta duración son muy fáciles de crear y usar en Git
  • las ramas de corta duración a menudo aíslan muchos compromisos que pueden reorganizarse libremente dentro de esa rama
  • esos compromisos son en realidad parte de la rama principal: una vez reorganizados, la rama principal se adelanta para incluirlos.

Pero si anticipa un flujo de trabajo iterativo en una rama de tema / característica (es decir, fusiono, luego vuelvo a esta rama de función y agrego algunos más confirmaciones), entonces es útil incluir solo la combinación en la rama principal, en lugar de Todas las confirmaciones intermedias de la rama característica.

En este caso, puede terminar configurando este tipo de archivo de configuración :

[branch "master"] # This is the list of cmdline options that should be added to git-merge # when I merge commits into the master branch. # The option --no-commit instructs git not to commit the merge # by default. This allows me to do some final adjustment to the commit log # message before it gets commited. I often use this to add extra info to # the merge message or rewrite my local branch names in the commit message # to branch names that are more understandable to the casual reader of the git log. # Option --no-ff instructs git to always record a merge commit, even if # the branch being merged into can be fast-forwarded. This is often the # case when you create a short-lived topic branch which tracks master, do # some changes on the topic branch and then merge the changes into the # master which remained unchanged while you were doing your work on the # topic branch. In this case the master branch can be fast-forwarded (that # is the tip of the master branch can be updated to point to the tip of # the topic branch) and this is what git does by default. With --no-ff # option set, git creates a real merge commit which records the fact that # another branch was merged. I find this easier to understand and read in # the log. mergeoptions = --no-commit --no-ff

El OP añade en los comentarios:

Veo algo de sentido en el avance rápido para las sucursales [de corta duración], pero al convertirlo en la acción predeterminada significa que Git asume que ... a menudo tienen ramas [de corta duración]. ¿Razonable?

Jefromi responde:

Creo que la vida útil de las sucursales varía mucho de un usuario a otro. Sin embargo, entre los usuarios experimentados, probablemente haya una tendencia a tener sucursales mucho más efímeras.

Para mí, una rama de corta duración es una que creo para facilitar una determinada operación (rebasar, probablemente, o parchear y probar rápidamente), y luego eliminar inmediatamente una vez que termine.
Eso significa que probablemente debería ser absorbido por la rama temática desde la cual se bifurcó , y la rama temática se fusionará como una rama. Nadie necesita saber lo que hice internamente para crear la serie de confirmaciones que implementan esa característica dada.

Más en general, agrego:

Realmente depende de su flujo de trabajo de desarrollo :

  • Si es lineal, una rama tiene sentido.
  • Si necesita aislar características y trabajar en ellas durante un largo período de tiempo y combinarlas repetidamente, varias ramas tienen sentido.

Ver "¿ Cuándo debes ramificar? "

En realidad, cuando considera el modelo de rama de Mercurial, es en su núcleo una rama por repositorio (aunque puede crear cabezas anónimas, marcadores e incluso ramas con nombre )
Ver "Git y Mercurial - Comparar y contrastar" .

Mercurial, por defecto, utiliza líneas de código anónimas de peso ligero, que en su terminología se denominan "jefes".
Git utiliza ramas con nombre ligero, con mapeo inyectivo para asignar nombres de ramas en el repositorio remoto a nombres de ramas de seguimiento remoto.
Git lo "obliga" a nombrar sucursales (bueno, con la excepción de una única sucursal sin nombre, que es una situación llamada " HEAD desapegada "), pero creo que esto funciona mejor con flujos de trabajo con muchas ramas, como el flujo de trabajo de la rama temática, es decir, Ramas múltiples en un paradigma de repositorio único.


Permítanme ampliar un poco la respuesta muy completa de un VonC :

Primero, si lo recuerdo correctamente, el hecho de que Git por defecto no cree confirmaciones de mezcla en el caso de avance rápido se debe a la consideración de "repositorios iguales" de una sola rama, donde se utiliza la extracción mutua para sincronizar esos dos repositorios (un El flujo de trabajo que puede encontrar como primer ejemplo en la mayoría de la documentación del usuario, incluido el "Manual del usuario de Git" y "Control de versiones por ejemplo"). En este caso, no utiliza la función de extracción para fusionar una rama completamente realizada, la utiliza para mantenerse al día con otros trabajos. No querrá tener un hecho efímero y sin importancia cuando haga una sincronización guardada y almacenada en el repositorio, guardada para el futuro.

Tenga en cuenta que la utilidad de las ramas de características y de tener múltiples sucursales en el repositorio único llegó más tarde, con un uso más generalizado de VCS con un buen soporte de fusión y con varios flujos de trabajo basados ​​en combinación. Es por eso que, por ejemplo, Mercurial originalmente admitía solo una sucursal por repositorio (más consejos anónimos para el seguimiento de sucursales remotas), como se ve en revisiones anteriores de "Mercurial: La Guía Definitiva".

En segundo lugar, cuando se siguen las mejores prácticas de uso de las ramas de características , es decir, que las ramas de las características deben comenzar desde la versión estable (generalmente desde la última versión), para poder seleccionar y seleccionar qué funciones incluir al seleccionar qué ramas de las entidades se fusionarán, por lo general no están en una situación de avance rápido ... lo que hace que este problema sea discutible. Debe preocuparse por crear una fusión verdadera y no avanzar rápidamente al fusionar una primera rama (suponiendo que no coloque cambios de confirmación única directamente en ''maestro''); todas las otras fusiones posteriores son, por supuesto, en una situación de no avance rápido.

HTH