Git rebase: wszystko, co musisz wiedzieć
Opublikowany: 2022-12-15 Polecenie Git rebase
łączy dwie gałęzie kodu źródłowego w jedną. Polecenie merge
Git również to robi. Wyjaśniamy, co robi rebase
, jak jest używany i kiedy zamiast tego używać merge
.
Eksplozja Gita
Co to jest scalanie Git?
Co to jest rebase Git?
Jak zmienić bazę na inną gałąź
Git Rebase vs. Merge: Którego powinieneś użyć?
Rebazować, czy nie rebazować?
Eksplozja Gita
Sfrustrowany innymi systemami kontroli wersji oraz ich powolnymi aktualizacjami i zobowiązaniami, Linus Torvalds, znany z jądra Linuksa, odłożył miesiąc w 2005 roku na napisanie własnego. Nazwał go Git.
Witryny takie jak GitHub, GitLab i BitBucket symbiotycznie promowały Git i czerpały z niego korzyści. Obecnie Git jest używany na całym świecie, a 98 procent z 71 tysięcy respondentów w ankiecie z 2022 roku używa Git jako systemu kontroli wersji.
Jedną z głównych decyzji projektowych Gita była szybkość. W szczególności praca z oddziałami musiała przebiegać jak najszybciej. Gałęzie są podstawową częścią systemów kontroli wersji. Repozytorium projektu będzie miało gałąź główną lub główną. To tutaj znajduje się baza kodu projektu. Rozwój, taki jak nowe funkcje, odbywa się w wydzielonych gałęziach bocznych. To powstrzymuje pracę wykonywaną w gałęziach przed zepsuciem gałęzi głównej i pozwala na równoczesny rozwój w różnych częściach bazy kodu.
Po zakończeniu rozwoju w gałęziach bocznych zmiany są przenoszone do gałęzi głównej poprzez połączenie gałęzi rozwojowej z gałęzią główną. W innych wersjach systemów kontroli praca z oddziałami była trudna i kosztowna obliczeniowo. Praca z gałęziami w Git jest bardzo szybka i bardzo lekka. To, co kiedyś było żmudnym i często unikanym ćwiczeniem w innych systemach, stało się trywialne w Git.
Polecenie Git rebase
to kolejny sposób przenoszenia zmian z jednej gałęzi do drugiej. Polecenia merge
i rebase
mają podobne cele, ale osiągają swoje cele na różne sposoby i dają nieco inne wyniki.
Co to jest scalanie Git?
Do czego służy polecenie merge
Git? Załóżmy, że utworzyłeś gałąź o nazwie dev-branch
, aby pracować nad nową funkcją.
Dokonujesz kilku zatwierdzeń i testujesz nową funkcję. Wszystko działa dobrze. Teraz chcesz wysłać nową funkcję do gałęzi master
. Musisz być w gałęzi master
, aby połączyć z nią inną.
Możemy upewnić się, że jesteśmy w gałęzi master
, wyraźnie ją sprawdzając przed połączeniem.
git mistrz kasy
Możemy teraz powiedzieć Gitowi, aby dev-branch
deweloperską z bieżącą gałęzią, która jest gałęzią master
.
git merge dev-branch
Nasza merge
jest dla nas zakończona. Jeśli wyewidencjonujesz gałąź master
i skompilujesz ją, będzie ona zawierała nowo opracowaną funkcję. To, czego faktycznie dokonał Git, to połączenie trójstronne. porównuje najnowsze zatwierdzenia w gałęzi master
i dev-branch
deweloperskiej oraz zatwierdzenie w gałęzi master
bezpośrednio przed utworzeniem dev-branch
deweloperskiej. Następnie wykonuje zatwierdzenie w gałęzi master
.
Scalanie jest uważane za nieniszczące, ponieważ niczego nie usuwa i nie zmienia żadnej historii Git. dev-branch
nadal istnieje i żadne z poprzednich zatwierdzeń nie zostało zmienione. Tworzone jest nowe zatwierdzenie, które przechwytuje wyniki trójstronnego scalania.
Po scaleniu nasze repozytorium Git wygląda jak oś czasu z alternatywną linią rozgałęziającą się i powracającą do głównej osi czasu.
dev-branch
została włączona do gałęzi master
.
Jeśli masz wiele oddziałów w jednym projekcie, historia projektu może być myląca. Dzieje się tak często, gdy projekt ma wielu współpracowników. Ponieważ wysiłek programistyczny dzieli się na wiele różnych ścieżek, historia rozwoju jest nieliniowa. Rozplątanie historii zatwierdzeń staje się jeszcze trudniejsze, jeśli gałęzie mają własne gałęzie.
Pamiętaj, że jeśli masz niezatwierdzone zmiany w gałęzi master
, musisz coś z nimi zrobić, zanim będziesz mógł coś z nią scalić. Możesz utworzyć nową gałąź i zatwierdzić tam zmiany, a następnie wykonać scalenie. Następnie musiałbyś scalić swoją tymczasową gałąź z powrotem w gałąź główną.
To działa, ale Git ma polecenie, które osiąga to samo, bez konieczności tworzenia nowych gałęzi. Komenda stash
przechowuje dla ciebie niezatwierdzone zmiany i pozwala ci przywołać je z powrotem za pomocą stash pop
.
Użyłbyś ich w ten sposób:
chować na potem git merge dev-branch schowek pop
Efektem końcowym jest scalona gałąź z przywróconymi niezapisanymi zmianami.
Co to jest rebase Git?
Polecenie Git rebase
realizuje swoje cele w zupełnie inny sposób. Pobiera wszystkie zatwierdzenia z gałęzi, na której zamierzasz zmienić bazę, i odtwarza je na końcu gałęzi, na której się opierasz.
Biorąc nasz poprzedni przykład, zanim wykonaliśmy jakąkolwiek akcję, nasze repozytorium Git wygląda tak. Mamy gałąź o nazwie dev-branch
i chcemy przenieść te zmiany do gałęzi master
.
Po rebase
wygląda to jak pojedyncza, całkowicie liniowa oś czasu zmian.
dev-branch
została usunięta, a zatwierdzenia w dev-branch
zostały dodane do gałęzi master. Końcowy wynik jest taki sam, jak gdyby zatwierdzenia w dev-branch
deweloperskiej zostały faktycznie przypisane bezpośrednio do gałęzi master
. Zatwierdzenia nie są po prostu przypinane do gałęzi master
, są „odtwarzane” i dodawane na nowo.
Dlatego polecenie rebase
jest uważane za destrukcyjne. Gałąź rebased nie istnieje już jako oddzielna gałąź, a historia twojego projektu Git została napisana od nowa. Nie możesz później określić, które zatwierdzenia zostały pierwotnie wykonane w dev-branch
.
Pozostawia to jednak uproszczoną, liniową historię. W porównaniu z repozytorium z dziesiątkami, a nawet setkami rozgałęzień i połączeń, czytaniem dziennika Git lub używaniem graficznego interfejsu GUI git do przeglądania wykresu repozytorium, repozytorium oparte na repozytorium jest łatwe do zrozumienia.
Jak zmienić bazę na inną gałąź
Wypróbujmy przykład git rebase
. Mamy projekt z gałęzią o nazwie new-feature
. rebase
tę gałąź na gałęzi master
w ten sposób.
Najpierw sprawdzamy, czy w gałęzi master
nie ma zaległych zmian.
status gita
Sprawdzamy gałąź new-feature
.
git checkout nowa funkcja
Mówimy rebase
, aby zmienił bazę bieżącej gałęzi na gałąź główną.
git rebase master
Widzimy, że mamy jeszcze dwie gałęzie.
gałąź git
Wracamy do gałęzi master
git mistrz kasy
Łączymy gałąź new-feature z gałęzią bieżącą, która w naszym przypadku jest gałęzią master
.
git merge nowa funkcja
Co ciekawe, po ostatecznym połączeniu mamy jeszcze dwa oddziały.
Różnica polega na tym, że teraz głowa gałęzi new-feature
i głowa gałęzi master
są ustawione tak, aby wskazywały na to samo zatwierdzenie, a historia Git nie pokazuje, że kiedyś istniała oddzielna gałąź new-feature
, oprócz etykieta oddziału.
Git Rebase vs. Merge: Którego powinieneś użyć?
To nie jest przypadek rebase
vs. merge
. Oba są potężnymi poleceniami i prawdopodobnie użyjesz ich obu. To powiedziawszy, istnieją przypadki użycia, w których rebase
nie działa tak dobrze. Usuwanie błędów spowodowanych błędami przy użyciu merge
jest nieprzyjemne, ale usuwanie błędów spowodowanych rebase
jest piekielne.
Jeśli jesteś jedynym programistą korzystającym z repozytorium, istnieje mniejsze prawdopodobieństwo, że zrobisz coś katastrofalnego w rebase
. Nadal możesz na przykład zmienić rebase
w niewłaściwym kierunku i rebase
gałęzi głównej na gałąź new-feature
. Aby odzyskać swoją gałąź master
, musisz ponownie rebase
, tym razem z gałęzi z new-feature
do gałęzi master
. To przywróciłoby twoją master
gałąź, choć z dziwnie wyglądającą historią.
Nie używaj rebase
we wspólnych gałęziach, w których inni mogą pracować. Twoje zmiany w repozytorium spowodują problemy dla wielu osób, gdy wypchniesz kod rebase do zdalnego repozytorium.
Jeśli twój projekt ma wielu współtwórców, bezpiecznym rozwiązaniem jest użycie rebase
tylko w lokalnym repozytorium, a nie w publicznych gałęziach. Podobnie, jeśli żądania ściągnięcia stanowią część recenzji kodu, nie używaj rebase
. Lub przynajmniej nie używaj rebase
po utworzeniu żądania ściągnięcia. Inni programiści prawdopodobnie będą patrzeć na twoje zatwierdzenia, co oznacza, że te zmiany są w gałęzi publicznej, nawet jeśli nie znajdują się w gałęzi master
.
Niebezpieczeństwo polega na tym, że zamierzasz rebase
zatwierdzeń, które zostały już wypchnięte do zdalnego repozytorium, a inni programiści mogli już oprzeć pracę na tych zatwierdzeniach. Twoja lokalna rebase
sprawi, że istniejące zatwierdzenia znikną. Jeśli wypchniesz te zmiany do repozytorium, nie będziesz popularny.
Inni współtwórcy będą musieli przejść przez niechlujne merge
, aby ich praca została przeniesiona z powrotem do repozytorium. Jeśli następnie wycofasz ich zmiany z powrotem do lokalnego repozytorium, staniesz przed usunięciem bałaganu zduplikowanych zmian.
Rebazować, czy nie rebazować?
Rebase
może być zabronione w twoim projekcie. Mogą istnieć lokalne, kulturowe obiekcje. Niektóre projekty lub organizacje uważają rebase
za formę herezji i akt profanacji. Niektórzy uważają, że historia Gita powinna być nienaruszalnym, trwałym zapisem tego, co się wydarzyło. Tak więc rebase
może być poza stołem.
Ale używany lokalnie, w prywatnych oddziałach, rebase
jest użytecznym narzędziem.
Push po zmianie bazy i ogranicz to do oddziałów, w których jesteś jedynym programistą. A przynajmniej tam, gdzie cały rozwój został zatrzymany i nikt inny nie oparł żadnej innej pracy na zobowiązaniach twojego oddziału.
Zrób to, a unikniesz problemów.
POWIĄZANE: Jak sprawdzić i zaktualizować swoją wersję Git