Pregunta ¿Cuál es la diferencia entre `git merge` y` git merge --no-ff`?


Utilizando gitk log, No pude ver una diferencia entre los dos. ¿Cómo puedo observar la diferencia (con un comando git o alguna herramienta)?


628
2018-01-30 18:45


origen


Respuestas:


los --no-ff bandera impide git merge de ejecutar un "avance rápido" si detecta que su actual HEAD es un ancestro del compromiso que intentas fusionar. Un avance rápido es cuando, en lugar de construir un commit de fusión, git simplemente mueve su puntero de sucursal para apuntar a la confirmación entrante. Esto ocurre comúnmente al hacer una git pull sin ningún cambio local

Sin embargo, ocasionalmente desea evitar que ocurra este comportamiento, generalmente porque desea mantener una topología de bifurcación específica (por ejemplo, se está fusionando en una rama de tema y desea asegurarse de que se vea de esa manera cuando se lee el historial). Para hacer eso, puedes pasar el --no-ff bandera y git merge será siempre construir una fusión en lugar de un avance rápido.

Del mismo modo, si desea ejecutar una git pull o usar git merge para avanzar de manera explícita, y si desea rescatar si no puede avanzar rápidamente, puede usar --ff-only bandera. De esta forma regularmente puedes hacer algo como git pull --ff-only sin pensarlo, y luego, si se equivoca, puede regresar y decidir si desea fusionar o volver a establecer la base.


723
2018-01-30 18:51



Respuesta gráfica a esta pregunta

Aquí hay un sitio con una explicación clara e ilustración gráfica del uso git merge --no-ff:

difference between git merge --no-ff and git merge

Hasta que vi esto, estaba completamente perdido con git. Utilizando --no-ff permite que alguien revise la historia claramente mira la rama que compraste para trabajar en. (ese enlace apunta a la herramienta de visualización de "red" de github) Y aquí está otra gran referencia con ilustraciones. Esta referencia complementa muy bien la primera con un enfoque más centrado en aquellos menos familiarizados con git.


Información básica para los recién nacidos como yo

Si eres como yo, y no un Git-guru, mi respuesta aquí describe el manejo de la eliminación de archivos del seguimiento de git sin eliminarlos del sistema de archivos local, que parece estar poco documentado pero a menudo ocurre. Otra situación newb es obteniendo el código actual, que aún se las arregla para eludirme.


Ejemplo de flujo de trabajo

Actualicé un paquete a mi sitio web y tuve que volver a mis notas para ver mi flujo de trabajo; Pensé que era útil agregar un ejemplo a esta respuesta.

Mi flujo de trabajo de los comandos de git:

git checkout -b contact-form
(do your work on "contact-form")
git status
git commit -am  "updated form in contact module"
git checkout master
git merge --no-ff contact-form
git branch -d contact-form
git push origin master

Abajo: uso real, incluidas las explicaciones.
Nota: el resultado a continuación se corta; git es bastante detallado.

$ git status
# On branch master
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   ecc/Desktop.php
#       modified:   ecc/Mobile.php
#       deleted:    ecc/ecc-config.php
#       modified:   ecc/readme.txt
#       modified:   ecc/test.php
#       deleted:    passthru-adapter.igs
#       deleted:    shop/mickey/index.php
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       ecc/upgrade.php
#       ecc/webgility-config.php
#       ecc/webgility-config.php.bak
#       ecc/webgility-magento.php

Note 3 cosas de arriba:
1) En la salida, puede ver los cambios de la actualización del paquete ECC, incluida la adición de nuevos archivos.
2) También note que hay dos archivos (no en el /ecc carpeta) borré independientemente de este cambio. En lugar de confundir esas eliminaciones de archivos con ecc, Haré una diferente cleanuprama más tarde para reflejar la eliminación de esos archivos.
3) ¡No seguí mi flujo de trabajo! Me olvidé de git mientras intentaba hacer que ecc volviera a funcionar.

A continuación: en lugar de hacer el todo incluido git commit -am "updated ecc package" Normalmente lo haría, solo quería agregar los archivos en /ecc carpeta. Esos archivos eliminados no eran específicamente parte de mi git add, pero como ya fueron rastreados en git, necesito eliminarlos de la confirmación de esta rama:

$ git checkout -b ecc
$ git add ecc/*
$ git reset HEAD passthru-adapter.igs
$ git reset HEAD shop/mickey/index.php
Unstaged changes after reset:
M       passthru-adapter.igs
M       shop/mickey/index.php

$ git commit -m "Webgility ecc desktop connector files; integrates with Quickbooks"

$ git checkout master
D       passthru-adapter.igs
D       shop/mickey/index.php
Switched to branch 'master'
$ git merge --no-ff ecc
$ git branch -d ecc
Deleted branch ecc (was 98269a2).
$ git push origin master
Counting objects: 22, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (14/14), 59.00 KiB, done.
Total 14 (delta 10), reused 0 (delta 0)
To git@github.com:me/mywebsite.git
   8a0d9ec..333eff5  master -> master



Script para automatizar lo anterior

Después de haber usado este proceso más de 10 veces en un día, me he dedicado a escribir guiones por lotes para ejecutar los comandos, así que hice un trabajo casi correcto. git_update.sh <branch> <"commit message"> secuencia de comandos para hacer los pasos anteriores. Aquí está la fuente de Gist para ese guion

En lugar de git commit -am Estoy seleccionando archivos de la lista "modificada" producida a través de git status y luego pegarlos en este guión. Esto ocurrió porque realicé docenas de ediciones pero quería nombres de ramas variados para ayudar a agrupar los cambios.


733
2018-02-14 00:08



los --no-ff opción asegura que no se producirá una fusión de avance rápido, y que un nuevo objeto de compromiso siempre será creado. Esto puede ser deseable si desea que git mantenga un historial de ramas de características. git merge --no-ff vs git merge En la imagen de arriba, el lado izquierdo es un ejemplo del historial de git después de usar git merge --no-ff y el lado derecho es un ejemplo de uso git merge donde una fusión FF era posible.

EDITAR: Una versión anterior de esta imagen indicaba solo un padre único para la confirmación de fusión. Las asignaciones de mezcla tienen múltiples confirmaciones principales que git usa para mantener un historial de la "rama de característica" y de la rama original. Los enlaces principales múltiples se resaltan en verde.


150
2018-02-12 02:33



Esta es una vieja pregunta, y esto se menciona sutilmente en las otras publicaciones, pero la explicación que hizo que este clic para mí fuera las fusiones hacia adelante no rápidas requerirán un compromiso separado.


32
2018-04-02 19:56