Restore?Trik. 2 Zrobiłeś więc zmiany do swojego repozytorium Git. Jak je jednak cofnąć. W tym wpisie zobaczmy trzy polecenia: reset, restore i revert.

Ich nazwa sugeruje, że każde z nich może służyć do cofanie swoich zmian. Jak jest jednak naprawdę. Zobaczmy.

 

git restore

git restore to całkiem nowe polecenie i całkiem nie dawno nie było go w git. Według moich źródeł istnieje on dopiero od sierpnia 2019 roku.

git restore nie służy do cofania zmian, mimo iż nazwa może coś takiego sugerować. To polecenie jest przydatne, gdy chcemy cofnąć swoje zmiany lokalne, które istnieją tylko na naszym dysku. Przykładowo skasowałeś pewne pliki przez przypadek i chcesz je odzyskać z repozytorium.

Możesz zadeklarować, że chcesz przywrócić tylko jeden konkretny plik.

To polecenie nie zrobi nic na danym branchu czy gałęzi. 

To wszystko o to przypadek użycia.

przykład restore

Jak widzisz mam zmiany w pliku system.xml i używając "restore" pozbywam się tych lokalnych zmian w moim pliku.

Jeśli więc chcesz cofnąć swoje zmiany na lokalnym dysku, to jest to najlepsze polecenie.

git reset

Git reset jest dużo bardziej skomplikowane. Zauważ, że reset można wykonać na cztery sposoby, używając argumentów -soft, -hard, -mixed lub bez żadnego argumentu.

W przypadku -soft cofniemy się do wybranego commita, jednakże wszelkie zmiany dokonane po commit nie zostaną usunięte. Plik ze zmianami będą widoczne jako "zmiany do potwierdzenia".

Gdy użyjemy opcji -mixed lub nie podamy argumentu, to pliki zostaną zachowane, ale nie zostaną one zgłoszone do zatwierdzenia.

Mam także opcję -hard, która robi najlepiej, to co chcemy, jeśli chodzi o cofanie zmian, ale jest niebezpieczna. Gdy użyjemy tej opcji, to cofamy się do wybranego commita i kasujemy wszelkie zmiany, jakie były dokonane po tym commit-cie.

Pora na przykład w konsoli:

git init
git commit -m "Init Repo"
notepad system.xml
git add .
git commit -m "Add system.xml"
notepad example.xml
git add .
git commit -m "Add example.xml"

Mam więc proste repozytorium z dwoma commita-mi. Mój log wygląda tak:

Jak wygląda teraz git log

Użyje reset --soft na commicie, w którym dodałem plik example.xml

git reset --soft ef0c548

Jeżeli wybiorę opcję --soft to zobaczę w statusie zmiany, które wykonałem w danym commit

git reset --soft przykład

Mogę teraz zrobić ponownie commita, który na potrzebę prostoty będzie wyglądał tak samo tylko będzie zawierał inną wiadomość

git log git commit

Jak widzisz, reset skasował mojego commita, na którym zrobiłem reset i zastąpił go moim nowym.

Teraz zobaczmy, co zrobi git reset --hard.

git reset --hard  dfdc9579e614

Jak widać twardy reset, skasował tak jakby mojego ostatniego commita. 

git reset --hard

Mogę teraz zacząć pracę - tak jakby nie dodał pliku 'example.xml'. 

Dopóki nie zrobię nowego commita, ta zmiana jest jeszcze odwracalna. Używając "git reflog" mogę zobaczyć historię swoich resetów. To akurat jest przydatne, jeśli się zgubisz lub zrobiłeś reset, nie tak jak chciałeś.

git reflog

Tak więc działa reset. W nim jeszcze można korzystać ze specjalnych znaków karoty.

To polecenie zrobi reset do przedostatniego commita.

git reset --hard HEAD^1

Nie polecam, jednak ich używaj, ponieważ łatwo się zgubić. Reset to i tak bardzo niebezpieczna operacja więc zalecam najpierw zrobić "git log" i wybrać konkretny commit, do którego się chcesz cofnąć niż korzystać ze specjalnych znaków.

Git revert

Poleceniem git revert także można cofnąć zmiany. Może to być przydatne, gdy wiesz, że w ostatnim commicie znalazł się błąd i trzeb go szybko cofnąć, ale zostawić historię, że tam był.

Za czasów TFS mówiło się na to Rollback check-in.

Co to polecenie zrobi? Wykona za Ciebie commita, który cofa twoje zmiany.  Będziesz miał w historii commit, który coś zmieniły i będziesz miał potem commita, który tę zmianę cofnął.

Powiedzmy, że chce zachować historię o tym, że dodałem plik example.xml, ale mimo wszystko chce cofnąć tę zmianę.

Robię to tak:

git revert

Nie mam już pliku example.xml na swoim dysku. Dodatkowo widać nowy wpis w git log.

nowy commit po reflog

To wszystko tak działa revert. Jest on bezpieczniejszy niż reset i w każdej chwili możesz cofnąć swoją zmianę cofania. Co też w karierze programisty mi się zdarzyło nie raz.

Reset kontra Revert

Podstawowa zmiana pomiędzy Reset, a Revert wynika z historii.  Dobre praktyki mówią, aby trzymać w historii każdą zmianę w kodzie, ale wybór należy do Ciebie.

Teraz wiesz, jaka jest różnica pomiędzy Reset, Revert, a Restore.

Miłego Gitowania.