Jak dobrze znasz git rebase? Poznaj git commit –fixup

git commit --fixup

Weźmy taką sytuację – wysłaliście swój kod do review a tam koledzy zgłaszają poprawki. Ot codzienność. Wrzucacie zatem poprawki w kolejny commit, powiedzmy pod nazwą “Fixes in relation to the code review” a później jeszcze drugi trzeci, bo poprawek jest więcej. Każdy zbiór poprawek wrzucacie w osobnym commicie aby było czytelniej – nie żadne tam amendy. W końcu historia w Waszym repo wygląda mniej więcej tak:

git log - code review

W końcu gdy Wasze zmiany zostaną zaakceptowane zabieracie się za squash czyli scalenie wszystkich commitów w jeden. Co w tym przypadku będzie przebiegało następująco:

git rebase -i master

Wynikiem będzie następująca lista git-rebase-todo:

git rebase - wynik

Chcielibyśmy by z tych czterech commitów został nam tylko pierwszy. W takim wypadku możemy wyedytować tę listę i napisać coś takiego:

git rebase - zmiana todo

W kolejnym kroku możemy dodatkowo pozbyć się śladów tych tymczasowych commitów:

git rebase todo - zmiana

Wówczas na koniec nasz git log będzie wyglądał następująco:

git log

Jak to zrobić lepiej? – git commit –fixup

Wyobraźcie sobie, że w takiej sytuacji wcale nie musicie edytować git-rebase-todo, bo jest narzędzie, które wszystko co trzeba zrobić automatycznie.

Wróćmy zatem do momentu, gdy wrzucamy pierwsze poprawki do review i zamiast zrobić zwykły git commit użyjmy bohatera dzisiejszego artykułu czyli:

git commit --fixup 1f6fa91

Gdzie hash – 1f6fa91, który widzicie odpowiada hashowi commita do którego dodajecie poprawki. Wówczas nasz git log będzie wyglądał następująco:

git commit --fixup - przykład

Dodajmy pozostałe commity i wówczas będzie to wyglądało tak:

git log - trzy commity fixup

Jak fajnie! Nie trzeba już wymyślać nazw commitów – nazwy tworzą się same.

A teraz zwykły rebase?

Ostatecznie możemy teraz te commity scalić w jeden, tak jak robiliśmy to wcześniej, ale nie o to chodzi:) Teraz mamy do dyspozycji komendę:

git rebase --interactive --autosquash master

Wówczas pojawi nam się okienko z git-rebase-todo i możemy je edytować albo zostawić tak jak jest i wówczas na koniec nasz git log wygląda następująco:

git log - po autosquash

Ale to nie jedyne fajne zastosowanie git commit –fixup

Inna sytuacja – zabieracie się do pracy nad jakimś zadaniem, ale wcześniej znaleźliście parę miejsc w kodzie, które można by ulepszyć i zdecydowanie powinny się znaleźć w osobnym commicie. Robicie zatem refaktoring, dodajecie commit z nim związany i ruszacie dalej z kopyta do pracy nad daną funkcjonalnością. Kodujecie, kodujecie, kodujecie i nagle pach! Jeszcze jedno miejsce, gdzie przydałby się refaktoring. No ale głupio tak wrzucić to do bieżącego commita, który dotyczy zadania nad którym pracujecie. Można wtedy utworzyć dodatkowy commit a następnie za pomocą git rebase scalić go z tym pierwszym dotyczącym refaktoringu. Strasznie dużo roboty!

Da się inaczej? Da!

Niech nasz git log wygląda następująco:

git log - zadanie i refaktoring

Ponieważ chcemy nasz kolejny commit tak naprawdę podpiąć pod ten związany z refaktoringiem, możemy zrobić tak:

git commit --fixup 6345e1

Znowu wykorzystujemy hash aby powiedzieć gitowi do jakiego commita ma podpiąć ten nowy. Co się teraz stanie z historią commitów:

fixup do refaktoringu

Może się wydawać, że ten commit wskoczył w to samo miejsce co normalny, zwykły commit. Ale… git sobie z tym bardzo zręcznie poradzi jeśli tylko następnie użyjemy znanej nam już komendy:

git rebase --interactive --autosquash master

I git-rebase-todo będzie miało commity w jak najbardziej prawidłowej kolejności:

git rebase todo - fixup

W efekcie uzyskamy następującą historię:

gitlog-fixup

Uwaga! Możliwe, że pojawią nam się tutaj konflikty, ale to nic strasznego – rozwiązujemy je tak jak normalne konflikty.

Porada

Nie musimy zawsze wpisywać --autosquash, gdy chcemy skorzystać z tej funkcjonalności. Zamiast tego możemy skonfigurować gita aby robił scalał commity oznaczone jako fixup automatycznie. Wystarczy wykorzystać następującą komendę:

git config rebase.autosquash true

You might also like