tag - ¿Qué constituye un conflicto de fusión en Git?
resolver conflictos git (3)
¿Cómo determina git que una fusión en particular tiene un conflicto y cuál es el conflicto?
Mi suposición sería algo como esto: si los dos se fusionan tienen un padre común comprometido, y si ambos han cambiado la línea X de lo que tenía el padre, eso es un conflicto.
Lo que complica mi comprensión es:
- "Cambiar la línea X" puede significar reemplazarlo con varias líneas nuevas, y eso todavía se muestra como un conflicto (la versión A tiene esta línea, y la versión B tiene estas 5 líneas, o lo que sea)
- Si insertas líneas en una de las confirmaciones, un algoritmo más tonto pensaría que todas las líneas siguientes han cambiado: la línea 30 ahora tiene los contenidos anteriores de la línea 25, 31 tiene el contenido anterior de 26, etc. Pero git puede decir que esos son lo mismo, y no sé cómo.
¿Alguien puede explicar cómo funciona esto, o señalarme un enlace que sí lo hace?
Básicamente, con git , cada fusión es un conflicto, que te deja con un índice que contiene tres versiones de cada archivo, las versiones de cada rama y la base. En este índice, se ejecutan varios resolvedores, que pueden decidir para cada archivo individual cómo resolver el problema.
La primera etapa es una resolución trivial, que se ocupa de cosas como archivos sin cambios, casos donde una rama ha modificado un archivo mientras que la otra no, o donde ambas ramas contienen la misma versión nueva del archivo.
Luego, son complementos que miran los casos restantes. Hay un complemento que maneja archivos de texto identificando cambios individuales (como diff) en una rama e intentando aplicarlos a la otra rama, volviendo a colocar marcadores de conflicto si eso no funciona. Puede enganchar fácilmente su propia herramienta de combinación en este punto, por ejemplo, puede escribir una herramienta que sepa cómo combinar archivos XML sin violar la buena formación, o que proporcione una interfaz gráfica de usuario que permita la edición interactiva y un lado a otro. vista lateral (por ejemplo, kdiff3 hace eso).
Entonces la presentación de conflictos es realmente una cuestión del plugin usado; el complemento predeterminado para los archivos de texto usará el mismo estilo que CVS, porque las personas y las herramientas están acostumbradas a él, y los marcadores de conflicto son un error de sintaxis conocido en casi cualquier lenguaje de programación.
No creo que el algoritmo de fusión tenga algo especial con Git: es un algoritmo de combinación de 3 vías clásico ( no el de Codeville ), que se puede usar con varias estrategias (por defecto: recurse, o resolve o pulpo). El resultado es un proceso de fusión bastante simple que se describe aquí .
Cualquier necesidad de visualización se delega luego en herramientas de fusión / diferencia de terceros.
Vaya al párrafo HOW CONFLICTS ARE PRESENTED
en esta page .
LE: No hay documentación real para los casos de conflicto ni para los marcadores de conflicto de archivos, y dado que estoy siendo golpeado en los comentarios aquí, aquí están los indicadores en el código fuente que conducen a estrategias cercanas a git para lograr un estado de conflicto . File merge-recursive.c , busque la "CONFLICT
cadena de "CONFLICT
. Al hacerlo, podemos descubrir fácilmente que en realidad hay un puñado de casos conflictivos como:
- CONFLICTO (renombrar / renombrar)
- CONFLICTO (contenido)
- CONFLICTO (renombrar / directorio)
- CONFLICTO (cambiar el nombre / eliminar)
- CONFLICTO (cambiar el nombre / agregar)
- CONFLICTO (eliminar / modificar)
- ... y así sucesivamente
Si me preguntas, sí, deberían estar documentados y claramente señalados, pero no es así, no hay nada que hacer, entonces inspecciona la fuente ... pero alguien realmente puede retomar de aquí y crear una buena documentación y luego enviarla al proyecto git.
@Wim Coenen sí, también depende de las estrategias de fusión, pero cómo se presentan los conflictos da mucho más de una idea. Luego puedes leer las estrategias de fusión también si me preguntas, pero sigues teniendo dudas.