Skip to content

Latest commit

 

History

History
681 lines (518 loc) · 26.8 KB

File metadata and controls

681 lines (518 loc) · 26.8 KB

Fusió Avançada

La fusió a Git és típicament força fàcil. Com que Git facilita fusionar una altra branca múltiples vegades, significa que podeu tenir una branca de molt llarga durada però podeu mantenir-la actualitzada a mesura que avanceu, resolent petits conflictes sovint, en lloc de sorprendre’s amb un enorme conflicte al final de la sèrie.

No obstant això, de vegades es produeixen conflictes complicats. A diferència d’alguns altres sistemes de control de versions, Git no intenta ser massa intel·ligent sobre la resolució de conflictes de fusió. La filosofia de Git és ser intel·ligent a l’hora de determinar quan una resolució de fusió és inequívoca, però si hi ha un conflicte, no intenta ser intel·ligent sobre la resolució automàtica. Per tant, si espereu massa temps per fusionar dues branques que divergeixen ràpidament, podeu trobar alguns problemes.

En aquesta secció, tractarem quins poden ser alguns d’aquests problemes i quines eines us proporciona Git per ajudar a gestionar aquestes situacions més complicades. També tractarem alguns dels diferents tipus de fusions no estàndards que podeu fer, així com veure com desfer fusions que heu realitzat.

Conflictes de Fusió

Tot i que vam tractar alguns conceptes bàsics sobre la resolució de conflictes de fusió a ch03-git-branching.asc, per a conflictes més complexos, Git proporciona algunes eines per ajudar-vos a entendre què està passant i com gestionar millor el conflicte.

En primer lloc, si és possible, intenteu assegurar-vos que el vostre directori de treball estigui net abans de fer una fusió que pugui tenir conflictes. Si teniu treball en procés, o bé confieu-lo en una branca temporal o deseu-lo. Això us permetrà desfer qualsevol cosa que intenteu aquí. Si teniu canvis no desats al vostre directori de treball quan intenteu una fusió, alguns d’aquests consells us poden ajudar a preservar aquest treball.

Passem per un exemple molt simple. Tenim un fitxer Ruby molt simple que imprimeix 'hola món'.

#! /usr/bin/env ruby

def hello
  puts 'hola món'
end

hello()

Al nostre repositori, creem una nova branca anomenada whitespace i procedim a canviar tots els finals de línia Unix a finals de línia DOS, canviant essencialment cada línia del fitxer, però només amb espais en blanc. Llavors canviem la línia “hola món” a “hola mundo”.

$ git checkout -b whitespace
Switched to a new branch 'whitespace'

$ unix2dos hello.rb
unix2dos: converting file hello.rb to DOS format ...
$ git commit -am 'Convertir hello.rb a DOS'
[whitespace 3270f76] Convertir hello.rb a DOS
 1 file changed, 7 insertions(+), 7 deletions(-)

$ vim hello.rb
$ git diff -b
diff --git a/hello.rb b/hello.rb
index ac51efd..e85207e 100755
--- a/hello.rb
+++ b/hello.rb
@@ -1,7 +1,7 @@
 #! /usr/bin/env ruby

 def hello
-  puts 'hola món'
+  puts 'hola mundo'^M
 end

 hello()

$ git commit -am 'Utilitzar espanyol en lloc d'anglès'
[whitespace 6d338d2] Utilitzar espanyol en lloc d'anglès
 1 file changed, 1 insertion(+), 1 deletion(-)

Ara tornem a la nostra branca master i afegim alguna documentació per a la funció.

$ git checkout master
Switched to branch 'master'

$ vim hello.rb
$ git diff
diff --git a/hello.rb b/hello.rb
index ac51efd..36c06c8 100755
--- a/hello.rb
+++ b/hello.rb
@@ -1,5 +1,6 @@
 #! /usr/bin/env ruby

+# imprimeix un missatge de salutació
 def hello
   puts 'hola món'
 end

$ git commit -am 'Afegir comentari documentant la funció'
[master bec6336] Afegir comentari documentant la funció
 1 file changed, 1 insertion(+)

Ara intentem fusionar la nostra branca whitespace i obtindrem conflictes a causa dels canvis d’espais en blanc.

$ git merge whitespace
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Automatic merge failed; fix conflicts and then commit the result.
Avortar una Fusió

Ara tenim algunes opcions. En primer lloc, tractem com sortir d’aquesta situació. Si potser no esperàveu conflictes i no voleu gestionar la situació encara, simplement podeu sortir de la fusió amb git merge --abort.

$ git status -sb
## master
UU hello.rb

$ git merge --abort

$ git status -sb
## master

L’opció git merge --abort intenta revertir a l’estat anterior a executar la fusió. Els únics casos en què potser no pugui fer això perfectament serien si teníeu canvis no desats al vostre directori de treball quan el vau executar, en cas contrari hauria de funcionar bé.

Si per alguna raó simplement voleu començar de nou, també podeu executar git reset --hard HEAD, i el vostre repositori tornarà a l’últim estat confirmat. Recordeu que qualsevol treball no confirmat es perdrà, així que assegureu-vos que no voleu cap dels vostres canvis.

Ignorar Espais en Blanc

En aquest cas específic, els conflictes estan relacionats amb espais en blanc. Ho sabem perquè el cas és simple, però també és força fàcil de veure en casos reals quan es mira el conflicte perquè cada línia es elimina en un costat i s’afegeix de nou a l’altre. Per defecte, Git veu totes aquestes línies com a canviades, així que no pot fusionar els fitxers.

No obstant això, l’estratègia de fusió per defecte pot acceptar arguments, i alguns d’ells són sobre ignorar correctament els canvis d’espais en blanc. Si veieu que teniu molts problemes d’espais en blanc en una fusió, simplement podeu avortar-la i fer-la de nou, aquesta vegada amb -Xignore-all-space o -Xignore-space-change. La primera opció ignora completament els espais en blanc en comparar línies, la segona tracta seqüències d’un o més caràcters d’espai en blanc com a equivalents.

$ git merge -Xignore-space-change whitespace
Auto-merging hello.rb
Merge made by the 'recursive' strategy.
 hello.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Com que en aquest cas, els canvis reals de fitxers no estaven en conflicte, un cop ignorem els canvis d’espais en blanc, tot es fusiona perfectament.

Això és un salvavides si teniu algú al vostre equip que de vegades li agrada reformatejar tot de espais a tabuladors o viceversa.

Re-fusió Manual de Fitxers

Tot i que Git gestiona el preprocessament d’espais en blanc força bé, hi ha altres tipus de canvis que potser Git no pot gestionar automàticament, però són solucions que es poden scriptar. Com a exemple, suposem que Git no pogués gestionar el canvi d’espais en blanc i necessitéssim fer-ho a mà.

El que realment necessitem fer és executar el fitxer que intentem fusionar a través d’un programa dos2unix abans d’intentar la fusió real del fitxer. Com ho faríem?

En primer lloc, entrem a l’estat de conflicte de fusió. Llavors volem obtenir còpies de la nostra versió del fitxer, la seva versió (de la branca que estem fusionant) i la versió comuna (d’on ambdues branques es van bifurcar). Llavors volem corregir qualsevol dels dos costats i tornar a intentar la fusió només per a aquest únic fitxer.

Obtenir les tres versions del fitxer és en realitat força fàcil. Git emmagatzema totes aquestes versions a l’índex sota “stages” que tenen números associats. L’etapa 1 és l’ancestre comú, l’etapa 2 és la vostra versió i l’etapa 3 és de MERGE_HEAD, la versió que esteu fusionant (“theirs”).

Podeu extreure una còpia de cadascuna d’aquestes versions del fitxer en conflicte amb la comanda git show i una sintaxi especial.

$ git show :1:hello.rb > hello.common.rb
$ git show :2:hello.rb > hello.ours.rb
$ git show :3:hello.rb > hello.theirs.rb

Si voleu ser una mica més durs, també podeu utilitzar la comanda ls-files -u per obtenir els SHA-1s reals dels blobs de Git per a cadascun d’aquests fitxers.

$ git ls-files -u
100755 ac51efdc3df4f4fd328d1a02ad05331d8e2c9111 1	hello.rb
100755 36c06c8752c78d2aff89571132f3bf7841a7b5c3 2	hello.rb
100755 e85207e04dfdd5eb0a1e9febbc67fd837c44a1cd 3	hello.rb

El :1:hello.rb és simplement una abreviatura per buscar aquest blob SHA-1.

Ara que tenim el contingut de les tres etapes al nostre directori de treball, podem corregir manualment la seva versió per solucionar el problema d’espais en blanc i tornar a fusionar el fitxer amb la poc coneguda comanda git merge-file que fa exactament això.

$ dos2unix hello.theirs.rb
dos2unix: converting file hello.theirs.rb to Unix format ...

$ git merge-file -p \
    hello.ours.rb hello.common.rb hello.theirs.rb > hello.rb

$ git diff -b
diff --cc hello.rb
index 36c06c8,e85207e..0000000
--- a/hello.rb
+++ b/hello.rb
@@@ -1,8 -1,7 +1,8 @@@
  #! /usr/bin/env ruby

 +# imprimeix un missatge de salutació
  def hello
-   puts 'hola món'
+   puts 'hola mundo'
  end

  hello()

En aquest punt hem fusionat bé el fitxer. De fet, això funciona millor que l’opció ignore-space-change perquè això realment corrigeix els canvis d’espais en blanc abans de la fusió en lloc de simplement ignorar-los. A la fusió ignore-space-change, realment vam acabar amb algunes línies amb finals de línia DOS, fent que les coses estiguessin barrejades.

Si voleu fer-vos una idea abans de finalitzar aquest commit sobre què va canviar realment entre un costat o l’altre, podeu demanar a git diff que compareu el que hi ha al vostre directori de treball que esteu a punt de confirmar com a resultat de la fusió amb qualsevol d’aquestes etapes. Passem per totes elles.

Per comparar el vostre resultat amb el que teníeu a la vostra branca abans de la fusió, en altres paraules, per veure què ha introduït la fusió, podeu executar git diff --ours:

$ git diff --ours
* Unmerged path hello.rb
diff --git a/hello.rb b/hello.rb
index 36c06c8..44d0a25 100755
--- a/hello.rb
+++ b/hello.rb
@@ -2,7 +2,7 @@

 # imprimeix un missatge de salutació
 def hello
-  puts 'hola món'
+  puts 'hola mundo'
 end

 hello()

Aquí podem veure fàcilment què va passar a la nostra branca, què estem introduint realment a aquest fitxer amb aquesta fusió, que és canviar aquesta única línia.

Si volem veure com el resultat de la fusió difereix del que hi havia al seu costat, podeu executar git diff --theirs. En aquest i l’exemple següent, hem d’utilitzar -b per eliminar els espais en blanc perquè estem comparant amb el que hi ha a Git, no el nostre fitxer hello.theirs.rb netejat.

$ git diff --theirs -b
* Unmerged path hello.rb
diff --git a/hello.rb b/hello.rb
index e85207e..44d0a25 100755
--- a/hello.rb
+++ b/hello.rb
@@ -1,5 +1,6 @@
 #! /usr/bin/env ruby

+# imprimeix un missatge de salutació
 def hello
   puts 'hola mundo'
 end

Finalment, podeu veure com el fitxer ha canviat des de tots dos costats amb git diff --base.

$ git diff --base -b
* Unmerged path hello.rb
diff --git a/hello.rb b/hello.rb
index ac51efd..44d0a25 100755
--- a/hello.rb
+++ b/hello.rb
@@ -1,7 +1,8 @@
 #! /usr/bin/env ruby

+# imprimeix un missatge de salutació
 def hello
-  puts 'hola món'
+  puts 'hola mundo'
 end

 hello()

En aquest punt podem utilitzar la comanda git clean per netejar els fitxers addicionals que vam crear per fer la fusió manual però que ja no necessitem.

$ git clean -f
Removing hello.common.rb
Removing hello.ours.rb
Removing hello.theirs.rb
Comprovar Conflictes

Potser no estem contents amb la resolució en aquest punt per alguna raó, o potser editar manualment un o tots dos costats encara no ha funcionat bé i necessitem més context.

Canviem una mica l’exemple. Per a aquest exemple, tenim dues branques de més llarga durada que cadascuna té alguns commits però creen un conflicte de contingut legítim quan es fusionen.

$ git log --graph --oneline --decorate --all
* f1270f7 (HEAD, master) Actualitzar README
* 9af9d3b Crear README
* 694971d Actualitzar frase a 'hola món'
| * e3eb223 (mundo) Afegir més proves
| * 7cff591 Crear script inicial de proves
| * c3ffff1 Canviar text a 'hola mundo'
|/
* b7dcc89 Codi inicial hola món

Ara tenim tres commits únics que viuen només a la branca master i tres altres que viuen a la branca mundo. Si intentem fusionar la branca mundo, obtenim un conflicte.

$ git merge mundo
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Automatic merge failed; fix conflicts and then commit the result.

Ens agradaria veure quin és el conflicte de fusió. Si obrim el fitxer, veurem alguna cosa com això:

#! /usr/bin/env ruby

def hello
<<<<<<< HEAD
  puts 'hola món'
=======
  puts 'hola mundo'
>>>>>>> mundo
end

hello()

Tots dos costats de la fusió van afegir contingut a aquest fitxer, però alguns dels commits van modificar el fitxer al mateix lloc que va causar aquest conflicte.

Explorem algunes eines que ara teniu a la vostra disposició per determinar com es va produir aquest conflicte. Potser no és òbvi com heu de corregir aquest conflicte. Necessiteu més context.

Una eina útil és git checkout amb l’opció --conflict. Això tornarà a comprovar el fitxer i reemplaçarà els marcadors de conflicte de fusió. Això pot ser útil si voleu restablir els marcadors i intentar resoldre’ls de nou.

Podeu passar --conflict amb diff3 o merge (que és el valor per defecte). Si li passeu diff3, Git utilitzarà una versió lleugerament diferent dels marcadors de conflicte, no només us donarà les versions “ours” i “theirs”, sinó també la versió “base” en línia per donar-vos més context.

$ git checkout --conflict=diff3 hello.rb

Un cop executem això, el fitxer semblarà així:

#! /usr/bin/env ruby

def hello
<<<<<<< ours
  puts 'hola món'
||||||| base
  puts 'hola món'
=======
  puts 'hola mundo'
>>>>>>> theirs
end

hello()

Si us agrada aquest format, podeu establir-lo com a valor per defecte per a futurs conflictes de fusió establint la configuració merge.conflictstyle a diff3.

$ git config --global merge.conflictstyle diff3

La comanda git checkout també pot acceptar les opcions --ours i --theirs, que poden ser una manera molt ràpida de simplement triar un costat o l’altre sense fusionar res en absolut.

Això pot ser especialment útil per a conflictes de fitxers binaris on simplement podeu triar un costat, o on només voleu fusionar certs fitxers des d’una altra branca: podeu fer la fusió i després comprovar certs fitxers d’un costat o l’altre abans de confirmar.

Registre de Fusió

Una altra eina útil en resoldre conflictes de fusió és git log. Això us pot ajudar a obtenir context sobre què podria haver contribuït als conflictes. Revisar una mica d’historial per recordar per què dues línies de desenvolupament estaven tocant la mateixa àrea de codi pot ser realment útil de vegades.

Per obtenir una llista completa de tots els commits únics que es van incloure en qualsevol de les branques involucrades en aquesta fusió, podem utilitzar la sintaxi de “triple punt” que vam aprendre a ch07-git-tools.asc.

$ git log --oneline --left-right HEAD...MERGE_HEAD
< f1270f7 Actualitzar README
< 9af9d3b Crear README
< 694971d Actualitzar frase a 'hola món'
> e3eb223 Afegir més proves
> 7cff591 Crear script inicial de proves
> c3ffff1 Canviar text a 'hola mundo'

Això és una bona llista dels sis commits totals involucrats, així com a quina línia de desenvolupament pertany cada commit.

No obstant això, podem simplificar això encara més per donar-nos un context molt més específic. Si afegim l’opció --merge a git log, només mostrarà els commits en qualsevol costat de la fusió que toquen un fitxer que està actualment en conflicte.

$ git log --oneline --left-right --merge
< 694971d Actualitzar frase a 'hola món'
> c3ffff1 Canviar text a 'hola mundo'

Si executeu això amb l’opció -p en lloc d’això, obteniu només els difs al fitxer que va acabar en conflicte. Això pot ser realment útil per donar-vos ràpidament el context que necessiteu per ajudar a entendre per què alguna cosa està en conflicte i com resoldre-ho de manera més intel·ligent.

Format de Diff Combinat

Com que Git prepara qualsevol resultat de fusió que tingui èxit, quan executeu git diff mentre esteu en un estat de fusió en conflicte, només obteniu el que actualment encara està en conflicte. Això pot ser útil per veure què encara heu de resoldre.

Quan executeu git diff directament després d’un conflicte de fusió, us donarà informació en un format de sortida de diff força únic.

$ git diff
diff --cc hello.rb
index 0399cd5,59727f0..0000000
--- a/hello.rb
+++ b/hello.rb
@@@ -1,7 -1,7 +1,11 @@@
  #! /usr/bin/env ruby

  def hello
++<<<<<<< HEAD
 +  puts 'hola món'
++=======
+   puts 'hola mundo'
++>>>>>>> mundo
  end

  hello()

El format s’anomena “Diff Combinat” i us dona dues columnes de dades al costat de cada línia. La primera columna us mostra si aquesta línia és diferent (afegida o eliminada) entre la branca “ours” i el fitxer al vostre directori de treball i la segona columna fa el mateix entre la branca “theirs” i la vostra còpia del directori de treball.

Així que en aquest exemple podeu veure que les línies <<<<<<< i >>>>>>> estan a la còpia de treball però no estaven en cap dels dos costats de la fusió. Això té sentit perquè l’eina de fusió les va posar allà per al vostre context, però s’espera que les elimineu.

Si resolveu el conflicte i executeu git diff de nou, veureu el mateix, però és una mica més útil.

$ vim hello.rb
$ git diff
diff --cc hello.rb
index 0399cd5,59727f0..0000000
--- a/hello.rb
+++ b/hello.rb
@@@ -1,7 -1,7 +1,7 @@@
  #! /usr/bin/env ruby

  def hello
-   puts 'hola món'
 -  puts 'hola mundo'
++  puts 'hola mundo'
  end

  hello()

Això ens mostra que “hola món” estava al nostre costat però no a la còpia de treball, que “hola mundo” estava al seu costat però no a la còpia de treball i finalment que “hola mundo” no estava en cap dels dos costats però ara està a la còpia de treball. Això pot ser útil per revisar abans de confirmar la resolució.

També podeu obtenir això des del git log per a qualsevol fusió per veure com es va resoldre alguna cosa després dels fets. Git generarà aquest format si executeu git show en un commit de fusió, o si afegiu una opció --cc a un git log -p (que per defecte només mostra parxets per a commits no de fusió).

$ git log --cc -p -1
commit 14f41939956d80b9e17bb8721354c33f8d5b5a79
Merge: f1270f7 e3eb223
Author: Scott Chacon <schacon@gmail.com>
Date:   Fri Sep 19 18:14:49 2014 +0200

    Merge branch 'mundo'

    Conflicts:
        hello.rb

diff --cc hello.rb
index 0399cd5,59727f0..e1d0799
--- a/hello.rb
+++ b/hello.rb
@@@ -1,7 -1,7 +1,7 @@@
  #! /usr/bin/env ruby

  def hello
-   puts 'hola món'
 -  puts 'hola mundo'
++  puts 'hola mundo'
  end

  hello()

Desfer Fusions

Ara que sabeu com crear un commit de fusió, probablement en fareu alguns per error. Una de les grans coses de treballar amb Git és que està bé fer errors, perquè és possible (i en molts casos fàcil) corregir-los.

Els commits de fusió no són diferents. Digueu que vau començar a treballar en una branca de tema, accidentalment la vau fusionar a master, i ara el vostre historial de commits sembla així:

Fusió accidental
Figure 1. Fusió accidental

Hi ha dues maneres d’abordar aquest problema, depenent de quin sigui el resultat desitjat.

Corregir les referències

Si el commit de fusió no desitjat només existeix al vostre repositori local, la solució més fàcil i millor és moure les branques perquè apuntin on voleu. En la majoria dels casos, si seguiu l’errònia git merge amb git reset --hard HEAD~, això restablirà els punters de branca perquè semblin així:

Historial després de `git reset --hard HEAD~`
Figure 2. Historial després de git reset --hard HEAD~

Ja vam tractar reset a ch07-git-tools.asc, així que no hauria de ser massa difícil entendre què està passant aquí. Aquí teniu un ràpid recordatori: reset --hard normalment passa per tres passos:

  1. Moure la branca a la qual apunta HEAD. En aquest cas, volem moure master a on estava abans del commit de fusió (C6).

  2. Fer que l’índex sembli HEAD.

  3. Fer que el directori de treball sembli l’índex.

L’inconvenient d’aquest enfocament és que està reescribent l’historial, el que pot ser problemàtic amb un repositori compartit. Consulteu ch03-git-branching.asc per a més informació sobre el que pot passar; la versió curta és que si altres persones tenen els commits que esteu reescribent, probablement hauríeu d’evitar reset. Aquest enfocament tampoc funcionarà si s’han creat altres commits des de la fusió; moure les referències perdria efectivament aquests canvis.

Invertir el commit

Si moure els punters de branca no us funcionarà, Git us dona l’opció de crear un nou commit que desfa tots els canvis d’un existent. Git anomena aquesta operació una “revert”, i en aquest escenari particular, l’invocaríeu així:

$ git revert -m 1 HEAD
[master b1d8379] Revert "Merge branch 'topic'"

L’opció -m 1 indica quin pare és la “mainline” i s’ha de mantenir. Quan invoqueu una fusió a HEAD (git merge topic), el nou commit té dos pares: el primer és HEAD (C6), i el segon és la punta de la branca que s’està fusionant (C4). En aquest cas, volem desfer tots els canvis introduïts per la fusió del pare #2 (C4), mantenint tot el contingut del pare #1 (C6).

L’historial amb el commit revertit sembla així:

Historial després de `git revert -m 1`
Figure 3. Historial després de git revert -m 1

El nou commit ^M té exactament el mateix contingut que C6, així que a partir d’aquí és com si la fusió mai hagués passat, excepte que els commits ara no fusionats encara estan a l’historial de HEAD. Git es confondrà si intenteu fusionar topic a master de nou:

$ git merge topic
Already up-to-date.

No hi ha res a topic que no sigui ja accessible des de master. El que és pitjor, si afegiu treball a topic i fusionau de nou, Git només portarà els canvis des de la fusió revertida:

Historial amb una mala fusió
Figure 4. Historial amb una mala fusió

La millor manera d’evitar això és des-revertir la fusió original, ja que ara voleu portar els canvis que es van revertir, llavors crear un nou commit de fusió:

$ git revert ^M
[master 09f0126] Revert "Revert "Merge branch 'topic'""
$ git merge topic
Historial després de tornar a fusionar una fusió revertida
Figure 5. Historial després de tornar a fusionar una fusió revertida

En aquest exemple, M i ^M es cancel·len. ^^M fusiona efectivament els canvis de C3 i C4, i C8 fusiona els canvis de C7, així que ara topic està completament fusionat.

Altres Tipus de Fusions

Fins ara hem tractat la fusió normal de dues branques, normalment gestionada amb el que s’anomena l’estratègia “recursiva” de fusió. No obstant això, hi ha altres maneres de fusionar branques. Tractem algunes d’elles ràpidament.

Preferència de Nostre o Seva

En primer lloc, hi ha una altra cosa útil que podem fer amb el mode normal “recursiu” de fusió. Ja hem vist les opcions ignore-all-space i ignore-space-change que es passen amb un -X però també podem dir a Git que prefereixi un costat o l’altre quan veu un conflicte.

Per defecte, quan Git veu un conflicte entre dues branques que es fusionen, afegirà marcadors de conflicte de fusió al vostre codi i marcarà el fitxer com a en conflicte i us deixarà resoldre’l. Si preferiu que Git simplement triï un costat específic i ignori l’altre costat en lloc de deixar-vos resoldre el conflicte manualment, podeu passar a la comanda merge un -Xours o -Xtheirs.

Si Git veu això, no afegirà marcadors de conflicte. Qualsevol diferència que sigui fusionable, es fusionarà. Qualsevol diferència que estigui en conflicte, simplement triarà el costat que especifiqueu en la seva totalitat, incloent fitxers binaris.

Si tornem a l’exemple “hola món” que estàvem utilitzant abans, podem veure que fusionar la nostra branca causa conflictes.

$ git merge mundo
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Resolved 'hello.rb' using previous resolution.
Automatic merge failed; fix conflicts and then commit the result.

No obstant això, si l’executem amb -Xours o -Xtheirs no ho fa.

$ git merge -Xours mundo
Auto-merging hello.rb
Merge made by the 'recursive' strategy.
 hello.rb | 2 +-
 test.sh  | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

En aquest cas, en lloc d’obtenir marcadors de conflicte al fitxer amb “hola mundo” en un costat i “hola món” a l’altre, simplement tria “hola món”. No obstant això, tots els altres canvis no conflictius en aquesta branca es fusionen amb èxit.

Aquesta opció també es pot passar a la comanda git merge-file que vam veure abans executant alguna cosa com git merge-file --ours per a fusions individuals de fitxers.

Si voleu fer alguna cosa com això però no voleu que Git ni tan sols intenti fusionar canvis de l’altre costat, hi ha una opció més dràstica, que és l’estratègia de fusió “ours”. Això és diferent de l’opció de fusió recursiva “ours”.

Això farà bàsicament una fusió falsa. Registrarà un nou commit de fusió amb ambdues branques com a pares, però ni tan sols mirarà la branca que esteu fusionant. Simplement registrarà com a resultat de la fusió el codi exacte a la vostra branca actual.

$ git merge -s ours mundo
Merge made by the 'ours' strategy.
$ git diff HEAD HEAD~
$

Podeu veure que no hi ha diferència entre la branca en què estàveu i el resultat de la fusió.

Això sovint pot ser útil per bàsicament enganyar Git perquè pensi que una branca ja està fusionada quan es fa una fusió més endavant. Per exemple, suposem que heu bifurcat una branca release i heu fet algun treball que voleu fusionar de nou a la vostra branca master en algun moment. Entretant, alguna correcció d’errors a master necessita ser retroportada a la vostra branca release. Podeu fusionar la branca de correcció d’errors a la branca release i també merge -s ours la mateixa branca a la vostra branca master (tot i que la correcció ja hi és) així que quan més endavant fusionau la branca release de nou, no hi ha conflictes de la correcció d’errors.