por qué fusionarse no causa conflicto

Esta pregunta sigue a este tema . Estoy tratando de entender qué es lo que se merge para evitar errores no deseados durante el mismo.

Tengo dos twigs: master , b . Vi un extraño resultado de hacer git merge . Puede ver la salida del logging de git antes de la fusión , aquí:

 * 148c970 (HEAD, master) rename 1 in master to 1_master | * ad18d9b (b) rename 1 in b to 1_b |/ * 15cd89b add 1 in master 

Así que tenía un file con el nombre 1 en el master y b . A continuación, cambie el nombre en master por 1_master y por 1_b en b . Luego hice git merge :

 git merge b 

Supongo que causa un conflicto, porque la base de combinación debe ser 15cd89b y ambas twigs introducen cambios en 1 , que no coinciden.

Pero la fusión no causó ningún conflict y después de fusionar vi tanto 1_b como 1_master en el directory de trabajo.

Nota:

Creo que tanto torek como twalberg en las respuestas vinculadas pronostican el conflicto en la situación anterior.

Si bash reproducir su problema, me sale un conflicto de renombrar / cambiar el nombre, como era de esperar. Primero, creé un repository y algunos files (con contenido único):

 $ mkdir rename-exp $ cd rename-exp/ $ git init Initialized empty Git repository in /home/torek/tmp/rename-exp/.git/ $ cat > 1 This is file "1" in its initial state. The file is being used for a test of what happens with a rename vs rename conflict in Git. The file needs some contents so that git can detect the rename when we actually do the rename. $ cat > 2 This is file "2". We give it some contents so that it has a unique SHA-1. $ git add . $ git commit -m initial [master (root-commit) a4b6f52] initial 2 files changed, 12 insertions(+) create mode 100644 1 create mode 100644 2 

A continuación, creo la twig b y cambio de nombre. Tenga en count que no importará si hago el cambio de nombre con git mv o con mv seguido de git rm --cached y git add (pero git mv es más fácil, entonces lo uso). Sin embargo, es importante que git pueda detectar el cambio de nombre. Esto requiere que los files coincidan exactamente al 100% (el caso fácil) o que coincidan con "al less el 50%" (este umbral se puede ajustar, pero el 50% es el valor pnetworkingeterminado) cuando se difieren y que el nombre anterior ( 1 ) ya no está presente en ambos treees en el momento de la git merge .

 $ git checkout -bb Switched to a new branch 'b' $ git mv 1 1_b $ git commit -m 'rename 1 to 1_b in branch b' [b cc104b1] rename 1 to 1_b in branch b 1 file changed, 0 insertions(+), 0 deletions(-) rename 1 => 1_b (100%) 

Luego hago el mismo cambio de nombre, con un nombre-objective diferente, en el master :

 $ git checkout master Switched to branch 'master' $ git mv 1 1_master $ git commit -m 'rename 1 to 1_master in master' [master b891757] rename 1 to 1_master in master 1 file changed, 0 insertions(+), 0 deletions(-) rename 1 => 1_master (100%) 

Finalmente, ejecuto git merge :

 $ git merge b CONFLICT (rename/rename): Rename "1"->"1_master" in branch "HEAD" rename "1"->"1_b" in "b" Automatic merge failed; fix conflicts and then commit the result. $ 

Tendrás que mostrar tus pasos (y tal vez también tu versión de git) para que pueda ver por qué tu combinación pensó que cada cambio era de eliminar y crear (con creaciones no conflictivas) en lugar de cambiar el nombre.

Otras variables que afectan esto:

  • cualquier argumento para -X rename-threshold durante la fusión (así es como sintonizas el 50% por defecto);
  • el valor de git config --get merge.renameLimit
  • el valor de git config --get diff.renameLimit , si no hay ninguna configuration para merge.renameLimit .

Creo que es porque Git no sabe realmente el concepto de cambiar el nombre de un file. Vea las preguntas frecuentes de Git .
Para Git es solo add 1_master seguido de remove 1 . Lo que hiciste es

en la twig principal:

  • agregar file 1_master
  • eliminar el file 1

y en la twig b:

  • agregar file 1_b
  • eliminar el file 1

Entonces en resumen (es decir, fusión ) esto da:

  • agregar file 1_master
  • agregar file 1_b
  • eliminar el file 1

No conflicto. Ambas twigs aplican la misma operación al file 1 : eliminarlo.

Las cosas cambiarían si hubiera editado el file 1 en una de sus sucursales. Entonces, Git no sabría si aplicar la edición o la eliminación .