Recientemente aprendí que al fusionar dos ramas en git, si hay cambios en dos líneas adyacentes , git declara que esto es un conflicto. Por ejemplo, si el archivo test.txt
tiene este contenido:
Line 1: A
Line 2: B
Line 3: C
Line 4: D
y en rama master
cambiamos esto a
Line 1: A
Line 2: B1
Line 3: C
Line 4: D
mientras que en la rama testing
cambiamos esto a
Line 1: A
Line 2: B
Line 3: C1
Line 4: D
y luego tratar de fusionar testing
en master
, git declara un conflicto de combinación. Mi ingenua expectativa era que la fusión ocurriría sin conflicto y produciría esto:
Line 1: A
Line 2: B1
Line 3: C1
Line 4: D
Estoy seguro de que hay una buena razón por la cual git no se fusiona de esta manera. ¿Alguien puede explicar esta razón?
Respuestas:
Suponiendo que este fragmento de código
se ha cambiado en una rama en este
y en otra rama en este
entonces no quisiera que git lo fusionara en esto
sin alarmarme
Para evitar causar tales problemas, git generalmente se niega a combinar automáticamente los cambios que tocan las líneas cercanas. Le da la oportunidad de verificar si la lógica del programa se rompería o no.
Este ejemplo es trivial, pero cuando se fusionan grandes ramas, el riesgo de conflictos "lógicos" similares es mucho mayor. A veces incluso me encantaría que el contexto sea aún más grande de lo que es actualmente.
fuente
¿Es este comportamiento solo git?
Después de discutir con un colega, acabo de intentarlo y SVN lo maneja sin problemas: se modifican las 2 líneas.
Las capacidades de fusión de varios VCS se prueban aquí para bazar, darcs, git y mercurial : https://github.com/mndrix/merge-this
Parece que solo los darcs fusionan con éxito el caso de "líneas adyacentes".
Aplicar cambios adyacentes a los archivos no es un problema difícil. Realmente creo que este comportamiento ha sido elegido a propósito.
¿Por qué alguien decidiría que modificar líneas adyacentes produce un conflicto?
Creo que esto es para obligarlo a mirarlo .
Modif número 1, en master:
Modif número 2, fusionado de una rama:
Después de la fusión, no quieres eso:
Ver este comportamiento como una característica
Puede convertir el comportamiento de fusión de git en una ventaja. Cuando necesite mantener 2 líneas consistentes pero no pueda detectarlo (en el momento de la compilación, al comienzo de sus pruebas o de lo contrario), puede intentar unirlas.
Reescribe esto ...:
...a esto:
Entonces, cuando fusionas Modif 1 ...:
... con Modif 2 ...:
..., git producirá un conflicto y te obligará a mirarlo.
fuente
Supongo que en su mayoría, pero creo que tiene que ver con que la línea 2 se use como contexto para el cambio de la línea 3.
Git no puede decir simplemente que "La línea con C se convirtió en una línea con C1" porque podría haber otra línea con "C", por lo que dice "La línea con C, justo después del inicio del archivo, la línea con A, y la línea con B, ahora es C1 "
Si "la línea con B" ya no está allí, se pierde parte del contexto y git solo puede decir aproximadamente a dónde debe ir la nueva línea.
fuente
Las otras respuestas aquí son todas correctas, pero para mí esto siempre me pareció una limitación innecesaria.
Como han dicho otros, en estos casos definitivamente no querrás que Git combine las líneas sin previo aviso.
Pero aún quería la opción de hacerlo automáticamente, después de ser advertido. Así que escribí un controlador de fusión git personalizado que podría fusionar conflictos en líneas adyacentes (o individuales) de forma interactiva:
Me ahorra una gran cantidad de tiempo, ya que administro un proyecto donde las personas a menudo trabajan en los mismos archivos y refactorizan mucho código.
El script está disponible en GitHub bajo una licencia GPLv3 +. Tal vez lo encuentres útil:
https://github.com/paulaltin/git-subline-merge
fuente