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 rebase
este 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
.
Lasă un răspuns