Fusionar ramas y resolver conflictos


Tu rama de funcionalidad está terminada. El interruptor funciona, ya confirmaste los cambios y ahora quieres que ese trabajo esté en main, donde vive el código del resto del equipo. La mayoría de las veces traerlo de vuelta es rápido y silencioso: Git compara las dos ramas, no encuentra nada que se superponga y combina el trabajo sin pasos adicionales. Pero a veces tú y un compañero de equipo cambiaron exactamente las mismas líneas en ramas distintas, y Git no puede adivinar cuál versión quieres conservar. Esa situación aparece en casi todo proyecto con más de una persona haciendo commits. Es una parte normal y cotidiana de trabajar con ramas, y significa que Git encontró dos ideas distintas sobre las mismas líneas y necesita que tú decidas cuál prevalece.
Traer una rama de vuelta con git merge
Supongamos que construiste el interruptor de Fahrenheit en su propia rama, add-fahrenheit-toggle, y main no se ha movido desde que te ramificaste de ella. Cambia a main y ejecuta git merge con el nombre de la rama que quieres traer:
$ git switch main
$ git merge add-fahrenheit-toggle
Updating 4f2a891..8c3d1a0
Fast-forward
src/index.js | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)git merge <rama> siempre fusiona la rama indicada dentro de la rama en la que te encuentres parado, por lo que cambiar primero a main es importante. La rama en la que estés parado es la que recibe la fusión. Después de ejecutar esto, main tiene todos los commits de add-fahrenheit-toggle. La rama de funcionalidad en sí no se toca: puedes seguir trabajando en ella o borrarla ahora que su trabajo también vive en main.
git merge nombre-de-rama trae los commits de esa rama hacia la rama en la que estés parado en ese momento, así que primero cambia a main. La mayoría de las fusiones ocurren en silencio y tú sigues con tu día. Nada cambia en la rama de funcionalidad en sí; puedes seguir usándola o borrarla una vez que main ya tenga el trabajo. Cómo se ve un conflicto de fusión
Un conflicto ocurre cuando las mismas líneas cambian en ambos lados de una fusión, y Git no tiene forma de saber qué versión quieres. Supongamos que un compañero de equipo fusionó en main un indicador de carga que modificó una función en src/index.js, y tu rama add-fahrenheit-toggle modificó esa misma función para agregar el interruptor. Ahora la fusión se detiene a la mitad en vez de terminar:
$ git switch main
$ git merge add-fahrenheit-toggle
Auto-merging src/index.js
CONFLICT (content): Merge conflict in src/index.js
Automatic merge failed; fix conflicts and then commit the result.Eso es un conflicto de fusión. Abre el archivo y verás que Git marcó exactamente dónde las dos versiones no coinciden:
<<<<<<< HEAD
showLoadingSpinner(true);
=======
const tempF = celsiusToFahrenheit(tempC);
>>>>>>> add-fahrenheit-toggle<<<<<<< HEAD marca el inicio de lo que está actualmente en tu rama (main, en este caso). ======= divide las dos versiones. >>>>>>> add-fahrenheit-toggle marca el final de la versión de la rama entrante. Todo lo que está entre los marcadores son las mismas pocas líneas, escritas de dos formas distintas.
Un conflicto significa que Git necesita tu criterio; nada está roto. Git encontró dos cambios sobre las mismas líneas y no tiene forma de adivinar cuál quieres, así que se detiene y te pide que decidas. Edita el archivo hasta que quede como lo quieres, conservando una versión, ambas, o algo nuevo que las combine, y luego borra las líneas de los marcadores:
showLoadingSpinner(true);
const tempF = celsiusToFahrenheit(tempC);Cuando el archivo se vea bien, agrégalo y confírmalo exactamente como cualquier otro cambio:
$ git add src/index.js
$ git commitEjecutar git commit sin ningún mensaje aquí abre tu editor con un mensaje que Git ya preparó, describiendo la fusión. Guarda y cierra, y la fusión queda completa.
<<<<<<<, =======, y >>>>>>>, edita hasta que quede como quieres y luego borra esas líneas de marcadores. Termina con git add y git commit. Mi primer conflicto se sintió como una emergencia; resultó ser Git haciéndome una pregunta bastante común. Uniendo todo de nuevo
Fusionar es lo que hace que ramificar valga la pena: experimentas de forma segura en tu propia línea de historia, tema que se cubre en Ramas, y luego incorporas ese trabajo de vuelta a main una vez que está listo, conflictos incluidos. En GitHub, la misma operación normalmente ocurre a través de un pull request en lugar de un git merge local en tu máquina; el capítulo de flujo de pull requests cubre cómo proponer, revisar y fusionar un cambio en un proyecto compartido. Si alguna vez una fusión termina en un lugar que no querías después de haberla confirmado, deshacer cosas explica cómo retroceder con seguridad.

