C贸mo comprender y resolver conflictos en Git

Ah铆 est谩, la palabra que todo desarrollador odia ver: conflicto. ? Simplemente no hay forma de evitar el conflicto de fusi贸n ocasional cuando se trabaja con Git (u otros sistemas de control de versiones).

Pero cuando hablo con los desarrolladores, a menudo escucho que hay una sensaci贸n de ansiedad o incomodidad en torno al tema de los conflictos de fusi贸n.

Manejar los conflictos a menudo sigue siendo un lugar oscuro y misterioso: una situaci贸n en la que las cosas est谩n muy mal y no est谩 claro c贸mo salir de ella (sin empeorar las cosas).

Si bien es cierto que los conflictos de fusi贸n son una parte inevitable de la vida de un desarrollador, la incomodidad en estas situaciones es completamente opcional.

Mi intenci贸n con este art铆culo es aportar algo de claridad a este tema: c贸mo y cu谩ndo ocurren normalmente los conflictos, qu茅 son en realidad y c贸mo resolverlos, o deshacerlos.

Cuando comprenda adecuadamente estas cosas, podr谩 lidiar con los conflictos de fusi贸n de una manera mucho m谩s relajada y segura. ?

C贸mo y cu谩ndo ocurren los conflictos

El nombre ya lo dice: "conflictos de fusi贸n" pueden ocurrir en el proceso de integraci贸n de confirmaciones de una fuente diferente.

Sin embargo, tenga en cuenta que la "integraci贸n" no se limita 煤nicamente a "fusionar ramas". Tambi茅n puede suceder al reajustar o reajustar interactivamente, al realizar una selecci贸n o un tir贸n, o incluso al volver a aplicar un Stash.

Todas estas acciones realizan alg煤n tipo de integraci贸n, y es entonces cuando pueden ocurrir conflictos de fusi贸n.

Pero, por supuesto, estas acciones no resultan en un conflicto de fusi贸n cada vez (隆gracias a Dios!). Idealmente, deber铆a encontrarse en estas situaciones s贸lo en raras ocasiones. Pero, 驴cu谩ndo ocurren exactamente los conflictos?

En realidad, las capacidades de fusi贸n de Git son una de sus mayores ventajas: la fusi贸n de ramas funciona sin esfuerzo la mayor parte del tiempo, porque Git suele ser capaz de resolver las cosas por s铆 solo.

Pero hay situaciones en las que se realizaron cambios contradictorios y en las que la tecnolog铆a simplemente no puede decidir qu茅 est谩 bien o qu茅 est谩 mal. Estas situaciones simplemente requieren una decisi贸n de un ser humano.

El verdadero cl谩sico es cuando se cambi贸 exactamente la misma l铆nea de c贸digo en dos confirmaciones, en dos ramas diferentes. 隆Git no tiene forma de saber qu茅 cambio prefiere! ?

Existen otras situaciones similares, por ejemplo, cuando un archivo se modific贸 en una rama y se elimin贸 en otra, pero son un poco menos comunes.

La GUI de escritorio Git "Tower" , por ejemplo, tiene una forma agradable de visualizar este tipo de situaciones:

C贸mo saber cu谩ndo ha ocurrido un conflicto

No se preocupe: Git le dir谩 muy claramente cu谩ndo ha ocurrido un conflicto. ?  

Primero, le informar谩 inmediatamente de la situaci贸n , por ejemplo, cuando una fusi贸n o rebase falla debido a un conflicto:

$ git merge develop Auto-merging index.html CONFLICT (content): Merge conflict in index.html CONFLICT (modify/delete): error.html deleted in HEAD and modified in develop. Version develop of error.html left in tree. Automatic merge failed; fix conflicts and then commit the result.

Como puede ver en el ejemplo anterior, cuando intent茅 realizar una fusi贸n, cre茅 un conflicto de fusi贸n, y Git comunica el problema de manera muy clara y r谩pida:

  • Se produjo un conflicto en el archivo "index.html".
  • Ocurri贸 otro conflicto en el archivo "error.html".
  • Y finalmente, debido a los conflictos, la operaci贸n de fusi贸n fall贸.

Estas son las situaciones en las que tenemos que profundizar en el c贸digo y ver qu茅 se debe hacer.

En el caso poco probable de que haya pasado por alto estos mensajes de advertencia cuando ocurri贸 el conflicto, Git tambi茅n le informa cada vez que ejecuta git status:

$ git status On branch main You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add/rm ..." as appropriate to mark resolution) deleted by us: error.html both modified: index.html

En otras palabras: no se preocupe por no notar conflictos de fusi贸n. Git se asegura de que no puedas pasarlos por alto.

C贸mo deshacer un conflicto en Git y empezar de nuevo

Los conflictos de fusi贸n vienen con cierto aire de urgencia. Y con raz贸n: tendr谩s que lidiar con ellos antes de poder continuar con tu trabajo.

Pero aunque ignorarlos no es una opci贸n, "lidiar con los conflictos de fusi贸n" no significa necesariamente que deba resolverlos. 隆Deshacerlos tambi茅n es posible!

Vale la pena repetir esto: siempre tiene la opci贸n de deshacer un conflicto de fusi贸n y volver al estado anterior. Esto es cierto incluso cuando ya ha comenzado a resolver los archivos en conflicto y se encuentra en un callej贸n sin salida.

En estas situaciones, es bueno tener en cuenta que siempre puede comenzar de nuevo y volver a un estado limpio antes de que ocurriera el conflicto.

Para este prop贸sito, la mayor铆a de los comandos vienen con una --abortopci贸n, por ejemplo git merge --aborty git rebase --abort:

$ git merge --abort $ git status On branch main nothing to commit, working tree clean

Esto deber铆a darte la confianza de que realmente no puedes equivocarte. Siempre puede abortar, volver a un estado limpio y empezar de nuevo.

C贸mo se ven realmente los conflictos en Git

Ahora, sabiendo que nada se puede romper, veamos c贸mo se ve realmente un conflicto bajo el cap贸. Esto desmitificar谩 a esos peque帽os cabrones y, al mismo tiempo, te ayudar谩 a perder el respeto por ellos y a ganar confianza en ti mismo.

Como ejemplo, veamos el contenido del archivo "index.html" (actualmente en conflicto) en un editor:

Git was kind enough to mark the problem area in the file, enclosing it in <<<<<<< HEAD and >>>>>>> [other/branch/name]. The content that comes after the first marker originates from our current working branch. Finally, a line with ======= characters separates the two conflicting changes.

How to Solve a Conflict in Git

Our job as developers now is to clean up these lines: after we're finished, the file has to look exactly as we want it to look.

It might be necessary to talk to the teammate who wrote the "other" changes and decide which code is actually correct. Maybe it's ours, maybe it's theirs - or maybe a mixture between the two.

This process - cleaning up the file and making sure it contains what we actually want - doesn't have to involve any magic. You can do this simply by opening your text editor or IDE and starting to making your changes.

Often, however, you'll find that this is not the most efficient way. That's when dedicated tools can save time and effort:

  • Git GUI Tools: Some of the graphical user interfaces for Git can be helpful when solving conflicts. The Tower Git GUI, for example, offers a dedicated "Conflict Wizard" that helps visualize and solve the situation:
  • Dedicated Merge Tools: For more complicated conflicts, it can be great to have a dedicated "Diff & Merge Tool" at hand. You can configure your tool of choice using the "git config" command. (Consult your tool's documentation for detailed instructions.) Then, in case of a conflict, you can invoke it by simply typing git mergetool. As an example, here's a screenshot of "Kaleidoscope" on macOS:

After cleaning up the file - either manually or in a Git GUI or Merge Tool - we have to commit this like any other change:

  • By using git add on the (previously) conflicted file, we inform Git that the conflict has been solved.
  • When all conflicts have been solved and added to the Staging Area, you need to complete the resolution by creating a regular commit.

How to Become More Confident and Productive

Many years ago, when I started using version control, merge conflicts regularly freaked me out: I was afraid that, finally, I had managed to break things for good. ?

Only when I took the time to truly understand what was going on under the hood was I able to deal with conflicts confidently and efficiently.

The same was true, for example, when dealing with mistakes: only once I learned how to undo mistakes with Git was I able to become more confident and productive in my work.

I highly recommend taking a look at the free "First Aid Kit for Git", a collection of short videos about how to undo and recover from mistakes with Git.

Have fun becoming a better programmer!

About the Author

Tobias G眉nther is the CEO of Tower, the popular Git desktop client that helps more than 100,000 developers around the world to be more productive with Git.