Git #6: reset vs. revert

Cofanie wprowadzonych przez nas zmian wbrew pozorom może zdarzać się częściej, niż nam się wydaje. Możemy to zrobić na wiele sposobów, jednak w tym artykule zajmiemy się dwoma najpopularniejszymi, git reset i git revert. 


Cofanie wprowadzonych przez nas zmian wbrew pozorom może zdarzać się częściej, niż nam się wydaje. Możemy to zrobić na wiele sposobów, jednak w tym artykule zajmiemy się dwoma najpopularniejszymi, git reset git revert. 

Git Reset

Jest to złożone narzędzie do cofania zmian. Możemy wywołać je na cztery sposoby, używając argumentów –soft, –hard i —mixed, lub bez żadnego dodatkowego argumentu. W przypadku argumentu –soft, cofniemy się do wybranego komita. Wszelkie zmiany dokonane po komicie nie zostaną usunięte, pliki ze zmianami będą widoczne jako „zmiany do zatwierdzenia”. Gdy użyjemy argumentu –mixed,  po cofnięciu się do wybranego komita, zmienione pliki są zachowane, ale nie są zgłoszone do zatwierdzenia. Jest on też domyślnym argumentem i będzie użyty, gdy nie wybierzemy żadnego z argumentów.  W tym artykule zajmiemy się ostatnim z wymienionych argumentów: –hard. Jest to najbardziej niebezpieczna z opcji. Po jego użyciu cofamy się do wybranego komita i kasujemy wszelkie zmiany, jakie były dokonane po tym komicie. Najlepszym sposobem pokazania jak działa git reset, jest utworzenie zestawu zmian w repozytorium i śledzenie zmian krok po kroku.

pi@raspberrypi:~ $ mkdir undoing_changes
pi@raspberrypi:~ $ cd undoing_changes/
pi@raspberrypi:~/undoing_changes $ git init
Initialized empty Git repository in /home/pi/undoing_changes/.git/
pi@raspberrypi:~/undoing_changes $ touch file_one.py
pi@raspberrypi:~/undoing_changes $ git add file_one.py
pi@raspberrypi:~/undoing_changes $ git commit -m "Added file_one"
pi@raspberrypi:~/undoing_changes $ touch file_two.py
pi@raspberrypi:~/undoing_changes $ git add file_two.py
pi@raspberrypi:~/undoing_changes $ git commit -m "Added file_two"

W powyższym przykładzie stworzyłem nowe lokalne repozytorium, dodałem do niego dwa nowe pliki (file_one.py file_two.py) i jeden po drugim skomitowałem. Na poniższym screenie (PyCharm – zakładka „Version Control”) widzimy dwie osobne „kulki” komitów, a także (po prawej stornie) informację o zaznaczonym pierwszym komicie. 

Aby cofnąć się do komitu o nazwie Added file_one potrzebny będzie numer komita. Znajduje się ona w informacjach komicie lub można ją uzyskać, używając komendy git log. W naszym przypadku jest to (86b6857a). Teraz dodając do git reset argument –hard i numer komita, wymusimy cofnięcie się do „Added file_one”

pi@raspberrypi:~/undoing_changes $ git reset --hard 86b6857a
HEAD is now at 86b6857 Added file_one
pi@raspberrypi:~/undoing_changes $

Sprawdźmy co stało się z historią naszych zmian:

Drugi komit „Added file_two” został usunięty, a nasz widok znajduje się na „Added file_one„. Git wymusił także usunięcie wszystkich zmian, które nastąpiły po komicie „Added file_two„, takich jak dodanie pliku file_two.py.

Git Revert

Poleceniem git revert można także cofać zmiany.  Może to być przydatne, jeśli śledzisz błąd i odkrywasz, że został on wprowadzony w ostatnim komicie. Zamiast ręcznie wchodzić i naprawiać, możesz użyć git revert, aby automatycznie zrobił to wszystko za Ciebie. Pamiętać trzeba, że nie jest to normalna operacja cofania. Jest to bardziej oficjalna ścieżka cofania zmian. Gdyż tworzy ona dodatkowy komit, który jest kopią komita poprzedzający kommit revert’owany. Jako że poprzednie zdanie może być dość zawiłe, przedstawię to na przykładzie. Wróćmy do punktu, w którym posiadamy dwa komity  „Added file_one” i „Added file_two” (dokładnie tak jak z początku opisu git reset)

Tym razem będziemy potrzebowali nazwy drugiego komita (w tym przypadku będzie to 379ab6d1)

pi@raspberrypi:~/undoing_changes $ git revert 379ab6d1

W taki sposób cofamy zmiany wybranego komita. Jak widzimy poniżej, utworzony został automatycznie dodatkowy komit o nazwie Revert „Added file_two”. A po sprawdzeniu co znajduje się aktualnie na naszym repozytorium zobaczymy jedynie file_one.py

Reset vs. Revert

Czas zająć się główną różnicą między git reset i git revert. Jest nią historia. Wiem, brzmi to dość śmiesznie, ale git revert zamiast usuwać zatwierdzenie zmiany z historii projektu, przywraca poprzedni stan repozytorium (komit) jako kolejny komit, nie niszcząc tym samym historii zmian. Zapobiega to utracie historii, co jest ważne dla integralności historii zmian.  W przypadku git reset, który jak już wcześniej wspominałem, nie jest bezpiecznym sposobem cofania zmian, tracimy historię zmian. Jest to popularne rozwiązaniem, gdyż w szybki sposób możemy wrócić do konkretnego stanu naszego repozytorium, bez jakichkolwiek „blokad”.
Kolejną znaczącą różnicą jest to, że git reset cofa zmiany komita, a git revert po prostu „przeskakuje w czasie”, zapominając o dokonanych zmianach.

Mam nadzieję, że po przeczytaniu tego artykułu już nigdy nie będziecie mylili ze sobą tych dwóch komend i nie usuniecie sobie przypadkiem waszych cennych zmian w kodzie, chcąc tylko cofnąć się o jeden komit wstecz.

close

Newsletter