26 Conflictos
Cuando comenzamos a trabajar con colaboradores, es usual que generemos conflictos si no se trabaja de forma adecuada.
Vamos a crear un conflicto para después resolverlo.
El colaborador va a modificar el notas.txt añadiendo algo. Luego lo añadirá al área de preparación, realizará el commit correspondiente y finalmente actualizará el repositorio remoto.
$ nano notas.txt
$ git add notas.txt
$ git commit -m "Modificamos el archivo notas para crear un conflicto"
$ git push origin mainAhora, el dueño del repositorio realizará un cambio también al archivo notas (sin antes actualizar con los últimos cambios del colaborador) y realizará todos los pasos hasta poder actualizar el repositorio remoto.
$ nano notas.txt
$ git add notas.txt
$ git commit -m "Cambios en el archivo notas por el dueño del repositorio"
$ git push origin mainGit no autorizo hacer el push porque había cambios en el remoto que no habíamos actualizado en el local, entonces vamos a actualizar el local primero, hacer un merge en la copia en la que estamos trabajando y después ya hacer un push.
$ git pull origin mainVamos a ver un mensaje de que hay un merge que no pudo resolver porque se trabajo en la misma línea en el mismo archivo. Si abrimos el archivo vamos a ver algo como lo siguiente:
texto aqui
<<<<<<< HEAD
cambios locales aqui
=======
cambios del colaborador aqui
>>>>>>> dabb4c8c450e8475aee9b14b4383acc99f42af1d
Ahora lo que tenemos que hacer es decidir que cambios queremos conservar, para eso, podemos borrar nuestros cambios, los del colaborador, ambos, o cambiar todo por algo nuevo (y borrar los identificadores de los conflictos).
Una vez finalizado el merge/resolver conflicto, ya podemos añadirlo al área de preparación, realizar el commit y enviarlo al remoto.
git add notas.txt
git status
git commit -m "Resolvimos el conflicto en el archivo notas"
git push origin mainCuando el colaborador intente hacer un git pull no verá ningún conflicto ya que git conservo el registro de que se resolvió y a la copia del colaborador se actualizará sin ningún problema.
git pull origin mainUna forma de evitar algunos conflictos es trabajando en ramas, o distribuyendo el trabajo y que cada quien trabaje sobre archivos diferentes.
También se puede dar el caso de que los conflictos sean por archivos con el mismo nombre pero con contenidos totalmente diferentes, por ejemplo con imágenes.
Vamos a crear de nuevo un conflicto con una imagen y vamos a tratar de resolverlo. Tanto el colaborador como el dueño del proyecto va a crear una imagen con el nombre imagen_prueba.jpg, guardará los cambios y realizará todo hasta mandarlo al repositorio remoto.
head -c 1024 /dev/urandom > imagen_prueba.jpg
ls -lh imagen_prueba.jpgLo añadimos al área de preparación, realizamos commit y lo enviamos al repositorio remoto.
git add imagen_prueba.jpg
git commit -m "Se creo imagen random para generar conflicto."El colaborador realizará un push de su imagen al repositorio remoto.
git push origin mainAhora el dueño del repositorio tratará de hacer un push también al repositorio.
git push origin mainLo primero que nos va a pasar y decir git, es que no actualizamos nuestro repositorio con los cambios como en el ejercicio anterior. Vamos a hacer un pull.
git pull origin mainNos va a marcar que hay conflictos y que no puede hacer auto merge y nos dirá adicionalmente un mensaje similar al siguiente:
warning: Cannot merge binary files: imagen_prueba.jpg (HEAD vs. 439dc8c08869c343538f6dc4a2b615b05b93c76e)
Esto se debe a que como es un archivo que no es de texto no puede empalmar los cambios. Entonces las opciones que tenemos es decidir quedarnos con solo una de las dos imágenes o renombrarlas para quedarnos con ambos.
- Quedarnos con la imagen del dueño del repo:
La imagen del dueño del repo es el HEAD y la del colaborador tiene un id de commit. Entonces procedemos a lo siguiente.
git checkout HEAD imagen_prueba.jpg
git add imagen_prueba.jpg
git commit -m "Usar la imagen del dueño del repo en lugar de la del colaborador"- Quedarnos con la imagen del colaborador del repo:
La imagen del colaborador tiene un id de commit, buscarlo. Entonces procedemos a lo siguiente.
git checkout 439dc8c0 imagen_prueba.jpg
git add imagen_prueba.jpg
git commit -m "Usar la imagen del colaborador del repo en lugar de la del dueño"- Quedarnos con ambas imágenes:
git checkout HEAD imagen_prueba.jpg
git mv imagen_prueba.jpg imagen_prueba-dueño.jpg
git checkout 439dc8c0 imagen_prueba.jpg
mv imagen_prueba.jpg imagen_prueba-colaborador.jpgY finalmente para remover la imagen de prueba y añadir las dos nuevas versiones:
git rm imagen_prueba.jpg
git add imagen_prueba-dueño.jpg
git add imagen_prueba-colaborador.jpg
git commit -m "Use two images: dueño y colaborador"
git push origin main