Ja jau kādu laiku lietojat Git, iespējams, esat saskāries ar vēsturi, kas pilna ar bezjēdzīgiem commit, "WIP" ziņojumiem, ātrajiem testiem vai pat tukšiem commit, kas izveidoti tikai, lai aktivizētu āķi vai cauruļvadu. Tajā brīdī jūs aplūkojat žurnālu un domājat: "Neviens to nevar saprast"Labā ziņa ir tā, ka jūs neesat viens: tas notiek ar mums visiem, un tieši tāpēc ir nepieciešams atbalsts. git rebase.
Interesanti ir tas, ka, pareizi lietojot, git rebase ļauj "attīrīt" izmaiņu vēsturiPadariet to lineāru, bez trokšņiem un daudz vieglāk pārskatāmu. Varat dzēst testa izmaiņu ierakstus (commit), apvienot vairākus vienā, mainīt to secību, labot izmaiņu ziņojumus un pat noņemt izmaiņas no attālās vadības, izmantojot piespiedu sūtīšanas komandu. Apskatīsim ar konkrētiem piemēriem, kā izmantot atkārtotu bāzi, lai pārveidotu savu vēsturi no pilnīga haosa par kaut ko organizētu un lasāmu.
Kas īsti ir Git Rebase un kāpēc tas ietekmē vēsturi?
Kad mēs runājam par apdzīšanu, mēs burtiski runājam par mainīt atzara sākuma punktuGit paņem izmaiņu ierakstus (commit) no jūsu atzara un tos pa vienam "atveido" citā bāzē (parasti atzarā galvenais vai atjauninātu attālo filiāli). Tas ir tā, it kā jūs būtu atgriezies laikā un sācis darbu no cita faila, bet saglabājis izmaiņas.
Iedomājieties, ka jūsu projekta galvenajā zarā ir šis stāsts: A – B – CJūs izveidojat funkcionalitātes atzaru un pēc tam veicat divas izmaiņas: D-ETikmēr, galvenokārt, kāds pievieno jaunu commit FBez atkārtotas bāzes izveides jūsu zari izskatītos apmēram šādi:
A---B---C---F (main)
A---B---C---D---E (feature)
Ja veicat klasisku sava funkciju atzara apvienošanu ar galveno atzaru, iegūstat papildu apvienošanas izmaiņu (commit), kas bieži vien ģenerē sapinusies vēsture ar vairākām sakrustotām līnijām. Savukārt, izmantojot atkārtotu bāzi, Git ņem jūsu izmaiņas D un E un atkārtoti piemēro tās F:
A---B---C---F---D'---E' (feature reescrita)
Tie D' un E' Šie nav gluži tādi paši grozījumi kā D un E: tie ir "kopijas" ar jauniem identifikatoriem (hešiem). Tāpēc mēs sakām "rebase". pārraksta vēsturiRezultāts ir lineārāks žurnāls, bez starpposma apvienošanas grozījumiem, kas tikai rada troksni.

Kāpēc jums vajadzētu būt tīrai izmaiņu vēsturei
Organizēts ieraksts nav tikai estētikas jautājums. Tīrs žurnāls ievērojami atvieglo ikdienas darbu.Jūs varat uzreiz redzēt, kas tika darīts, kad un kāpēc, bez nepieciešamības pārlēkt cauri tukšiem apvienošanas grozījumiem vai bezkonteksta "ātro labojumu" ziņojumiem.
Kad zari tiek apvienoti, pastāvīgi apvienojoties no galvenās zara, rodas virkne izmaiņu, piemēram, “Apvienot zaru 'galveno' ar funkciju-x”, kas Viņi nesniedz patiesu informāciju par koda izmaiņāmTas sarežģī tādus uzdevumus kā:
- Atrodiet izmaiņu, kurā tika ieviesta kļūda, izmantojot rīki failu salīdzināšanaijo vēsture ir pilna ar nebūtiskām apvienošanām.
- Pārskatīt pieprasījumusjo, lai redzētu, kas patiesībā mainījās, ir jāpārlec starp liekiem grozījumiem.
- Funkcijas evolūcijas izpratneit īpaši, ja tas ir izstrādāts daudzu mazu testa izmaiņu laikā.
Git rebase ir ideāls rīks, lai "noplīsētu" visu šo troksni pirms filiāles kopīgošanas ar pārējo komandu. Tas ir kā mazgāt savu vēsturi veļas mašīnā.Jūs saglabājat svarīgās izmaiņas, labi grupētas un ar skaidriem vēstījumiem.
Galvenās atšķirības starp git apvienošanu un git atkārtotu bāzi
Lai pilnībā izprastu, ko jūs darāt, izmantojot atkārtotu bāzi, ir vērts salīdzināt tās darbību ar git sapludinātAbi kalpo izmaiņu integrēšanai, taču dažādos veidos un ar būtiskām sekām ierakstam.
ar apvienotGit izveido jaunu apvienošanas commit, kuram ir divi vecāki: jūsu atzara gals un tā atzara gals, ar kuru jūs apvienojaties. Iegūtā vēsture precīzi saglabā sākotnējo izmaiņu secībuBet tas var beigties ar paralēlām atzarām un saplūšanu.
ar pārvērtētTā vietā, lai izveidotu apvienošanas izmaiņu kopumu (commit), Git ņem jūsu izmaiņas un piemēro tās jaunajai datubāzei pa vienai. Tas ģenerē jauni grozījumi ar jauniem hešiempat ja koda izmaiņas ir vienādas.
Praksē:
- Apvienot Tas saglabā vēsturi tieši tādu, kāda tā notika, ar visām tās savstarpējām saitēm un apvienojumiem.
- Atkārtot Tas ģenerē lineāru un tīru vēsturi, it kā viss būtu noticis taisnā līnijā.
Izvēle nav "viens ir labāks par otru", bet gan Kurai situācijai katrs no tiem ir piemērotāks?Lai apvienotu jau koplietotās un slēgtās filiāles, apvienošana parasti ir drošāka. Lai uzturētu lokālās darbīgās filiāles sakārtotas vai pirms pieprasījuma atvēršanas, ieteicams veikt atkārtotu bāzi.

Gadījumi, kad pārbāze izceļas: filiāļu atjaunināšana un pulēšana
Ir divi scenāriji, kuros lielākā daļa izstrādātāju katru dienu izmanto atkārtotu bāzi: uzturiet savu darba filiāli atjauninātu ar galveno y sakopt commit pirms to kopīgošanasApskatīsim tos sīkāk.
Atjauniniet savu funkciju atzaru ar jaunākajām izmaiņām no galvenās sadaļas
Jūs strādājat pie jaunas funkcijas savā filiālē, bet tikmēr jūsu kolēģi joprojām veic izmaiņas. galvenaisJa vēlaties integrēt izmaiņas, viena no iespējām ir:
git checkout tu-rama-feature
git merge main
Tas darbojas, bet katru reizi sinhronizējot, tiek ģenerēts apvienošanas apstiprinājums, kas galu galā rada problēmas. vēsture, kas pilna ar atkārtotām apvienošanāmTomēr, ja jūs to darāt:
git checkout tu-rama-feature
git rebase main
Git pārvietos jūsu veiktās izmaiņas virs pēdējā main stāvokļa, it kā jūs būtu sākuši filiāli pēc šīm izmaiņām. Jūs saņemsiet lineāra vēsture bez starpposma apvienošanas apstiprinājumiemun pārskats būs skaidrāks.
Notīriet savus commit failus pirms pieprasījuma atvēršanas
Ļoti bieži, ka funkcijas izstrādes laikā rodas tādi izmaiņu pieprasījumi kā "typo labojums", "pipeline testēšana", "vairāk pieteikšanās izmaiņu" utt. Tas ir labi, kamēr strādājat, bet Tā nav tāda vēsture, kādu vēlaties parādīt. kad atverat PR.
Interaktīva atkārtota bāze ļauj jums reorganizēt un grupēt šos grozījumus uz kaut ko loģiskāku. Piemēram, šī vietā:
- WIP: añadir login
- Más cambios login
- Corregir tests login
- Arreglar typo variable
Jūs varat iegūt vienu, labi aprakstītu commit:
- Añadir funcionalidad completa de login de usuario con tests
Šī vēstures "pulēšana" ievērojami atvieglo tās izpratni recenzentiem. ko katrs commits dod ieguldījumam un vienkāršo problēmu novēršanu nākotnē.
Interaktīva pārbūve vēstures pārrakstīšanai
Pārbāzes pamatversijā jūsu izmaiņas vienkārši tiek pārvietotas uz citu bāzi. Taču galvenais dārgakmens ir interaktīva virsbāze, kas atver redaktoru ar nesen veikto izmaiņu sarakstu, lai jūs varētu izlemt, ko darīt ar katru no tām.
Tipisks veids, kā to sākt, ir norādīt, cik izmaiņu atkārtojumus vēlaties "pieskarties" no pašreizējās HEAD daļas. Piemēram:
git rebase -i HEAD~6
Šī komanda norāda Git: “paņemiet pēdējos 6 grozījumus no šīs filiāles un sagatavojiet man interaktīvu atkārtotu bāzi.” Git atvērs jūsu noklusējuma redaktoru (Vim, Nano, VS Code utt.) ar kaut ko līdzīgu:
pick 7ed9c6e update version
pick ecb7ef3 empty commit 1
pick a323615 empty commit 2
pick 2c3d41d empty commit 3
pick d53c00f empty commit 4
pick 22dcc79 empty commit 5
# Pārveidot 549dd76..22dcc79 uz 549dd76 (6 komandas)
#
# Komandas:
# p, izvēlēties = izmantot commit
# r, pārfrāzēt = Izmantojiet commit, bet rediģējiet ziņojumu
# e, rediģēt = Izmantojiet commit un stop, lai to modificētu
# s, skvošs = apvienot iepriekšējā commit
# f, labojums = līdzīgi kā skvošs, bet atmetot ziņojumu
# x, izpildīt = izpildīt čaulas komandu
# b, pārtraukums = pārtraukt pārbāzēt šeit
# d, nomest = dzēst izdarīt
#…
Pievērsiet uzmanību vienai svarīgai detaļai: Šajā failā esošā secība ir apgriezta tam, ko redzat git žurnālā.Failā pirmais norādītais komits (7ed9c6e) ir vecākais no sešiem, bet pēdējais (22dcc79) ir jaunākais. Tas ir svarīgi, lai izvairītos no neskaidrībām, dzēšot vai pārkārtojot komit.
Noņemt testa vai tukšus izmaiņu ierakstus no lokālās vēstures
Pieņemsim, ka, lai pārbaudītu Git āķi, jūs veicat tukšas izmaiņas (commit) ar opciju –atļaut tukšumu. Piemēram:
git commit -m "commit with no changes" --allow-empty
Šī opcija ļauj izveidot izmaiņu failu pat tad, ja failos nav veiktas nekādas izmaiņas, kas ir noderīgi testēšanai, bet Tas pieblīvē vēsturi ar grozījumiem, kuriem nav reālas vērtības.Iedomājieties, ka jūsu žurnāls izskatās šādi:
git log --pretty=oneline --abbrev-commit
Un jūs saņemat:
22dcc79 (HEAD -> main, origin/main, origin/HEAD) empty commit 5
d53c00f empty commit 4
2c3d41d empty commit 3
a323615 empty commit 2
ecb7ef3 empty commit 1
7ed9c6e update version
Šajā scenārijā vēlaties paturēt tikai noderīgo "update version" commit un noņemt visus pārējos. tukšs commit kas bija tikai testi. Lai to izdarītu, pēdējos 6 izmainītajos failos palaidiet interaktīvo atkārtoto bāzi:
git rebase -i HEAD~6
Redaktors atveras ar 6 komentiem. Jūsu mērķis ir noņemt rindas, kas atbilst tukšajiem komitiem. Tas nozīmē, ka jūs atstājat tikai kaut ko līdzīgu šim:
pick 7ed9c6e update version
# Pārveidot 549dd76..22dcc79 uz 549dd76 (6 komandas)
# … pārējie komentāri …
Kā norādīts paša faila palīdzības sadaļā, Ja izdzēsīsiet rindu, šī commit pazūd no vēstures. Jaunajā, pārrakstītajā versijā, saglabājot un aizverot redaktoru, Git atveidos tikai "update version" commit un pārējos atmetīs.
Jauna stāsta augšupielāde pakalpojumā Origin: piespiedu pārsūtīšanas izmantošana
Līdz šim visas atkārtotās bāzes izmaiņas ir veiktas jūsu lokālajā repozitorija kopijā. Ja vēlaties, lai šī tīrīšana tiktu atspoguļota arī attālajā repozitorijā (piemēram, izcelsme/galvenais), jums būs jāpārraksta attālā vēsture ar jauno.
Tas tiek darīts ar piespiedu grūdiensBieži vien to norāda, izmantojot "+" zīmi pirms filiāles nosaukuma, veicot šādu darbību:
git push origin +main
Šī pluszīme norāda Git, ka Ignorēt vēstures atšķirības un pārrakstīt attālo atzaru ar jūsu pārrakstīto versiju. Ja jūs vienkārši mēģinātu darīt:
git push origin main
Git brīdinātu, ka jūsu lokālā vēsture nav tiešs attālās vēstures pēctecis (jo esat pārrakstījis grozījumus ar rebase) un noraidītu spiedienu, lai izvairītos no datu zuduma.
Ir svarīgi saprast, ka pēc šī piespiedu grūdiena, Dzēstās izmaiņas vairs nebūs pieejamas no sākotnējās/galvenās mapes.Tie joprojām var būt atkārtoti publicēti emuāros vai citu kolēģu lokālajās kopijās, taču praktisku apsvērumu dēļ jūs esat iztīrījis attālās vēstures ierakstus.
Nopietns brīdinājums: koplietoto zaru pārrakstīšana nav spēle
Vēstures pārrakstīšana izklausās lieliski, lai visu sakārtotu, taču tai ir būtiskas sekas: veidojot jaunus izmaiņu ierakstus ar jauniem jaucējkociņiem, Jūs atmetat ikvienu, kurš savu darbu jau bija balstījis uz vecajiem grozījumiem.Tāpēc pastāv slavenais zelta likums:
Nepārveidojiet filiāļu bāzi, kuras jau ir koplietotas un aktīvi izmanto citi.
Praksē tas nozīmē, ka atkārtotu bāzi var droši izmantot, ja:
- Vietējās filiāles ko vēl neesat publicējis vai ko izmantojat tikai jūs.
- Jaunākās saistības tie, no kuriem tu zini, ka neviens cits vēl nav atkarīgs.
Un tā ir diezgan slikta ideja to darīt par:
- galvenā, izstrādātāja vai jebkura “oficiāla” filiāle no krātuves, kas kalpo par pamatu vairākiem cilvēkiem.
- Koplietotas darba filiāles kur vairāk nekā viens izstrādātājs veic izmaiņas.
Ja pārrakstīsiet koplietotās filiāles vēsturi un pēc tam veiksiet piespiedu grūdienu, citi komandas biedri to atklās Tās filiāles norāda uz grozījumiem, kas vairs nepastāv attālajā serverī.Viņiem būs jāveic sarežģītākas darbības (piemēram, jāpārveido jaunā vēsture vai jāveic atiestatīšana), lai novērstu problēmu.
Spēka grūdiens: labāk ar drošības jostu
Daudzos gadījumos pēc atkārtotas bāzes izveides būs jāpiespiež spiediens. Klasiskā iespēja ir:
git push --force origin tu-rama
Tomēr šis variants pārraksta visu tālvadības pultī bez jautāšanas. Lai izvairītos no nejaušas citu cilvēku darba pārrakstīšanas, Git piedāvā daudz labāku iespēju: –spēks ar nomu.
Kad jūs to darāt:
git push --force-with-lease origin tu-rama
Git vispirms pārbauda, vai Tālvadības pults joprojām ir tādā stāvoklī, kādā jūs to uzskatījāt. Kad veicāt pēdējo izvilkšanu vai izgūšanu. Ja tiek konstatēts, ka kopš tā laika kāds ir ievietojis jaunus izmaiņu izmaiņu izmaiņu izmaiņu izmaiņu izmaiņu izmaiņu izmaiņu izmaiņu izmaiņu izmaiņu izmaiņu izmaiņu gadījumā.
Ideja ir apvienot atkārtotu bāzes veidošanu un spēka stumšanu, vienmēr saglabājot vēsu prātu: tikai filiālēs, kuras jūs kontrolējat un, kad vien iespējams, izmantojot piespiedu nomu kā papildu drošības slāni.
Ko darīt, ja pārbāzes izveide noiet greizi: reblog glābiņš
Tas ir noticis ar mums visiem: jūs sākat interaktīvu pārbāzi, nejauši kaut ko izdzēšat vai maināt, nepareizi atrisināt konfliktu un pēkšņi... Šķiet, ka esi zaudējis daļu darbaPirms krītat panikā, atcerieties, ka Git ir lielisks palīgs: git reblog.
Reblog ir lokāls ieraksts par visām HEAD kustībām: jauniem grozījumiem, atiestatījumiem, atkārtotām bāzēm, apvienojumiem… Pateicoties tam, jūs varat atrast, kur atradās jūsu atzars, pirms to sabojājāt, un atgriezties šajā punktā ar stingru atiestatīšanu.
Tipiska plūsma būtu šāda:
git reflog
Tur jūs redzēsiet ierakstu sarakstu ar kaut ko līdzīgu:
abc1234 HEAD@{0}: rebase terminado
def5678 HEAD@{1}: checkout: moving from main to main
...
Jūs norādāt, kurā komitājā bijāt pirms atkārtotas bāzes izveides (piemēram, def5678) un jūs atgriežaties pie viņa ar:
git reset --hard def5678
Tādā veidā Jūs pilnībā atceļat pārklājumu un jūs atgriežaties iepriekšējā stāvoklī. Varat arī pārtraukt notiekošu atkārtotu bāzes izveidi (ja atrodaties procesa vidū un vēl neesat pabeidzis), vienkārši izmantojot:
git rebase --abort
Šī komanda atstāj jūsu atzaru tādu, kāds tas bija tieši pirms pašreizējās pārbāzes izveides, kas ir ideāli piemērots, ja parādās nevēlami konflikti vai redzat, ka nav īstais laiks turpināt.
Git pull vs git pull – rebase: mazas atšķirības, liela ietekme
Vēl viens aspekts, kas bieži rada šaubas, ir atšķirība starp git pull normāls un git pull --rebaseAbi atjaunina jūsu lokālo filiāli no attālā servera, taču to dara dažādos veidos.
Kad jūs skrienat:
git pull
Git veic divus soļus: git fetch lai veiktu izmaiņas no tālvadības pults un pēc tam a git sapludināt lai tos apvienotu ar jūsu pašreizējo atzaru. Tas var radīt papildu apvienošanas izmaiņu ierakstu (commit), ja virs attālās atzara ir lokālas izmaiņas, kas atkal vēsture ar nevajadzīgām apvienošanām.
Tomēr, ja jūs palaižat:
git pull --rebase
Git veic ielādi un pēc tam Replikējiet lokālos izmaiņu ierakstus (commit) atjauninātajā versijā attālajā ierīcē.Rezultāts ir līdzīgs tam, ja jūs to būtu izdarījis git fetch pēc tam git rebase origin/mainun uztur tīrāku, lineārāku vēsturi.
Tāpēc daudzas komandas konfigurē Git, lai, veicot izvilkumus, pēc noklusējuma izmantotu atkārtotu bāzi. Tas ir vienkāršs veids, kā izvairīties no automātiskas apvienošanas apstiprināšanas kas nedod lielu ieguldījumu.
Failu vai attēlu dzēšana no vēstures: vispārīga ideja
Dažreiz problēma nav neglīts apstrīdējums, bet gan fails, kuram nekad nevajadzēja nonākt repozitorijānepareizs attēls, nepareizi akreditācijas dati, lieli faili utt. Rodas kārdinājums doties uz GitHub un meklēt miskastes ikonu, bet, ja tā šķiet atspējota un rāda ziņojumus, piemēram, "jums jābūt atzarā", tas ir tāpēc, ka GitHub neļauj šādi dzēst vēsturi..
Pareizais veids parasti ietver vēstures pārrakstīšanu no jūsu lokālā datora (ar interaktīvu atkārtotu bāzi vai tādiem rīkiem kā git filter-repo) un pēc tam veiciet piespiedu nosūtīšanu. GitHub Desktop var arī pārvaldīt atzarus un veikt izmaiņas, taču darbība pilnībā noņemt failu no visiem grozījumiem Tas ietver vēstures pārrakstīšanu līdzīgā veidā, kā mēs šeit redzam.
Īsāk sakot, ja augšupielādējat nepareizu attēlu vai sensitīvu failu un vēlaties, lai tas "pazustu" no vēstures, ar tā vienkāršu dzēšanu pēdējā izmaiņu reizē nepietiek: Izvēles, kurās tas tika ieviests, ir jāpārraksta. un tad piespiediet grūdienu. Tā ir delikāta darbība, un tā jāveic mierīgi un sadarbībā ar komandu.
Praktiska plūsma apdzīšanas praktizēšanai, neko nesalaužot
Labākais veids, kā apgūt apdzīšanas prasmes, ir praktizēties kontrolētā vidē, nebaidoties traucēt citu darbu. Vienkārša secība būtu šāda:
- Izveidojiet jaunu filiāli no galvenās lapas ar git checkout -b my-branch-tests.
- Veiciet vairākus nelielus izmaiņu ierakstus (tie var būt triviālas izmaiņas vai testa faili).
- Simulējiet galveno progresu, veicot jaunus grozījumus (vai lūdzot kādam citam to izdarīt).
- Dodieties atpakaļ uz savu testa filiāli un palaidiet git rebase main lai redzētu, kā jūsu izdarītās izmaiņas tiek pārvietotas.
- Prueba un git rebase -i GALVENĀ~3 lai apvienotu, pārdēvētu vai dzēstu jebkuru no jaunākajiem grozījumiem.
Ar šo vingrinājumu jūs redzēsiet, kā Mainiet vēsturi pirms un pēcKā Git reaģē uz konfliktiem un kā, izmantojot reflog, var atgriezties pie iepriekšējiem stāvokļiem, ja nepieciešams. Jo vairāk prakses jums ir lokāli, jo pārliecinātāki jūs jutīsieties, pielietojot šīs metodes reālos projekta atzaros.
Git pārbāzes apgūšana ļauj pārveidot haotisku vēsturi, kas pilna ar tukšiem grozījumiem, nevajadzīgām apvienošanām un bezjēdzīgiem ziņojumiem, skaidrā un lasāmā nozīmīgu izmaiņu secībā. Izmantojot interaktīvu pārbāzi, dzēšot testa grozījumus, grupējot izkliedēto darbu, lineāri atjauninot filiāles un paļaujoties uz tādiem rīkiem kā reblogošana un piespiedu nosūtīšana ar `--force-with-lease`, jūs varat uzturēt savu repozitoriju daudz veselīgākā un profesionālākā stāvoklī, ja vien atceraties šīs metodes piemērot tikai filiālēm, kas atrodas jūsu kontrolē, un pirms koplietotās vēstures pārrakstīšanas paziņot komandai.