¿Por qué Git se fusiona creando múltiples commits en la twig principal?

Hay dos twigs con las que estoy trabajando, master y newFeature . Mientras newFeature la "nueva característica", agregué varias confirmaciones a la newFeature twig de newFeature . Mi comprensión de la git merge de git merge es que creará una confirmación única en el master una vez que se fusionen las twigs, sin embargo, cuando se fusiona, el master ahora tiene el historial de confirmación completo que está en la característica newFeature . Por ejemplo-

 master (pre-merge): 1=>2=>3 newVersion: 1=>2=>3=>4=>5=>6 master (actual results of merge): 1=>2=>3=>4=>5=>6 master (expected results of merge): 1=>2=>3=>6 

¿Hay alguna manera de eliminar las confirmaciones intermedias de newVersion durante la fusión, y por qué la fusión no funciona como se esperaba?

La key a tener en count aquí, es que no se han realizado cambios para master largo del curso de su trabajo en newVersion . En estas situaciones, Git adopta por defecto una fusión de "avance rápido", que esencialmente se puede considerar que toma todos los nuevos commits de newVersion y los newVersion al commit más reciente en master (que no separa el historial de commit que fue hecho en newVersion ). Esto se puede anular con el indicador --no-ff , por ejemplo:

 git merge newVersion --no-ff 

Resultados en:

 master (pre-merge): 1=>2=>3 newVersion: 1=>2=>3=>4=>5=>6 master (actual results of merge): 1=>2=>3=========>7 4=>5=>6 

Tenga en count que, commit 7 representa la fusión, y no reemplaza el historial de commit.

Referencia: https://sandofsky.com/images/fast_forward.pdf

Alternativamente, si prefiere consolidar todo el historial de newVersion de newVersion en una sola confirmación en el master (podría ser útil si fueran simplemente commits menores a lo largo de la progresión de la "nueva versión") podría ejecutar la fusión con --squash bandera. Por ejemplo:

 git merge --squash newVersion 

Resultados en:

 master (pre-merge): 1=>2=>3 newVersion: 1=>2=>3=>4=>5=>6 master (actual results of merge): 1=>2=>3=>7 

Tenga en count que, 7 consolida el historial de confirmación que se realizó en commit 4 – 6

No es posible tener un historial final que se parece a lo que quieres. Cada commit en git está vinculado a su padre. Cada confirmación contiene una reference a su padre, por lo que 6 hace reference explícita a 5.

Si realmente desea que solo se agreguen los cambios entre 5 y 6 además de 1=>2=>3 , entonces puede usar git cherry-pick newFeature . Esto creará un nuevo compromiso que tiene solo los cambios entre 5 y 6, pero aplicado sobre los 3.

Si quiere todos los cambios de 4, 5 y 6, pero solo quiere una única confirmación, puede usar la bandera --squash para git merge . Esto creará una única confirmación nueva que contiene todos los cambios de 4, 5 y 6. Sin embargo, su historial no será 1=>2=>3=>6 , pero 1=>2=>3=>7 donde 7 es este nuevo compromiso.

Tenga en count que si elige la opción --squash , solo puede hacer esto una vez para cada twig, ya que al aplastar, está perdiendo la información sobre lo que es diferente entre las dos twigs.