git rebase comanda are reputația de a fi magic Git voodoo ca incepatorii ar trebui să stea departe de, dar de fapt poate face viața mult mai ușoară pentru o echipa de dezvoltare atunci când este utilizat cu grijă. În acest articol, vom compara git rebase cu git merge comandă și să identifice toate oportunitățile potențiale să includă rebasing în tipic Git flux de lucru.,

prezentare conceptuală

primul lucru de înțeles despre git rebaseeste că rezolvă aceeași problemă ca git merge. Ambele comenzi sunt concepute pentru a integra modificările dintr—o ramură într-o altă ramură-o fac doar în moduri foarte diferite.

luați în considerare ce se întâmplă atunci când începeți să lucrați la o nouă caracteristică într-o ramură dedicată, apoi un alt membru al echipei actualizează ramuramaster cu noi comiteri. Acest lucru are ca rezultat o istorie bifurcată, care ar trebui să fie familiară oricui a folosit Git ca instrument de colaborare.,

Acum, să spunem că la noi se angajează în master sunt relevante pentru trăsătura care lucrezi. Pentru a încorpora noile angajează în feature ramură, ai două opțiuni: fuziune sau rebasing.,

Opțiunea Îmbinare

Cea mai simplă opțiune este de a fuziona master ramură în funcție de ramură, folosind ceva de genul următor:

git checkout feature git merge master

Sau, puteți condensa asta la o singură linie:

 git merge feature master

Acest lucru creează o nouă „unificare a comis” în feature craca de care se leagă istoria de ambele ramuri, oferindu-vă o structură de ramură care arata ca acest lucru:

Fuziune este frumos, pentru că e un non-distructive de exploatare. Ramurile existente nu sunt modificate în nici un fel., Acest lucru evită toate capcanele potențiale ale rebasing (discutate mai jos).

Pe de altă parte, acest lucru înseamnă, de asemenea, că feature ramură va avea un exterior îmbinare comite de fiecare dată când aveți nevoie să includă schimbările din amonte. Dacă master este foarte activ, acest lucru poate polua destul de mult Istoricul sucursalei dvs. de caracteristici. Deși este posibil pentru a atenua această problemă cu advancedgit log opțiuni, se poate face greu pentru alți dezvoltatori pentru a înțelege istoria proiectului.,

De Rebazare Opțiune

Ca o alternativă la unirea, puteți rebazare feature ramura pe master ramură folosind următoarele comenzi:

git checkout feature git rebase master

Acest lucru se mută întreaga feature ramură a începe pe vârful master ramură, în mod eficient încorporează toate dintre noi se angajează în master. Dar, în loc să folosească o comitere de îmbinare, rebasing re-scrie istoricul proiectului prin crearea de comiteri noi pentru fiecare comitere în ramura originală.,

avantajul major al rebasing este că veți obține un istoric de proiect mult mai curat. În primul rând, elimină comiterile de îmbinare inutile cerute de git merge. În al doilea rând, după cum puteți vedea în diagrama de mai sus, rebasing—ul are ca rezultat și un istoric al proiectului perfect liniar-puteți urmări vârful feature până la începutul proiectului fără furci. Acest lucru face mai ușor pentru a naviga-ți de proiect cu comenzi de genul git log, git bisect și gitk.,dar, există două compromisuri pentru acest istoric de comitere curat: siguranță și trasabilitate. Dacă nu respectați regula de aur a Rebasing-ului, rescrierea istoricului proiectului poate fi potențial catastrofală pentru fluxul de lucru al colaborării. Și, mai puțin important, rebasing pierde contextul oferit de un Commit merge—nu puteți vedea când modificările din amonte au fost încorporate în caracteristică.

Interactive Rebasing

Interactive rebasing vă oferă posibilitatea de a modifica angajează ca ei sunt mutat la noua filială., Acest lucru este chiar mai puternic decât o rebase automată, deoarece oferă un control complet asupra istoriei comiterii sucursalei. De obicei, acest lucru este folosit pentru a curăța un istoric murdar înainte de a fuziona o ramură caracteristică în master.,

Pentru a începe un interactiv rebasing sesiune, trece i opțiunea de a git rebase command:

git checkout feature git rebase -i master

Acest lucru va deschide un editor de text în care sunt listate toate se angajează ca sunt pe cale de a fi mutat:

pick 33d5b7a Message for commit #1 pick 9480b3d Message for commit #2 pick 5c67e61 Message for commit #3

Această listă definește exact ce ramura va arata ca dupa rebazare este realizată. Modificând comanda pick și/sau re-ordonând intrările, puteți face ca istoricul sucursalei să arate ca orice doriți., De exemplu, dacă comite a 2-a fixat o mică problemă, în 1-a comis-o, puteți să le condenseze într-un singur comite cu fixup command:

pick 33d5b7a Message for commit #1 fixup 9480b3d Message for commit #2 pick 5c67e61 Message for commit #3

atunci Când salvați și închideți fișierul, Git va efectua rebazare în conformitate cu instrucțiunile dumneavoastră, care rezultă în istoria proiect care arată în felul următor:

Eliminarea nesemnificative se angajează ca acest lucru face caracteristică istorie mult mai ușor de înțeles. Acesta este un lucru pe care git merge pur și simplu nu îl poate face.,

Regula de Aur a Rebasing

Odată ce ați înțeles ce rebasing este, cel mai important lucru pentru a învăța este atunci când nu o fac. Regula de aur a git rebase este să nu o folosești niciodată pe sucursalele publice.

De exemplu, gândiți-vă ce s-ar întâmpla dacă ai indexat master pe feature ramură:

rebazare se mișcă toate se angajează în master pe vârful feature. Problema este că acest lucru sa întâmplat numai în depozitul dvs., Toți ceilalți dezvoltatori sunt încă de lucru cu originalul master. Deoarece rebasing rezultate in nou se angajează, Git va crede că master ramură de istorie a deviat de la toți ceilalți.

singurul mod De a sincroniza cele două master ramuri este de a le îmbina din nou împreună, rezultând un plus de îmbinare a comis-o și două seturi de comite, care conțin aceleași modificări (cele originale, iar cele de la indexate de ramură). Inutil să spun, Aceasta este o situație foarte confuză.,deci, înainte de a rula git rebase, întrebați-vă întotdeauna: „se mai uită cineva la această ramură?”Dacă răspunsul este da, luați-vă mâinile de pe tastatură și începeți să vă gândiți la un mod nedistructiv de a face modificările (de exemplu, comanda git revert). În caz contrar, sunteți în siguranță să re-scrieți istoria cât doriți.dacă încercați să împingeți ramura rebased masterînapoi într-un depozit la distanță, Git vă va împiedica să faceți acest lucru deoarece intră în conflict cu ramura master., Dar, puteți forța împinge să treacă printr-prin trecerea --force pavilion, astfel:

# Be very careful with this command! git push --force

Aceasta suprascrie la distanță master ramură pentru a se potrivi indexate unul din repository-ul dvs. și de a face lucruri foarte confuz pentru restul echipei. Deci, fiți foarte atenți să utilizați această comandă numai atunci când știți exact ce faceți.

una dintre singurele situații în care ar trebui să apăsați cu forța este atunci când ați efectuat o curățare locală după ce ați împins o ramură de caracteristici private într-un depozit la distanță (de exemplu, în scopuri de backup)., Este ca și cum ai spune: „Oops, nu am vrut cu adevărat să împing acea versiune originală a ramurii de caracteristici. Ia-o pe cea actuală.”Din nou, este important ca nimeni să nu lucreze la comiterile din versiunea originală a ramurii de caracteristici.

flux de lucru Walkthrough

Rebasing pot fi încorporate în fluxul de lucru git existent la fel de mult sau la fel de puțin ca echipa ta este confortabil cu. În această secțiune, vom analiza beneficiile pe care rebasing le poate oferi în diferitele etape ale dezvoltării unei caracteristici.,

primul pas în orice flux de lucru care utilizează git rebase este de a crea o ramură dedicată pentru fiecare caracteristică. Acest lucru vă oferă necesar structură de ramură în condiții de siguranță pentru a utiliza rebasing:

Locale de Curatare

Unul dintre cele mai bune moduri de a încorpora rebasing în fluxul dvs. de lucru este de a curăța locale, în curs de caracteristici. Prin efectuarea periodică a unei rebase interactive, vă puteți asigura că fiecare comitere din funcția dvs. este focalizată și semnificativă., Acest lucru vă permite să scrieți codul dvs. fără să vă faceți griji cu privire la împărțirea acestuia în comiteri izolate—îl puteți repara după fapt.

atunci Când de asteptare git rebase, aveți două opțiuni pentru noua bază: funcția părinte ramură (de exemplu, master), sau mai devreme comite în funcție. Am văzut un exemplu al primei opțiuni în secțiunea Rebasing interactiv. Ultima opțiune este plăcută atunci când trebuie doar să remediați ultimele câteva angajamente. De exemplu, următoarea comandă începe o rebase interactivă numai pentru ultimele 3 comiteri.,

git checkout feature git rebase -i HEAD~3

Prin specificarea HEAD~3 ca noua baza, nu ești de fapt în mișcare ramura—esti interactiv re-scris 3 se angajează ca-l urmeze. Rețineți că aceasta nu va încorpora modificările din amonte în ramura feature.

Dacă doriți să re-scrie întreaga caracteristică folosind această metodă, git merge-base comanda poate fi util pentru a găsi cel original baza feature ramură., Următoarele returnează comite ID-ul de baza originala, pe care o puteți trece apoi la git rebase:

git merge-base feature master

folosirea interactivă rebasing este o modalitate foarte bună de a introduce git rebase în fluxul dvs. de lucru, deoarece aceasta afectează numai filiale locale. Singurul lucru pe care îl vor vedea alți dezvoltatori este produsul dvs. finit, care ar trebui să fie un istoric curat, ușor de urmărit.

dar, din nou, acest lucru funcționează numai pentru sucursalele de caracteristici private., Dacă colaborezi cu alți dezvoltatori prin intermediul aceleiași sucursale de caracteristici, sucursala respectivă este publică și nu ai voie să rescrii istoricul acesteia.

nu există o alternativă git merge pentru curățarea angajărilor locale cu o rebază interactivă.

Încorporează Schimbările din Amonte Într-o Caracteristică

În privire de Ansamblu Conceptual secțiune, am văzut cum o caracteristică de ramură pot integra în amonte modificările de la master folosind fie git merge sau git rebase., Fuziunea este o opțiune sigură că păstrează întreaga istorie de depozit, în timp ce rebasing creează o istorie liniară de mișcare caracteristică ramură pe vârful master.

Acest git rebase este similar cu un local de curățare (și pot fi efectuate simultan), dar în procesul acesta încorporează cele din amonte se angajează la master.

rețineți că este perfect legal să rebase pe o sucursală la distanță în loc de master., Acest lucru se poate întâmpla atunci când colaborați la aceeași caracteristică cu un alt dezvoltator și trebuie să încorporați modificările acestuia în depozitul dvs.,

De exemplu, dacă ai și un alt dezvoltator pe nume John a adăugat angajează să feature ramură, repository-ul dvs. ar putea fi următoarea după preluarea de la distanță feature ramură de John depozit:

puteți rezolva această furcă exact în același mod ca să se integreze în amonte modificările de la master: fie merge locale feature cu john/feature, sau rebazare local feature pe vârful john/feature.,

Rețineți că această schimbare de bază nu se încalcă Regula de Aur a Rebasing pentru că numai local feature se angajează sunt mutate—tot înainte că este de neatins. Acest lucru este ca și cum ai spune: „adăugați modificările mele la ceea ce John a făcut deja.”În majoritatea circumstanțelor, acest lucru este mai intuitiv decât sincronizarea cu sucursala de la distanță printr-o comitere de îmbinare.

în mod implicit, git pull comandă efectuează o unificare, dar puteți forța să integreze ramură de la distanță cu o rebazare prin trecerea --rebase opțiune.,dacă utilizați solicitări pull ca parte a procesului de examinare a codului, trebuie să evitați utilizarea git rebase după crearea solicitării pull. De îndată ce faceți solicitarea pull, alți dezvoltatori vă vor examina angajamentele, ceea ce înseamnă că este o ramură publică. Re-scrierea istoricului său va face imposibil pentru Git și coechipierii dvs. să urmărească orice angajamente de urmărire adăugate la caracteristică.

Orice modificări la alte dezvoltatorii trebuie să fie încorporate cu git merge în loc de git rebase.,

Din acest motiv, este de obicei o idee bună să vă curățați codul cu o rebase interactivă înainte de a trimite solicitarea pull.

Integrarea unui Aprobat Caracteristică

După o caracteristică a fost aprobat de echipa ta, aveți opțiunea de a rebasing caracteristica pe vârful master sucursală înainte de a utiliza git merge pentru a integra caracteristică în principal cod de bază.,

Aceasta este o situație similară cu încorporează schimbările din amonte într-o caracteristică de ramură, dar din moment ce nu ai voie să re-scrie angajează în master ramură, trebuie să în cele din urmă folosi git merge pentru a integra caracteristică. Cu toate acestea, prin efectuarea unei rebase înainte de îmbinare, sunteți sigur că îmbinarea va fi redirecționată rapid, rezultând o istorie perfect liniară. Acest lucru vă oferă, de asemenea, șansa de a zdrobi orice angajamente de urmărire adăugate în timpul unei solicitări de tragere.,

Daca nu esti pe deplin confortabil cu git rebase, puteți efectua întotdeauna rebazare într-o temporară de ramură. În acest fel, dacă încurcați accidental Istoricul funcției dvs., puteți verifica sucursala originală și încercați din nou. De exemplu:

git checkout feature git checkout -b temporary-branch git rebase -i master # git checkout master git merge temporary-branch

Sumar

Și asta e tot ce trebuie să știi pentru a începe rebasing crengi., Dacă preferați un loc curat, liniar istorie gratuit de inutile fuziona comite, ar trebui să ajungă pentru git rebase în loc de git merge când integrarea schimbă de la o altă ramură.

Pe de altă parte, dacă doriți să păstrați istoricul complet al proiectului dvs. și să evitați riscul de a re-scrie comiteri publice, puteți rămâne cu git merge. Oricare dintre opțiuni este perfect validă, dar cel puțin acum aveți opțiunea de a profita de avantajele git rebase.