====== Git: Exemple de conflicte ======
Els conflictes de versions es donen quan dos desenvolupadors han modificat la mateixa línia (o línies) de codi. Forçarem un senzill exemple de conflicte que Git detectarà, simulant el treball de dos //developers// en branques diferents. Partirem d'un simple arxiu ''circ.py'' del qual derivarem 2 branques i, finalment, les fusionarem, trobant el conflicte.
{{vcs-merge.png?500}}
{{tag> #Daw #DawMp08 #DawMp08Uf4 #DawMp08Uf04 #DawMp05 #DawMp05Uf2 #DawMp05Uf02 #Dam #DamMp05 #DamMp05Uf2 #DamMp05Uf02 #Ciber #CiberMp03 #Ceti #CetiMp03 git cvs vcs versions subversion svn DevOps }}
En aquest exemple es fa tot a la mateixa màquina i carpeta per forçar un conflicte. La situació "real" seria que dos desenvolupadors estarien en màquines diferents i el conflicte arribaria quan incorporessin els canvis de l'altre mitjançant un //fetch//.
===== Codi =====
Dos desenvolupadors volen treballar amb el següent codi i parteixen d'aquesta primera versió. Tots dos tindran la mateixa pensada, millorar la precisió del valor ''PI'', però un hi afegirà 4 decimals i l'altre 5, resultant en un conflicte de codi.
#!/usr/bin/env python3
radi = input("Radi de la circumferència? ")
PI = 3.14
perimetre = 2*PI*float(radi)
print("El perímetre de la circumferència de radi {} és {}".format(radi,perimetre))
\\
===== Branques =====
Històricament, al crear un repositori Git es crea una branca per defecte anomenada "master". Temps després s'ha estimat que la referència "master/slave" que se'n dedueix no era adequada ja que recorda el passat esclavista i uns valors dels quals es vol passar pàgina. Per això en la majoria de tutorials de Git sempre es sol canviar el nom de la branca principal a "main".
Per tal de treballar en paral·lel, els dos desenvolupadors crearan 2 branques iguals a partir d'aquest codi (a part de la //main//). Amb les següents instruccions es crearan 2 branques iguals a partir d'aquest codi:
$ git init
$ git branch -M main # la branca principal l'anomenem main en lloc de master
$ git add . # s'afegeixen tots els arxius i carpetes del directori actual (./)
$ git commit -am "primer commit"
$ git branch dev_a # simulem developer a
$ git branch dev_b # simulem developer b
El primer //developer// treballa a la branca //dev_a//:
$ git checkout dev_a
I aplica canvis per fer el valor de ''PI'' mes exacte ''PI = 3.1416'' a l'arxiu ''circ.py''.
$ git commit -am "millora de PI"
En canvi, l'altre desenvolupador treballa a la branca //dev_b//:
$ git checkout dev_b
En extreure la branca //dev_b// amb //checkout// es pot observar que l'arxiu és l'original i ''PI'' torna al valor inicial. Canvia ''PI'' per ''PI = 3.14159'' (5 decimals de precisió).
$ git commit -am "PI mes exacte"
Per fer el **//merge//** (integració de les dues branques) cal situar-se a la branca destí (en aquest cas //main//) amb la instrucció //checkout// i incorporar les branques (primer //dev_a// i després //dev_b//):
Git funciona per línies. Les insercions i eliminacions detectades fan referència al nombre de línies trobades amb canvis. 1 inserció (+) i 1 eliminació (-) és el que detecta quan modifiquem una sola línia.
$ git checkout main
$ git merge dev_a
1 file changed, 1 insertion(+), 1 deletion(-)
\\
===== Conflicte =====
La fusió de la branca //dev_a// sobre //main// no ha donat errors. Procedim amb la fusió de la segona branca:
$ git merge dev_b
S'està autofusionant circ.py
CONFLICTE (contingut): Conflicte de fusió en circ.py
La fusió automàtica ha fallat; arregleu els conflictes i després cometeu el resultat.
A l'arxiu de codi, Git ha introduït cert text (''<<<<'' ''===='' ''>>>>'') per **ressaltar el conflicte detectat**, ja que els dos //developers// han tocat la mateixa línia:
#!/usr/bin/env python3
radi = input("Radi de la circumferència? ")
<<<<<<< HEAD
PI = 3.1416
=======
PI = 3.14159
>>>>>>> dev_b
perimetre = 2*PI*float(radi)
print("El perímetre de la circumferència de radi {} és {}".format(radi,perimetre))
\\
===== Resolució =====
El darrer desenvolupador es trobarà el conflicte en fer el merge de l'altra branca, i haurà de decidir si posa un valor o un altre, eliminar les línies que ressalten el conflicte i tornar a fer un //commit// amb la correcció sobre la branca //main//. En aquest cas, **el darrer desenvolupador opta per emprar el valor de PI amb més decimals de precisió**:
#!/usr/bin/env python3
radi = input("Radi de la circumferència? ")
PI = 3.14159
perimetre = 2*PI*float(radi)
print("El perímetre de la circumferència de radi {} és {}".format(radi,perimetre))
I guardar el codi resultant amb un //commit// que tancarà la fusió que teníem pendent de resoldre:
$ git commit -am "arranjament PI més precís"