Snažím sa úmyselne vyvolať konflikt zlúčenia git. Tu je to, čo som urobil
mkdir to-stack
cd to-stack
git init
vi a.txt
Added some text to first line of a.txt
git add a.txt
git commit -m "Added a line to a.txt"
git checkout -b other
vi a.txt
Updated the text on first line of a.txt to something else
git add a.txt
git commit -m "Updated line 1"
git checkout master
git merge other
Došlo k zlúčeniu a obsah a.txt v hlavnej vetve bol prepísaný na obsah z inej vetvy
Očakával som, že pri zlúčení dôjde ku konfliktu zlúčenia. Pretože som zmenil ten istý riadok v inej vetve
Môžete mi povedať, prečo k zlúčeniu konfliktu v uvedenom prípade nedošlo?
odpovede:
1 pre odpoveď č. 1A zlúčiť kombinuje zmeny z niektorých spoločných záväzkov na dve rozdielny spácha (ktorých vzťah je taký, že obaja majú tento spoločný záväzok vo svojej histórii).
To znamená, zvážte nasledujúci graf potvrdenia, kde každý o
alebo *
predstavuje potvrdenie a každé potvrdenie rodič je potvrdenie, ktoré sa zistí sledovaním jeho spojenia doľava (v prípade potreby pohybom nahor alebo nadol):
o <-- branchA
/
...--o--*
o--o <-- branchB
Prví sa toho dopustia branchA
a branchB
zdieľam je označený *
. Zdieľajú tiež každý predchádzajúci záväzok (naľavo od *
), ale *
je najzaujímavejší takýto záväzok. Tomu hovoríme zaviazať zlúčiť základňu z branchA
a branchB
.
Keď spustíte:
$ git checkout branchA
$ git merge branchB
na git merge
krok vidí, že sme na branchA
(v dôsledku git checkout
príkaz) a že požadujeme zlúčenie najdôležitejších záväzkov branchB
. Git potom vyhľadá tento základný príkaz zlúčenia a spustí sa dva git diff
príkazy.
Povedzme, že je to hash potvrdenia *
je ba5e...
a tip sa zaviaže ďalej branchA
je spáchať 1111...
s tipom spáchať z branchB
bytia 2222...
. Dva git diff
príkazy sú potom v podstate:
$ git diff ba5e 1111
a:
$ git diff ba5e 2222
Prvý rozdiel hovorí Gitu „čo sme urobili“: čo my zmenené z *
na koniec branchA
. Druhý rozdiel hovorí Gitu „čo urobili“: čo oni zmenil sa od *
na koniec branchB
.
A zlúčiť konflikt nastane, keď sa v časti „čo sme“ zmenili rovnaké riadky rovnakého súboru (súborov) ako v časti „čo urobili“, tieto dve zmeny sa však líšia. Napríklad ak sa obaja zmeníme README.txt
zmeniť farbu jablka, ale my zmeniť to z fialovej na čiernu a zmeniť to z fialovej na oranžovú, Git nevie, ktorú z nich si vziať.
Urobme teda toto:
mkdir mtest && cd mtest && git init
echo "for testing" > README.txt
echo "have a purple apple" >> README.txt
git add README.txt && git commit -m initial
Takto sa vytvorí vetva master
s jedným súborom, README.txt
. Teraz poďme vytvoriť dve samostatné vetvy rozvetvené od tohto jedného potvrdenia a zmeniť farbu jablka v každej vetve:
git checkout -b branchA master
sed -i "" s/purple/black/ README.txt
git add README.txt && git commit -m black
git checkout -b branchB master
sed -i "" s/purple/orange/ README.txt
git add README.txt && git commit -m black
Teraz jednoducho zlúčime jednu vetvu s druhou. Momentálne sme na branchB
, takže môžeme git merge branchA
teraz. Len čo konflikt vyriešime a zaviažeme, zlúčime sa branchB
. Alebo môžeme git checkout branchA
potom najskôr git merge branchB
. Dostaneme rovnaký konflikt, ale akonáhle ho vyriešime a zaviažeme, zlúčime sa branchA
.