git rebase
kommando har ry for at være magiske Git voodoo, at begyndere bør holde sig væk fra, men det kan faktisk gøre livet meget lettere for en udvikling team, når de anvendes med forsigtighed. I denne artikel vil vi sammenligne git rebase
med de tilhørende git merge
kommando og identificere alle de potentielle muligheder for at indarbejde rebasing i den typiske Git workflow.,
Konceptuel Oversigt
Den første ting at forstå, om git rebase
er, at det løser det samme problem som git merge
. Begge disse kommandoer er designet til at integrere ændringer fra en gren til en anden gren—de gør det bare på meget forskellige måder.
overvej hvad der sker, når du begynder at arbejde på en ny funktion i en dedikeret filial, så opdaterer et andet teammedlem master
gren med nye commits. Dette resulterer i en forked historie, som bør være kendt for alle, der har brugt Git som et samarbejdsværktøj.,
lad os nu sige, at de nye forpligtelser i master
er relevante for den funktion, du arbejder på. For at indarbejde de nye forpligtelser i din feature
gren, har du to muligheder: sammenlægning eller rebasing.,
Merge Option
Den nemmeste løsning er at flette master
gren i den funktion, filial ved hjælp af noget, der ligner følgende:
git checkout feature git merge master
Eller du kan kondensere dette til en one-liner:
git merge feature master
Dette skaber en ny “flet begå” i feature
gren, der binder de historier, at de to grene, der giver dig en filial struktur, der ligner dette:
Fletning er rart, fordi det er en ikke-destruktiv drift. De eksisterende grene ændres ikke på nogen måde., Dette undgår alle de potentielle faldgruber af rebasing (diskuteret nedenfor).
på den anden side betyder dette også, at feature
– grenen vil have en fremmed merge commit, hver gang du har brug for at inkorporere opstrømsændringer. Hvis master
er meget aktiv, kan dette forurene din funktionsgrens historie ganske lidt. Selvom det er muligt at afbøde dette problem med advanced git log
indstillinger, kan det gøre det svært for andre udviklere at forstå projektets historie.,
Den Rebase Mulighed
Som et alternativ til en sammenlægning, kan du rebase feature
gren på master
gren ved hjælp af følgende kommandoer:
git checkout feature git rebase master
Det flytter sig hele feature
gren til at begynde på spidsen af master
gren, effektivt, som inkorporerer alle de nye begår i master
. Men i stedet for at bruge en merge commit, skriver rebasing igen projekthistorikken ved at skabe helt nye commits for hver commit i den oprindelige gren.,
den største fordel ved rebasing er, at du får en meget renere projekthistorie. For det første eliminerer det de unødvendige fusionsforpligtelser, der kræves af git merge
. For det andet, som du kan se i ovenstående diagram, resulterer rebasing også i en perfekt lineær projekthistorie—du kan følge spidsen af feature
helt til projektets begyndelse uden gafler. Dette gør det nemmere at navigere i dit projekt med kommandoer som f.eks. git log
git bisect
og gitk
.,
men der er to afvejninger for denne uberørte begå historie: sikkerhed og sporbarhed. Hvis du ikke følger den gyldne regel om Rebasing, kan omskrivning af projekthistorik være potentielt katastrofalt for dit samarbejde workorkflo.. Og, mindre vigtigt, at rebasing mister konteksten, der leveres af en merge commit—du kan ikke se, hvornår opstrømsændringer blev inkorporeret i funktionen.
interaktiv Rebasing
interaktiv rebasing giver dig mulighed for at ændre commits, når de flyttes til den nye filial., Dette er endnu mere kraftfuldt end en automatiseret rebase, da det giver fuld kontrol over filialens commit-historie. Typisk bruges dette til at rydde op i en rodet historie, før du fusionerer en funktionsgren til master
.,
for At starte et interaktivt rebasing session, passerer i
mulighed for at git rebase
kommando:
git checkout feature git rebase -i master
Dette vil åbne et tekstredigeringsprogram for at vise alle begår, som er ved at blive flyttet:
pick 33d5b7a Message for commit #1 pick 9480b3d Message for commit #2 pick 5c67e61 Message for commit #3
Denne liste definerer præcis, hvad filialen vil se ud efter rebase er udført. Ved at ændre kommandoen pick
og / eller genbestille posterne, kan du få filialens historie til at se ud som hvad du vil., For eksempel, hvis 2nd begå løser et lille problem i den 1st begå, kan du komprimere dem til en samlet begå med fixup
kommando:
pick 33d5b7a Message for commit #1 fixup 9480b3d Message for commit #2 pick 5c67e61 Message for commit #3
Når du gemme og lukke filen, Git vil udføre rebase i henhold til dine anvisninger, hvilket resulterer i projektets historie, der ligner følgende:
at Fjerne ubetydelige begår som denne gør din feature ‘ s historie meget lettere at forstå. Dette er noget, som git merge
simpelthen ikke kan gøre.,
den gyldne regel om Rebasing
Når du forstår, hvad rebasing er, er det vigtigste at lære, hvornår man ikke skal gøre det. Den gyldne regel af git rebase
er at aldrig bruge den på offentlige filialer.
For eksempel, så tænk på hvad der ville ske, hvis du omgjort master
på din feature
branch:
Den rebase flytter alle begår i master
på spidsen af feature
. Problemet er, at dette kun skete i dit lager., Alle de andre udviklere arbejder stadig med originalen master
. Da rebasing resulterer i helt nye begår, Git vil mene, at din master
branch ‘ s historie har afveget fra alle andres.
Den eneste måde at synkronisere de to master
filialer er at flette dem sammen igen, hvilket resulterer i en ekstra fusionere begå og to sæt begår, der indeholder de samme ændringer (de originale, og dem fra din omgjort filial). Det er overflødigt at sige, at dette er en meget forvirrende situation.,
så før du kører git rebase
, spørg altid dig selv, ” er der nogen der kigger på denne gren?”Hvis svaret er ja, skal du tage hænderne fra tastaturet og begynde at tænke på en ikke-destruktiv måde at foretage dine ændringer på (f.eks. kommandoen git revert
). Ellers er du sikker på at omskrive historien så meget som du vil.
Kraft-at Skubbe
Hvis du prøver at skubbe den omgjort master
branch tilbage til en remote repository, Git vil forhindre dig fra at gøre det, fordi det er i modstrid med den eksterne master
filial., Men, du kan tvinge tryk for at gå gennem ved at passere --force
flag, som så:
# Be very careful with this command! git push --force
Dette overskriver den eksterne master
filial for at matche det omgjort en fra dit arkiv og gør tingene meget forvirrende for resten af dit team. Så vær meget forsigtig med kun at bruge denne kommando, når du ved nøjagtigt, hvad du laver.
en af de eneste gange, du skal tvinge, er, når du har udført en lokal oprydning, efter at du har skubbet en privat funktionsgren til et eksternt lager (f.eks., Det er som at sige, ” Ups, jeg ønskede ikke rigtig at skubbe den originale version af funktionsgrenen. Tag den nuværende i stedet.”Igen er det vigtigt, at ingen arbejder ud af forpligtelserne fra den originale version af funktionsgrenen.
Walorkflo.Walalkthrough
Rebasing kan indarbejdes i din eksisterende Git workorkflo. så meget eller så lidt som dit team er komfortabel med. I dette afsnit vil vi se på de fordele, som rebasing kan tilbyde på de forskellige stadier af en funktions udvikling.,
det første trin i enhver arbejdsgang, der udnytter git rebase
er at oprette en dedikeret gren for hver funktion. Dette giver dig den nødvendige filial struktur for sikkert at bruge rebasing:
Lokale Oprydning
En af de bedste måder til at indarbejde rebasing ind i din arbejdsgang er at rydde op i det lokale, i-fremskridt funktioner. Ved periodisk at udføre en interaktiv rebase kan du sikre dig, at hver forpligtelse i din funktion er fokuseret og meningsfuld., Dette giver dig mulighed for at skrive din kode uden at bekymre dig om at bryde den op i isolerede forpligtelser—du kan rette den op efter faktum.
Når du ringer git rebase
, har du to muligheder for den nye base: funktionens overordnede gren (f.eks. master
), eller en tidligere commit i din funktion. Vi så et eksempel på den første mulighed i det interaktive Rebasing-afsnit. Sidstnævnte mulighed er rart, når du kun behøver at ordne de sidste par forpligtelser. For eksempel begynder følgende kommando en interaktiv rebase af kun de sidste 3-forpligtelser.,
git checkout feature git rebase -i HEAD~3
Ved at angive HEAD~3
som den nye base flytter du faktisk ikke filialen—du skriver bare interaktivt de 3 forpligtelser, der følger den. Bemærk, at dette ikke vil inkorporere opstrømsændringer ifeature
forgreningen.
Hvis du ønsker at re-skrive det hele funktionen ved hjælp af denne metode, git merge-base
kommando kan være nyttigt at finde den oprindelige bunden af feature
filial., Følgende returnerer begå ID for den oprindelige base, som du derefter kan videregive til git rebase
:
git merge-base feature master
Denne brug af interaktive rebasing er en god måde at introducere git rebase
ind i din arbejdsgang, da det kun påvirker de lokale afdelinger. Det eneste, andre udviklere vil se, er dit færdige produkt, som skal være en ren, let at følge funktionen gren historie.
men igen fungerer dette kun for private funktionsgrene., Hvis du samarbejder med andre udviklere via den samme funktionsgren, er den gren offentlig, og du har ikke lov til at omskrive sin historie.
der er ingen git merge
alternativ til oprydning af lokale forpligtelser med en interaktiv rebase.
Indarbejde Opstrøms Ændringer I en Funktion
I den Konceptuelle Overblik afsnit, vi så, hvordan en funktion filial kan optage opstrøms ændringerne fra master
enten ved hjælp af git merge
eller git rebase
., Fletning er en sikker mulighed, der bevarer hele dit arkiv, mens rebasing opretter en lineær historie ved at flytte din funktionsgren til spidsen af master
.
denne brug af git rebase
svarer til en lokal oprydning (og kan udføres samtidigt), men i processen inkorporerer den disse opstrøms-forpligtelser fra master
.
Husk, at det er helt lovligt at rebase på en ekstern gren i stedet for master
., Dette kan ske, når du samarbejder om den samme funktion med en anden udvikler, og du skal indarbejde deres ændringer i dit arkiv.,
For eksempel, hvis du og en anden udvikler ved navn John tilføjet forpligter sig til at feature
gren, dit arkiv kan se ud som følgende efter at hente fjernbetjeningen feature
gren fra John ‘ s repository:
Du kan løse dette gaffel nøjagtig samme måde, som du integrere opstrøms ændringerne fra master
: enten samle dine lokale feature
med john/feature
eller rebase din lokale feature
på spidsen af john/feature
.,
Bemærk, at denne rebase ikke overtræder den Gyldne Regel for Rebasing, fordi kun din lokale feature
begår, er at blive flyttet—alt før der er uberørt. Det er som at sige, “tilføj mine ændringer til, hvad John allerede har gjort.”I de fleste tilfælde er dette mere intuitivt end at synkronisere med fjerngrenen via en merge commit.
Som standard git pull
kommando udfører en brevfletning, men du kan tvinge den til at integrere eksterne gren med en rebase ved at overføre det de --rebase
option.,
gennemgang af en funktion med en Pull-anmodning
Hvis du bruger pull-anmodninger som en del af din kodegennemgangsproces, skal du undgå at brugegit rebase
efter oprettelse af pull-anmodningen. Så snart du foretager pull-anmodningen, vil andre udviklere se på dine forpligtelser, hvilket betyder, at det er en offentlig filial. Re-skrive sin historie vil gøre det umuligt for Git og dine holdkammerater til at spore eventuelle opfølgende commits tilføjet til funktionen.
eventuelle ændringer fra andre udviklere skal indarbejdes med git merge
i stedet for git rebase
.,af denne grund er det normalt en god ide at rydde op i din kode med en interaktiv rebase, før du sender din pull-anmodning.
Integrere en Godkendt Funktion
Efter at en funktion er blevet godkendt af dit team, har du mulighed for at rebasing funktionen på spidsen af master
gren, før du bruger git merge
for at integrere funktionen i de vigtigste kode base.,
Dette er en lignende situation, til at indarbejde opstrøms ændringer i en funktion gren, men da du ikke lov til at re-skrive begår i master
gren, har du til sidst bruge git merge
for at integrere funktionen. Ved at udføre en rebase før fusionen er du dog sikker på, at fusionen vil blive videresendt hurtigt, hvilket resulterer i en perfekt lineær historie. Dette giver dig også chancen for at s .uash eventuelle opfølgende forpligtelser tilføjet under en pull anmodning.,
Hvis du ikke er helt fortrolig med git rebase
, kan du altid udføre den rebase i en midlertidig filial. På den måde, hvis du ved et uheld ødelægger din funktions historie, kan du tjekke den originale gren og prøve igen. For eksempel:
git checkout feature git checkout -b temporary-branch git rebase -i master # git checkout master git merge temporary-branch
resum And
og det er alt hvad du virkelig behøver at vide for at begynde at rebasing dine grene., Hvis du foretrækker en ren, lineær historie uden unødvendige fusionere begår, du skal nå for git rebase
i stedet for git merge
, når integrere ændringer fra en anden gren.
På den anden side, hvis du vil bevare projektets komplette historie og undgå risikoen for at omskrive offentlige forpligtelser, kan du holde dig til git merge
. Enten mulighed er helt gyldig, men i det mindste nu har du mulighed for at udnytte fordelene ved git rebase
.
Skriv et svar