Ręka pokazuje diagram słów Internet rzeczy IoT jako koncepcję

Git Squash – jak łączyć wiele commitów w jeden? Poradnik

4 min. czytania

Git squash to praktyczna technika łączenia wielu commitów w jeden, która porządkuje historię i ułatwia pracę całemu zespołowi. Wykorzystaj ją przed scaleniem zmian do gałęzi głównej, aby historia była spójna i czytelna.

Czym jest git squash?

Squash scala kilka commitów w jeden commit o przejrzystym opisie. To idealne rozwiązanie, gdy podczas tworzenia funkcjonalności powstało wiele drobnych zmian typu „poprawka” czy „naprawiono błąd”.

Zamiast wielu drobnych commitów w historii zobaczysz jeden, dobrze opisany commit zawierający całą pracę.

Najważniejsze korzyści z używania squasha to:

  • porządek w historii – mniej szumu i łatwiejsza nawigacja w logach;
  • spójne commit message – jeden, treściwy opis całej funkcjonalności;
  • szybsze code review – przeglądający skupiają się na efektach, nie na drobnych krokach;
  • łatwiejszy revert – w razie potrzeby cofasz jeden commit zamiast wielu;
  • czytelne blame i anotacje – prostsze śledzenie źródła zmian.

Metoda 1 – interaktywny rebase (git rebase -i)

To najpopularniejsza metoda dająca pełną kontrolę nad historią commitów.

Krok 1 – określ liczbę commitów do scalenia

Jeśli chcesz scalić ostatnie 5 commitów, uruchom:

git rebase -i HEAD~5

Liczba po HEAD~ określa, ile commitów wstecz chcesz przeanalizować.

Krok 2 – otwórz edytor interaktywnego rebase

Komenda otworzy edytor z listą commitów, np.:

pick 5c6eb73 Dodano link do repo.or.cz

pick a311a64 Zmieniono kolejność analogii

pick 100834f Dodano cel push do pliku Makefile

Krok 3 – zmień pick na squash

Aby połączyć commit z poprzednim, zmień pick na squash (lub s). Pierwszy commit pozostaw jako pick, ponieważ squash łączy kolejny commit z poprzednim.

Przykład:

pick 5c6eb73 Dodano link do repo.or.cz

squash a311a64 Zmieniono kolejność analogii

squash 100834f Dodano cel push do pliku Makefile

W tym układzie commity a311a64 i 100834f zostaną połączone z commitem 5c6eb73.

Krok 4 – edytuj wiadomość commita

Po zapisaniu zmian Git otworzy edytor do edycji finalnej wiadomości. Możesz w nim:

  • scalić wiadomości z łączonych commitów,
  • edytować treść tak, by jasno opisywała zakres zmian,
  • usunąć zbędne informacje zostawiając tylko to, co istotne.

Krok 5 – potwierdź operację

Po zakończeniu rebase sprawdź historię:

git log

Jeśli wcześniej wypchnąłeś już te commity, do aktualizacji zdalnej gałęzi użyj bezpiecznego nadpisania:

git push --force-with-lease

Metoda 2 – git merge –squash

Gdy pracujesz na oddzielnych gałęziach, ta metoda bywa prostsza i bezpieczniejsza, zwłaszcza przy obecności merge’ów w historii.

Krok 1 – utwórz tymczasową gałąź

Utwórz nową gałąź jako kopię gałęzi docelowej:

git checkout -b new_feature_temp development

W tym przykładzie powstaje tymczasowa gałąź new_feature_temp na bazie development.

Krok 2 – zastosuj squash merge

Scal gałąź z funkcjonalnością do gałęzi tymczasowej używając opcji --squash:

git merge --squash new_feature

Opcja --squash zbiera całą pracę z gałęzi w jeden zestaw zmian i nie tworzy automatycznie commita.

Krok 3 – utwórz nowy commit

Zatwierdź scalone zmiany jednym, opisowym commitem:

git commit -m "feat: nowa funkcjonalność"

Krok 4 – zaktualizuj gałąź z funkcjonalnością

Wróć do gałęzi z funkcjonalnością i zresetuj ją do stanu gałęzi tymczasowej:

git checkout new_feature

git reset --hard new_feature_temp

Uwaga: --hard nadpisuje lokalne zmiany. Upewnij się, że niczego nie utracisz.

Krok 5 – wypchnij zmiany i wyczyść

Wypchnij zaktualizowaną gałąź:

git push

Następnie usuń gałąź tymczasową:

git branch -D new_feature_temp

Alternatywa – fixup zamiast squash

fixup (skrót f) działa jak squash, ale automatycznie odrzuca wiadomość scalanego commita, zachowując opis z pierwszego.

Przykład użycia w interaktywnym rebase:

pick 5c6eb73 Dodano link do repo.or.cz

fixup a311a64 Zmieniono kolejność analogii

fixup 100834f Dodano cel push do pliku Makefile

Praktyczne wskazówki

Poniższe rekomendacje pomogą bezpiecznie i skutecznie porządkować historię:

  • pracuj wcześnie i często – rób tyle commitów, ile potrzebujesz, a przed scaleniem posprzątaj historię rebase’em;
  • wykonuj squash przed push – porządkuj lokalnie, by nie mieszać historii w repozytorium współdzielonym;
  • uważaj na zmerge’owane gałęzie – przy rozbudowanej historii preferuj git merge --squash zamiast interaktywnego rebase;
  • dziel commit zamiast łączyć – gdy trzeba, użyj git rebase -i z opcją edit, by rozbić duży commit na mniejsze;
  • aktualizuj zdalne gałęzie bezpiecznie – po rebase używaj git push --force-with-lease, aby uniknąć nadpisania cudzej pracy.
Emil Jarecki
Emil Jarecki

Pasjonat technologii i analityk cyfrowej rzeczywistości. Na blogu poruszam tematykę z pogranicza IT i biznesu. Piszę o AI, cyberbezpieczeństwie i finansach, testuję sprzęt i analizuję trendy w social mediach. W wolnych chwilach sprawdzam nowości w świecie gier i płatności cyfrowych. Pomagam zrozumieć technologię, by służyła nam lepiej i bezpieczniej.