Git rebase: Všetko, čo potrebujete vedieť


Zhrnutie: Príkaz Git rebase presunie vetvu na nové miesto v čele inej vetvy. Na rozdiel od príkazu Git merge, rebase zahŕňa prepísanie vašej histórie projektu. Je to skvelý nástroj, ale nezaväzujte sa, že iní vývojári na ňom pracovali.

Príkaz Git rebase kombinuje dve vetvy zdrojového kódu do jednej. Príkaz merge Git to robí tiež. Vysvetlíme, čo robí rebase, ako sa používa a kedy namiesto toho použiť zlúčiť.

Explózia Git

Linus Torvalds, frustrovaný inými systémami na správu verzií a ich pomalými aktualizáciami a potvrdeniami, si v roku 2005 odložil mesiac na napísanie vlastného. Pomenoval ho Git.

Stránky ako GitHub, GitLab a BitBucket symbioticky propagujú a ťažia z Gitu. V súčasnosti sa Git používa celosvetovo, pričom v prieskume z roku 2022 použilo Git ako systém na správu verzií masívnych 98 percent zo 71 tisíc respondentov.

Jedným z hlavných návrhových rozhodnutí Gitu bola rýchlosť. Najmä práca s pobočkami musela byť čo najrýchlejšia. Pobočky sú základnou súčasťou systémov na správu verzií. Úložisko projektu bude mať hlavnú alebo hlavnú vetvu. Tu sa nachádza základ kódu projektu. Vývoj, ako napríklad nové funkcie, prebieha v oddelených bočných vetvách. To zabraňuje tomu, aby práca vykonávaná vo vetvách pokazila hlavnú vetvu, a umožňuje to simultánny vývoj v rôznych častiach kódovej základne.

Po dokončení vývoja v bočných vetvách sa zmeny prenesú do hlavnej vetvy zlúčením vývojovej vetvy do hlavnej vetvy. V iných verziách riadiacich systémov bola práca s pobočkami náročná a výpočtovo nákladná. Práca s vetvami v Git je veľmi rýchla a veľmi ľahká. To, čo bolo kedysi únavným cvičením, ktorému sa v iných systémoch často vyhýbalo, sa v Gite stalo triviálnym.

Príkaz Git rebase je ďalším spôsobom prenosu zmien z jednej vetvy do druhej. Príkazy merge a rebase majú podobné ciele, no dosahujú svoj účel rôznymi spôsobmi a prinášajú mierne odlišné výsledky.

Čo je zlúčenie Git?

Na čo teda slúži príkaz Git merge? Povedzme, že ste vytvorili vetvu s názvom dev-branch na prácu na novej funkcii.

Urobíte niekoľko záväzkov a otestujete svoju novú funkciu. Všetko to funguje dobre. Teraz chcete poslať svoju novú funkciu do pobočky master. Ak chcete zlúčiť ďalšiu vetvu, musíte byť vo vetve master.

Môžeme sa uistiť, že sme v hlavnej pobočke tak, že ju pred zlúčením výslovne skontrolujeme.

git checkout master

Teraz môžeme Gitu povedať, aby zlúčil dev-branch do aktuálnej vetvy, ktorou je vetva master.

git merge dev-branch

Naše zlúčenie je pre nás dokončené. Ak skontrolujete vetvu master a skompilujete ju, bude obsahovať novo vyvinutú funkciu. To, čo Git v skutočnosti vykonal, je trojcestné zlúčenie. porovnáva najnovšie odovzdania vo vetvách master a dev-branch a odovzdanie vo vetve master bezprostredne pred vetvou dev -branch bol vytvorený. Potom vykoná potvrdenie na vetve master.

Zlúčenia sa považujú za nedeštruktívne, pretože nič neodstraňujú a nemenia žiadnu históriu Git. dev-branch stále existuje a žiadne z predchádzajúcich potvrdení nie je zmenené. Vytvorí sa nové potvrdenie, ktoré zachytí výsledky trojcestného zlúčenia.

Po zlúčení vyzerá náš Git repozitár ako časová os s alternatívnou líniou, ktorá sa rozvetvuje a potom sa vracia na hlavnú časovú os.

Vetva dev-branch bola začlenená do vetvy master.

Ak máte v jednom projekte veľa pobočiek, história projektu môže byť mätúca. To je často prípad, ak má projekt veľa prispievateľov. Pretože vývojové úsilie sa delí na mnoho rôznych ciest, história vývoja je nelineárna. Rozlúštenie histórie odovzdania je ešte ťažšie, ak majú pobočky svoje vlastné pobočky.

Upozorňujeme, že ak máte vo vetve master nepotvrdené zmeny, budete musieť s týmito zmenami niečo urobiť, až potom do nej budete môcť čokoľvek zlúčiť. Môžete vytvoriť novú vetvu a tam odovzdať zmeny a potom vykonať zlúčenie. Potom budete musieť zlúčiť svoju dočasnú pobočku späť do hlavnej pobočky.

Funguje to, ale Git má príkaz, ktorý dosahuje to isté bez toho, aby ste museli vytvárať nové vetvy. Príkaz stash za vás uloží vaše nepotvrdené zmeny a umožní vám ich zavolať späť pomocou stash pop .

Použili by ste ich takto:

stash

git merge dev-branch

stash pop

Konečným výsledkom je zlúčená vetva s obnovenými neuloženými zmenami.

Čo je rebase Git?

Príkaz Git rebase dosahuje svoje ciele úplne iným spôsobom. Vezme všetky odovzdania z vetvy, ktorú chcete prehodnotiť, a prehrá ich na koniec vetvy, na ktorú sa chystáte prehodnotiť.

Ak vezmeme do úvahy náš predchádzajúci príklad, predtým, ako sme vykonali akúkoľvek akciu, naše úložisko Git vyzerá takto. Máme vetvu s názvom dev-branch a chceme tieto zmeny presunúť do vetvy master.

Po rebase to vyzerá ako jedna, úplne lineárna časová os zmien.

dev-branch bola odstránená a odovzdania v dev-branch boli pridané do hlavnej vetvy. Konečný výsledok je rovnaký, ako keby odovzdania vo vetve dev-branch boli skutočne priamo odovzdané vetve master. Potvrdenia nie sú len prilepené na vetvu master, ale sú „prehraté“ a pridané čerstvé.

Preto sa príkaz rebase považuje za deštruktívny. Znovu založená vetva už neexistuje ako samostatná vetva a história Git vášho projektu bola prepísaná. Neskôr nemôžete určiť, ktoré potvrdenia boli pôvodne vykonané na dev-branch.

Zanecháva vám však zjednodušenú, lineárnu históriu. V porovnaní s úložiskom s desiatkami alebo dokonca stovkami pobočiek a zlúčení, čítaním denníka Git alebo používaním grafického grafického používateľského rozhrania git na prezeranie grafu úložiska, je repozitár s novým základom hračkou pochopiť.

Ako sa preorientovať na inú vetvu

Skúsme príklad git rebase. Máme projekt s vetvou s názvom new-feature. Túto vetvu by sme premenili na vetvu master takto.

Najprv skontrolujeme, či vetva master neobsahuje žiadne nevyriešené zmeny.

git status

Skontrolujeme vetvu new-feature.

git checkout new-feature

Povieme Gitu, aby pretvoril aktuálnu vetvu na hlavnú.

git rebase master

Vidíme, že stále máme dve vetvy.

git branch

Prejdeme späť na vetvu master

git checkout master

Zlúčime vetvu s novými funkciami do aktuálnej vetvy, ktorou je v našom prípade vetva master.

git merge new-feature

Zaujímavé je, že po konečnom zlúčení máme stále dve pobočky.

Rozdiel je v tom, že hlavička vetvy new-feature a hlavička vetvy master sú teraz nastavené tak, aby ukazovali na rovnaké odovzdanie, a história Git nie ukázať, že okrem označenia vetvy bývala samostatná vetva new-feature.

Git Rebase vs. Merge: Ktorý z nich by ste mali použiť?

Nejde o prípad rebase vs. zlúčenie. Oba sú to mocné príkazy a pravdepodobne ich použijete oba. To znamená, že existujú prípady použitia, keď rebase v skutočnosti nefunguje tak dobre. Vyberanie chýb spôsobených chybami pomocou zlúčiť je nepríjemné, ale vyberanie chýb spôsobených rebase je pekelné.

Ak ste jediným vývojárom, ktorý používa úložisko, je menšia šanca, že s rebase urobíte niečo katastrofálne. Stále môžete napríklad preložiť nesprávnym smerom a preložiť svoju hlavnú vetvu na vetvu new-feature. Ak chcete získať späť svoju hlavnú pobočku, musíte ju znova pretvoriť, tentoraz z vašej novej funkcie vetvy na hlavnú vetva. To by obnovilo vašu master vetvu, aj keď s čudne vyzerajúcou históriou.

Nepoužívajte rebase na zdieľaných pobočkách, kde budú pravdepodobne pracovať iní. Vaše zmeny vo vašom úložisku spôsobia problémy mnohým ľuďom, keď presuniete svoj prepracovaný kód do vzdialeného úložiska.

Ak má váš projekt viacerých prispievateľov, môžete bezpečne použiť rebase iba vo svojom lokálnom úložisku a nie na verejných pobočkách. Podobne, ak požiadavky na stiahnutie tvoria súčasť kontroly kódu, nepoužívajte rebase. Alebo aspoň nepoužívajte rebase po vytvorení žiadosti o stiahnutie. Iní vývojári si pravdepodobne prezerajú vaše potvrdenia, čo znamená, že tieto zmeny sú vo verejnej vetve, aj keď nie sú vo vetve master.

Nebezpečenstvo spočíva v tom, že sa chystáte znovu založiť potvrdenia, ktoré už boli odoslané do vzdialeného úložiska a iní vývojári už mohli na týchto potvrdeniach pracovať. Vaša lokálna rebase spôsobí, že tieto existujúce odovzdania zmiznú. Ak tieto zmeny presuniete do úložiska, nebudete populárni.

Ostatní prispievatelia budú musieť prejsť komplikovaným zlúčením, aby sa ich práca vrátila späť do úložiska. Ak potom ich zmeny stiahnete späť do miestneho úložiska, budete musieť vybrať zmätok duplicitných zmien.

Rebaseovať, či nerebaseovať?

Rebase môže byť vo vašom projekte zakázaný. Môžu existovať miestne, kultúrne námietky. Niektoré projekty alebo organizácie považujú rebase za formu herézy a akt znesvätenia. Niektorí ľudia veria, že história Git by mala byť nedotknuteľným, trvalým záznamom toho, čo sa stalo. Takže rebase môže byť mimo tabuľky.

Ale pri lokálnom použití na súkromných pobočkách je rebase užitočným nástrojom.

Zatlačte po, čo ste zmenili, a obmedzte ho na pobočky, v ktorých ste jediným vývojárom. Alebo aspoň tam, kde sa všetok vývoj zastavil a nikto iný nezaložil žiadnu inú prácu na záväzkoch vašej pobočky.

Urobte to a vyhnete sa akýmkoľvek problémom.