GIT – Cofanie zmian

Czasem wprowadzimy do repozytorium zmiany których nie chcemy lub nie powinniśmy wysyłać na serwer. Z pomocą przychodzą dwie komendy – git revert oraz git reset. Ze względów praktycznych użyję angielskich nazw w artykule.

Cofanie commita

Jeśli nie przeszkadza nam fakt że w logu GITa zostanie informacja o commicie a potem fakcie jego cofnięcia (lub jest to wręcz wskazane), na pomoc przychodzi polecenie git revert. Zasada jego działania jest prosta – cofa on zmiany na zasadzie ich odwrócenia. Np. jeśli w commicie A dodamy linijkę kodu echo $string; to revert zrobi coś odwrotnego – utworzy commit B który usuwa ten fragment kodu (czyli zrobi to, co moglibyśmy zrobić ręcznie).

Zróbmy trochę bałaganu i użyjmy git revert aby wycofać ostatni commit (podając jego hash):

Cofanie zmian wprowadzonych przez commit przy pomocy git revert

Po wykonaniu pusha na serwer, fakt usuwania jest widoczny w logu. To nic złego i uważam że jest to elegancki sposób na „posprzątanie” bez naruszania ciągłości historii GITa. Jeśli wysłaliśmy zmiany na serwer i ktoś inny zdążył je pobrać (pull) to wystarczy że ponownie pobierze zmiany wprowadzone przez git revert, bo to tylko kolejny commit. W przypadku twardego usunięcia zmian (które omówię w następnym punkcie) zaciągnięcie zmian z serwera wymagałoby nadpisania lokalnego repozytorium u innych użytkowników.

Usuwanie commita

Czasem zakomitujemy zmiany których wcale nie chcemy zostawiać w historii (z różnych względów). Jeśli jeszcze nie wysłaliśmy ich na serwer (push) to możemy je usunąć poleceniem git reset:

Usuwanie commita z historii, czyli resetowanie do wskazanego commita

Jak widać usunęliśmy commita z loga, a nasze zmiany z tego commita wróciły do drzewa roboczego. Możemy je teraz przywrócić, poprawić i zakomitować ponownie lub porzucić.

Jeśli jednak nie chcemy zmian z commita w drzewie roboczym, można użyć to polecenie z flagą --hard (domyślnie aplikowana jest flaga --mixed):

Usuwanie commita wraz z zawartością przy pomocy git reset –hard

Przenoszenie commita na inny branch

Często jesteśmy na głównym branchu, np. master, naprawiamy jakiś błąd i przez przypadek commitujemy lokalnie do mastera zamiast wcześniej utworzyć osobny branch „tematyczny”, potrzebny do pull/merge request. Aby nie utracić naszej pracy i wyczyścić obecny branch, można najpierw utworzyć nowy branch a potem zresetować ten główny.

Użyjmy zatem dwóch poleceń, git branch nazwa-nowego-brancha oraz git reset --hard HEAD~1 aby „przenieść” ostatni commit na nowy branch i usunąć ze starego:

Przeniesienie ostatniego commita na inny branch