Mecanismos internos de Mercurial sobre files conflits

Estoy estudiando Mercurial, pero no entiendo cómo detecta los conflictos de files.

Cuando un SCM centralizado (como SubVersion) detecta un conflit entre dos versiones de un file en mi proyecto, significa que el número de versión del file local de mina es menor que el número de versión del mismo file en el repository remoto, porque otro desarrollador (pe John Smith ) se ha comprometido antes que yo (con el mismo número de versión inicial).

En un SCM descentralizado (Mercurial, Git, etc.), no tengo un repository central, entonces:

  • Yo clono un repository, descargando un número de versión A del file desde el server remoto;
  • John Smith clona el mismo repository, descargando la misma versión de número A del file desde el server remoto;
  • John Smith codifica un poco y se compromete en él localmente;
  • Después, me comprometo en mi local;

¿Cómo entiende Git que nuestros files son descendientes directos de la versión número A? El Mercurial / Git / Bazaar / etc no tiene un número interno que identifique: ¿cómo entienden cuando un file modificado está en conflicto o no?

Los conflictos solo se detectan después de que usted y John Smith se comunican entre sí (usando hg push y hg pull ) y uno de ustedes quiere fusionar las dos líneas de trabajo (usando hg merge ).

Después de tirar el cambio de John Smith a su repository local, el gráfico del set de cambios podría verse así:

 ... [a] --- [b] \ `---------- [c] 

donde hizo el set de cambios b y John Smith hizo c , ambos basados ​​en el set de cambios a . Entre b , cambiaste el file helloworld.c y entre a y c John Smith cambió el mismo file. Mercurial ahora puede decir que podría haber un conflicto potencial aquí (una edición superpuesta) y le dirá cuando ejecute hg merge .

El sistema no se basa en numbers de versión asociados con los files, sino que se basa en el gráfico del set de cambios anterior. Concretamente, cuando fusionas b con c , Mercurial encontrará el ancestro común más grande, que es a . Luego observará el manifiesto (una list de los files (y su versión) presentes en un set de cambios determinado) en a , b , y notará que el file helloworld.c existía en tres versiones diferentes. Eso le dice a Mercurial que necesita hacer una fusión de tres vías con a versión básica, y c son las versiones local y de otro tipo. De forma pnetworkingeterminada, intenta hacer la fusión internamente, pero llamará a las herramientas de fusión externas (como KDiff3) si eso falla.

Si realmente quieres saber cómo funciona, recomiendo el Capítulo 4 del libro "Mercurial: The Definite Guide".

En resumen, Mercurial crea un identificador único para cada versión. Es único en todos los repositorys, basado en hash. Tanto usted como John Smith tendrán el mismo identificador para la versión A en sus repositorys. Sus cambios locales tendrán diferentes identificadores. Cuando uno de ustedes decide extraer y fusionar los cambios, Mercurial puede determinar que ambos hicieron cambios en la misma versión A. Ambos cambios se comparan con la versión base A. Es fácil verificar si los parches resultantes están en conflicto o no. .