====== Conflictos ====== Sección perteneciente al curso [[informatica:programacion:cursos:control_version_git_avanzado|Control de versiones con Git Avanzado]]. ===== Introducción ===== Uno de los grandes quebraderos de cabeza de los que se inician en Git son los conflictos. ===== Qué significan y cómo resolverlos ===== Un conflicto no es un error. Un conflicto aparece cuando hay dos versiones de código y Git no puede decidir cuál es la definitiva. Esto pasa por ejemplo cuando mezclamos dos ramas y en una hay un archivo que contiene un texto en una línea y en la otra existe el mismo archivo, pero con otro texto en esa línea. A veces los conflictos también son diferencias en el formato del archivo (tabulaciones, codificación de caracteres, saltos de línea...). También pueden aparecer conflictos en cualquier operación que implique fusión de código:**merge** (fusiona dos ramas), **rebase** (también fusiona ramas), **cherry-pick** (aplica un commit de otra rama en la rama en la que estamos), **pull** (trae código del repositorio remoto al local). **Regla de oro**: Siempre que aparezcan conflictos, primero lanzar ''git status''. Esto nos dará más información sobre lo que podemos hacer. Git espera a que resolvamos los conflictos y le demos la orden de cerrar la operación. Los conflictos se delimitan por marcas en los archivos: <<<<<<< HEAD // Código del commit o rama // a donde apunta el HEAD ======= // Código del commit o rama // que estoy intentando fusionar con HEAD >>>>>>> develop En la parte de arriba está el código actual y en la parte de abajo el código que viene de otro repositorio, commit o rama. Cuando Git nos enseña conflictos, lo primero que hay que hacer es buscar el separador (''%%=======%%'') para ver cuántos bloques de conflicto hay. Si queremos resolverlos a mano, editaremos el texto, borraremos las marcas y dejamos el código definitivo. Una vez resueltos los conflictos, se lo comunicamos a git: git add Para terminar la fusión en un ''merge'' o en un ''pull'': git commit Para terminar la fusión en un ''rebase'': git rebase --continue Para terminar la fusión en un ''cherry-pick'': git cherry-pick --continue Recordemos usar ''git status'' para obtener consejos sobre cómo terminar las operaciones de conflictos sin tener que sabérnoslo de memoria. ===== Herramientas para resolver conflictos ===== Si queremos usar una interfaz gráfica específica para resolver conflictos: git mergetool ''mergetool'' solo funcionará cuando haya conflictos ''git mergetool'' lo que hace es llamar a la herramienta gráfica que le hayamos indicado a través de la variable ''merge.tool''. Por ejemplo, para usar el programa [[https://kdiff3.sourceforge.net/|KDiff3]]: git config --global merge.tool kdiff3 git config --global mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe" Al usar una herramienta gráfica, git crea una copia del fichero origen del conflicto con las marcas de conflicto por si queremos revisar (añade la extensión ''.orig''). ===== Conclusión ===== Un conflicto no es un error. Es parte del flujo de trabajo habitual con git siempre que estemos fusionando código. Git hay cosas que no puede resolver él solo y requiere de intervención humana para decidir. Cuando hay conflicto, ''git status''. Antes de cerrar el conflicto, ''git status''. Es muy recomendable el uso de este comando por la ayuda que nos ofrece. ===== Recursos ===== * [[https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/|Artículo "Resolving a merge conflict using the command line"]] * [[https://es.atlassian.com/git/tutorials/using-branches/merge-conflicts|Artículo "Git merge conflicts"]]