La fusión de avance rápido tiene sentido para las ramas de corta duración, pero en una historia más compleja , la fusión sin avance rápido puede hacer que la historia sea más fácil de entender y facilitar la reversión de un grupo de confirmaciones.
Advertencia : el reenvío no rápido también tiene posibles efectos secundarios. Revise https://sandofsky.com/blog/git-workflow.html , evite el 'no-ff' con sus "confirmaciones de puntos de control" que rompen la bisección o la culpa, y considere cuidadosamente si debería ser su enfoque predeterminado master
.
(De nvie.com , Vincent Driessen , publique " Un modelo de ramificación Git exitoso ")
Incorporando una característica terminada en desarrollo
Las funciones 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 --no-ff
indicador hace que la fusión siempre cree un nuevo objeto de confirmación, incluso si la fusión se puede realizar con un avance rápido. Esto evita perder información sobre la existencia histórica de una rama de características y agrupa todas las confirmaciones que juntas agregaron la característica.
Jakub Narębski también menciona la configuraciónmerge.ff
:
De forma predeterminada, Git no crea una confirmación de fusión adicional al fusionar una confirmación que es descendiente de la confirmación actual. En cambio, la punta de la rama actual se reenvía rápidamente.
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 el--no-ff
opción desde la línea de comando).
Cuando se establece en ' only
', solo se permiten esas fusiones de avance rápido (equivalente a dar la --ff-only
opción desde la línea de comando).
El avance rápido es el predeterminado porque:
- Las ramas de corta duración son muy fáciles de crear y usar en Git
- Las ramas de corta duración a menudo aíslan muchas confirmaciones que pueden reorganizarse libremente dentro de esa rama
- esos commits son en realidad parte de la rama principal: una vez reorganizados, la rama principal se reenvía rápidamente para incluirlos.
Pero si anticipa un flujo de trabajo iterativo en un tema / rama de características (es decir, me fusiono, luego vuelvo a esta rama de características y agrego más confirmaciones), entonces es útil incluir solo la fusión en la rama principal, en lugar de todos los commits intermedios de la rama de características.
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 agrega en los comentarios:
Veo algo de sentido en el avance rápido para ramas [de corta duración], pero convertirlo en la acción predeterminada significa que git asume que ... a menudo tiene 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 muchas más ramas de corta duración.
Para mí, una rama de corta duración es la que creo para facilitar una determinada operación (rebase, probable, o parches y pruebas rápidas), y luego eliminar inmediatamente una vez que haya terminado.
Eso significa que probablemente debería ser absorbido por la rama del tema de la que se bifurcó , y la rama del tema se fusionará como una rama. Nadie necesita saber qué 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 fusionarlas repetidamente, varias ramas tienen sentido.
Consulte "¿ Cuándo debe ramificarse? "
En realidad, cuando considera el modelo de rama Mercurial, está en su núcleo una rama por repositorio (aunque puede crear cabezas anónimas, marcadores e incluso ramas con nombre )
Consulte "Git y Mercurial - Comparar y contrastar" .
Mercurial, por defecto, utiliza líneas de código anónimas y ligeras, que en su terminología se llaman "cabezas".
Git usa ramas con nombre livianas, con mapeo inyectivo para mapear nombres de ramas en repositorio remoto a nombres de ramas de seguimiento remoto.
Git "lo obliga" a nombrar ramas (bueno, con la excepción de una sola rama sin nombre, que es una situación llamada " CABEZA separada "), pero creo que esto funciona mejor con flujos de trabajo con muchas ramas, como el flujo de trabajo de rama temática, lo que significa múltiples ramas en un solo paradigma de repositorio.
no-ff
' con sus "confirmaciones de puntos de control" que rompen la culpa o la bisecta.