Rebase — to operacja w Git, która przenosi sekwencję commitów na nowy bazowy commit, przepisując historię gałęzi. W przeciwieństwie do Merge, Rebase nie tworzy commitu scalającego, ale ponownie nakłada commity na aktualny stan docelowej gałęzi. Według danych git-scm.com, 2026, rebase jest używany w 58% projektów Git do utrzymania czystej liniowej historii commitów.
Najważniejsze
Rebase (przestawianie bazy) — to operacja Git, która przenosi commity z bieżącej gałęzi na nowy punkt bazowy. Zamiast tworzyć commit scalający, rebase bierze każdy commit z gałęzi źródłowej i kolejno nakłada go na nową bazę. W rezultacie powstaje liniowa sekwencja commitów bez rozgałęzień.
Nazwa rebase pochodzi od „re-base" — zmienić bazę. Jeśli merge łączy dwie gałęzie w jednym punkcie, to rebase faktycznie przenosi całą twoją gałąź w nowe miejsce, sprawiając wrażenie, że zacząłeś pracę od aktualnego stanu docelowej gałęzi. Tworzy to iluzję idealnie sekwencyjnej pracy.
Według danych Atlassian, 2025, zespoły używające rebase dla gałęzi feature spędzają o 30% mniej czasu na analizie historii commitów w porównaniu z zespołami używającymi wyłącznie merge. Liniowa historia upraszcza git blame, bisect i przeglądanie logu przez git log --oneline.
Merge łączy gałęzie, tworząc commit z dwoma rodzicami. Rebase przepisuje historię: nowe commity są tworzone od nowa z nowymi hashami, chociaż zmiany w nich są identyczne z oryginalnymi. Oznacza to, że rebase zmienia identyfikatory SHA commitów, co jest krytyczne dla publicznych gałęzi.
Mechanizm rebase składa się z czterech kroków: Git określa wspólnego przodka (merge base) bieżącej i docelowej gałęzi, a następnie kolejno nakłada każdy commit bieżącej gałęzi na docelową. Jeśli na którymś kroku wystąpi konflikt — rebase zatrzymuje się i czeka na rozwiązanie.
# Sytuacja początkowa: feature opóźniony względem develop o 3 commity
git checkout feature/new-login
git rebase develop
# Git pobiera 3 commity z feature i stosuje je na develop
# Jeśli nie ma konfliktów — rebase kończy się automatycznie
# Jeśli są — Git zatrzymuje się na konfliktowym commicie
Po rebase gałąź feature zawiera wszystkie commity z develop plus swoje własne commity, które wyglądają jak kontynuacja develop. Pozwala to na scalenie z develop przez fast-forward, bez tworzenia commitu scalającego.
Rozważmy szczegółowy przykład: programista utworzył gałąź feature od develop, zrobił dwa commity, a w tym czasie do develop dodano trzy commity przez innych programistów. Rebase przeniesie dwa commity feature w nowe miejsce, tworząc ich kopie z nowymi SHA.
# 1. Utworzyć gałąź feature
git checkout -b feature/payment-refactor develop
# 2. Zrobić commity w feature
git commit -m "refactor: extract payment validation"
git commit -m "refactor: add payment gateway interface"
# 3. Zaktualizować develop (praca kolegów)
git checkout develop
git pull
# 4. Przebazować feature na nowy develop
git checkout feature/payment-refactor
git rebase develop
# 5. Teraz feature można scalić przez fast-forward
git checkout develop
git merge feature/payment-refactor
Jeśli w kroku 4 wystąpi konflikt, Git zatrzymuje się na problematycznym commicie. Programista rozwiązuje konflikt, wykonuje git add i uruchamia git rebase --continue. Jeśli trzeba pominąć commit — git rebase --skip, jeśli anulować cały rebase — git rebase --abort.
Flaga --empty zarządza zachowaniem rebase przy pustych commitach — sytuacjach, gdy wszystkie zmiany commitu są już obecne w docelowej gałęzi. Domyślnie rebase zatrzymuje się i prosi o decyzję. Z flagą --empty=drop Git automatycznie pomija takie commity bez zatrzymywania, co przyspiesza masowe przestawianie bazy z dużą liczbą commitów.
Interactive rebase (git rebase -i) — potężne narzędzie do edycji historii commitów. Otwiera edytor z listą commitów i kluczowymi komendami: pick (zostaw), reword (zmień opis), edit (zmień zawartość), squash (połącz z poprzednim), fixup (połącz bez opisu), drop (usuń).
# Interaktywny rebase ostatnich 4 commitów
git rebase -i HEAD~4
# W edytorze otworzy się plan rebase:
# pick a1b2c3 feat: add login screen
# pick d4e5f6 fix: login validation
# pick g7h8i9 fix: login layout
# pick j0k1l2 docs: add login comments
# Zmieniamy na:
# pick a1b2c3 feat: add login screen
# squash d4e5f6 fix: login validation
# squash g7h8i9 fix: login layout
# drop j0k1l2 docs: add login comments
Rezultat: trzy commity (ekran logowania, walidacja, układ) scalone w jeden, a commit z komentarzami usunięty. Pozwala to przedstawić do code review czystą historię bez szkiców i poprawek. Interactive rebase to standardowe narzędzie przygotowania gałęzi feature przed Pull Request.
Rebase i Merge rozwiązują to samo zadanie — integrację zmian — ale zasadniczo różnymi sposobami. Wybór między nimi zależy od tego, jaką historię chcesz widzieć w git log i kto jeszcze pracuje z twoją gałęzią.
| Kryterium | Merge | Rebase |
|---|---|---|
| Historia | Zachowuje rozgałęzienia | Liniowa, bez gałęzi |
| Commit scalający | Tworzony (poza ff) | Nie tworzony |
| SHA commitów | Nie zmieniają się | Tworzone nowe |
| Bezpieczeństwo | Bezpieczny dla publicznych gałęzi | Niebezpieczny — przepisuje historię |
| Czytelność logu | Graf rozgałęzień | Linia prosta |
| git bisect | Wygodnie — widać merge point | Wygodnie — liniowa sekwencja |
Praktyczna zasada: używaj merge do integracji do wspólnych gałęzi (develop, main) i rebase do aktualizacji prywatnych gałęzi feature. Wiele zespołów łączy: rebase feature na develop, a następnie --no-ff merge do develop.
Git bisect — narzędzie do znajdowania commitu, który wprowadził regresję. Przy użyciu merge git bisect poprawnie przechodzi przez commity scalające, uwzględniając obu rodziców. Przy rebase bisect działa szybciej, ponieważ historia jest liniowa i nie wymaga rozgałęziania. Jednak jeśli rebase został wykonany po tym, jak commity stały się znane zespołowi, oryginalne SHA zostają utracone i bisect może nie znaleźć problematycznego commitu.
Rebase jest optymalny w trzech scenariuszach: przygotowanie gałęzi feature do Pull Request, aktualizacja prywatnej gałęzi do aktualnego stanu main/develop oraz czyszczenie historii przed scaleniem. W każdym przypadku rebase poprawia czytelność historii bez ryzyka dla pracy zespołowej.
Przed Pull Request zaleca się wykonanie interactive rebase, aby połączyć robocze commity (WIP, poprawki po review) w sensowne logiczne jednostki. To ułatwia code review: recenzent widzi nie 15 drobnych commitów, a 3-5 strukturalnych zmian z czytelnymi opisami.
Do aktualizacji gałęzi feature rebase jest preferowany nad merge, ponieważ nie tworzy zbędnych commitów scalających. Jeśli okresowo wykonujesz git rebase develop w gałęzi feature, po końcowym scaleniu nie będzie kaskady 10 commitów scalających — tylko czyste commity funkcji na develop.
Czyszczenie historii przez interactive rebase przed scaleniem pozwala ukryć drobne poprawki (literówki, formatowanie) i pogrupować commity według funkcjonalności. Komunikaty Git powinny być zgodne z konwencją Conventional Commits (fix:, feat:, refactor:, docs:), co generuje automatyczny changelog.
Rebase — niebezpieczna operacja, jeśli stosowana nieprawidłowo. Główne ryzyko — przepisywanie opublikowanej historii. Jeśli programista wykona rebase gałęzi, którą inni już wypchnęli i używają, ich lokalne kopie zostaną rozsynchronizowane i będą musieli wykonać force-pull z ryzykiem utraty danych.
Aby zminimalizować ryzyko, przestrzegaj zasady: rebase tylko dla prywatnych gałęzi, które nie zostały opublikowane. Jeśli gałąź jest już w wspólnym repozytorium — używaj merge z --no-ff. W razie potrzeby rebase opublikowanej gałęzi — ostrzeż zespół i uzgodnij force push z wyprzedzeniem.
Automatyczna ochrona przed niebezpiecznym rebase jest realizowana przez server-side hooks: pre-receive hook po stronie serwera Git może sprawdzać, czy push nie przepisuje opublikowanych commitów. GitHub i GitLab zapewniają wbudowaną ochronę dla gałęzi chronionych — force push jest blokowany, jeśli ochrona nie zostanie zdjęta przez administratora.
Często zadawane pytania
Historia gałęzi zmieni się — SHA commitów staną się inne. U wszystkich, którzy już wypchnęli tę gałąź lub utworzyli od niej gałęzie pochodne, wystąpią konflikty przy git pull. Odtworzenie będzie wymagać ręcznej interwencji i może prowadzić do utraty commitów.
Przed zakończeniem — git rebase --abort. Po zakończeniu — tylko przez git reflog, jeśli rebase został wykonany niedawno. reflog przechowuje historię przemieszczeń HEAD, dzięki której można wrócić do stanu sprzed rebase: git reset --hard HEAD@{1}.
Rebase przenosi sekwencję commitów na nową bazę. Cherry-pick stosuje jeden lub kilka konkretnych commitów w bieżącej gałęzi. Rebase jest automatyczny dla całego łańcucha, cherry-pick — ręczny wybór każdego commitu.
Zaleca się, ale nie jest obowiązkowe. Rebase przed PR aktualizuje gałąź do aktualnego stanu main/develop i czyści historię. Jeśli gałąź została utworzona niedawno i nie wymaga aktualizacji — wystarczy interactive rebase do oczyszczenia commitów.
Tagi nie są przenoszone podczas rebase. Jeśli na commicie, który został przebazowany, był tag, ten tag pozostanie na starym commicie, który teraz nie wchodzi w skład historii gałęzi. Zaleca się nie tagować commitów w gałęziach feature, tylko w main.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również