Git jako najpopularniejszy rozproszony system kontroli wersji – może się pochwalić rozbudowanym zbiorem funkcjonalności oraz różnego rodzaju integracji – co pozwala wykorzystać go swobodnie w wielu codziennych zadaniach.
W ramach tego materiału dowiesz się jak cofnąć zapisane już zmiany (git reset) w swoim lokalnym repozytorium wykorzystując komendę git reset – oraz jak zrobić tak zwany „twardy” reset, czyli git reset hard.
Spis treści
- 1 Git reset – Git reset hard
- 2 Git
- 3 Git commit
- 4 Git reset
- 5 Git reset soft
- 6 Git reset mixed
- 7 Git reset hard
- 8 Git reset to origin, git reset to remote – cofanie zmian do głównego branch’a (ang. master)
- 9 Git reset – remote repository – cofanie zmian na zdalnym repozytorium
- 10 Git revert
- 11 Git reset – podsumowanie
- 12 20+ BONUSOWYCH materiałów z programowania
Git reset – Git reset hard
Z tego materiału dowiesz się:
- Jak cofać zapisane zmiany za pomocą komendy git reset?
- Jakie są typy git reset?
- Jak cofnąć zmiany do branch’a master?
- Jak zrobić tak zwany „twardy” reset – czyli git reset hard?
Git
W ramach tego materiału zajmiemy się przede wszystkim cofaniem zmian w Gicie (git reset) – natomiast kompletny tutorial Git znajdziesz poniżej – tam również zapoznasz się ze stanami plików w Git, których zrozumienie może być bardzo pomocne przy cofaniu zmian.
➡ ZOBACZ 👉: Git tutorial | stash, rebase, commit, merge, checkout, push i clone
Git commit
Git reset – cofa zmiany wprowadzone przez git commit. Jeżeli chcesz bliżej zapoznać się z tematem commit’a (zapisywaniem zmian) – to zapraszam do dodatkowych materiałów:
➡ ZOBACZ 👉: Git commit | git amend.
Git reset
Przechodząc już do naszego głównego tematu, czyli resetowania zmian – wyobraź sobie taką sytuację:
- pracujesz nad swoją funkcjonalnością – może to być coś całkowicie nowego lub drobny hot-fix na produkcję,
- zapisujesz jedną zmianę (leci git commit), potem kolejną – i kolejny commit 🙂
- w pewnym momencie jednak dochodzisz do wniosku, że to co powstaję nie jest tym co chcesz osiągnąć – powodów może być wiele.
Może kolega z zespołu naprawił już ten sam błąd nad, którym Ty pracujesz?
A może zwyczajnie orientujesz się, że jest inny – lepszy sposób na rozwiązanie Twojego problemu. - To co jednak dla nas istotne, to to, że chcesz wycofać przynajmniej część swoich dotychczasowych zmian.
Tutaj właśnie przychodzi nam z pomocą Git ze swoją komendą git reset.
Narzędzie to ma dość dużą moc i daje nam sporo możliwości jeżeli chodzi o cofanie zmian – w zależności od tego, co konkretnie chcemy osiągnąć i do jakiego momentu w historii chcemy się cofnąć – do dyspozycji mamy trzy podstawowe formy polecenia git reset:
- soft – ––soft,
- mixed – ––mixed (opcja domyślna),
- hard – ––hard.
Git reset soft
Git reset ––soft – zmienia tylko wskaźnik HEAD, ale nie zmienia plików pozostawionych w przechowalni ani plików roboczych – co oznacza, że cofniemy się do wybranego commit’a i wszystkie zmiany, które zostały wprowadzone po nim, zostaną nienaruszone.
Ta wersja git reset tak naprawdę nie zmienia naszych plików, a samą historię ich zmian w Git.
Możemy ją wykorzystać, żeby np. „posprzątać” w historii zmian – usuwając dotychczasowe lokalne commity i tworząc później jeden zbiorczy commit ze wszystkimi zmianami – lub resetujemy commit i zmieniamy jego zawartość, bo np. zaplątał się tam plik, którego nie chcemy wrzucić do zdalnego repozytorium.
Po komendzie git reset ––soft, nie mamy w historii commita, ale nasze zmiany w plikach dalej są.
Zmodyfikowane pliki zostaną oznaczone jako „zmiany do zatwierdzenia” (ang. Changes to be committed).
Przykład pokazuje cofnięcie commit’a o hash’u : debd1dfc6cff32bfadeea192aee3cd30c92c42fb.
Zmiany zostały cofnięte z lokalnego repozytorium do przechowalni (ang. stage).
Jeśli chcesz, możesz je ponownie dodać do lokalnego repozytorium, wystarczy, że je ponownie zatwierdzisz (git commit).
Git reset mixed
Git reset ––mixed – przesuwa wskaźnik HEAD i aktualizuje przechowalnię do punktu, na który wskazuje teraz HEAD.
Oznacza to, że zmienione pliki są zachowywane, ale nie są oznaczone do zatwierdzenia.
Zachowanie to jest domyślne dla git reset, dlatego można, ale nie trzeba dodawać flagi ––mixed.
Przyjrzyjmy się takiej sytuacji.
Pracując nad większym fragmentem kodu w pewnym momencie stwierdzam, że mam lepszy pomysł na napisanie konkretnej metody.
Jednak pierwszą wersję zdążyłem już zapisać na lokalnym repozytorium.
Plus nie chciałbym jej całkowicie kasować, ponieważ część funkcjonalności chcę zachować bez zmian.
Po chwili zastanowienia wybieram git reset ––mixed.
Zmiany zostały wycofane z lokalnego repozytorium i nie znajdziesz ich również w przechowalni (ang. stage) – Ale! 🙂
Moje zmiany dalej są w katalogu roboczym, czyli jak w przypadku git reset soft – zmodyfikowana została tylko historia zmian, a nie same pliki nad którymi pracuję.
Teraz mogę już zmienić w kodzie to, co potrzebuję – a następnie jeszcze raz użyć komendy git add, aby dodać zmiany do przechowalni i następnie je zatwierdzić (git commit), aby znalazły się ponownie w lokalnym repozytorium.
Git reset hard
Git reset ––hard – przesuwa wskaźnik HEAD i aktualizuje przechowalnię oraz katalog roboczy.
Oznacza to cofnięcie to wybranego commit’a i usunięcie wszystkich zmian, które po nim nastąpiły.
dlatego należy bardzo uważać i przemyślanie stosować tę opcję.
Wyobraź sobie teraz, że tworzysz aplikacje dla klienta.
Od kilku dni tworzysz kod, gdy nagle dostajesz informację, że klient rezygnuję z funkcjonalności nad, którą pracujesz.
Nie potrzebujesz już tych linii kodu w Twoim katalogu roboczym, a tym bardziej na lokalnym repozytorium.
Trochę szkoda Twojej pracy, ale co zrobić? Takie życie projektowe. 🙂
W tej sytuacji przyda Ci się git reset ––hard.
Upewnij się jednak przed użyciem go, czy wszystko co napisałeś jest do usunięcia, aby nie skasować przez przypadek potrzebnych fragmentów kodu.
Spójrzmy na poniższą klasę mamy w niej takie metody jak setAge() oraz sayHi() i odpowiednie dla nich poniżej dwa commit’y:
setter age oraz say hi.
Wykonamy został git reset ––hard 5649474ec6902e636ea7c95f3b07bb6e6b7dbe7a (hash commit’a setter age).
Co oznacza, że wszystkie zmiany do tego commit’a zostały usunięte z lokalnego repozytorium.
Nie znajdziesz ich również w przechowalni ani w katalogu roboczym.
Na poniższym przykładzie widać, że nasze zmiany zostały cofnięte również z katalogu roboczego:
Nie tylko commit say hi, ale także metoda sayHi() zostały usunięte.
Przykład ten dobrze obrazuje jak ważne jest przemyślane stosowanie komendy git reset ––hard.
Git reset hard HEAD
Git reset możemy użyć m.in. poprzez wskazanie konkretnego commit’a lub pliku.
git reset --soft ed0b538 git reset --mixed file.ext
Możliwy jest też reset do poprzedniego commit’a poprzez zastosowanie komendy:
git reset --soft HEAD^
Git reset to origin, git reset to remote – cofanie zmian do głównego branch’a (ang. master)
Przećwiczmy teraz przypadek, w którym chcemy cofnąć nasze lokalne zmiany i nadpisać je tymi znajdującymi się w zdalnym repozytorium.
Krok 1. Pobranie zdalnych zmian
Jeżeli chcesz cofnąć wprowadzone zmiany na swoim branch’u i doprowadzić go do stanu, jaki znajduje się na głównym branch’u (ang. master) to możesz to zrobić stosując najpierw komendę: git fetch origin.
Uzyskamy dzięki temu wszystkie dane, które znajdują się na branch’u głównym, a których nasz branch jeszcze nie posiada.
Komenda ta jednak nie zmienia, ani nie update’uje naszego branch’a – tylko pobiera nowe dane ze zdalnego repozytorium.
Krok 2. Nadpisanie zmian
Następnie należy wykonać komendę: git reset ––hard origin/master.
Prześledźmy jeszcze raz poszczególne kroki:
- git fetch pobrał najbardziej aktualne dane z mastera,
- po czym cofnęliśmy za pomocą git reset ––hard origin/master do aktualnego stanu mastera.
Musisz jednak pamiętać, że to działanie usunie wszystkie wprowadzone przez Ciebie zmiany na tym branch’u.
Jeżeli nie jesteś w 100% przekonany, że zmian tych nie będziesz już potrzebować to zalecam stworzenie backup’u tych zmian.
git fetch origin git reset --hard origin/master
Git reset – remote repository – cofanie zmian na zdalnym repozytorium
Zawsze kiedy wypychamy zmiany z lokalnego do zdalnego repozytorium, powinniśmy robić to w sposób przemyślany i z dużą dozą pewności, że to co tam przesyłamy jest dokładnie tym co chcemy, aby na zdalnym repozytorium się znalazło.
Szczególne duże znaczenie ma to w przypadku projektów, nad którymi pracuję więcej osób niż tylko Ty.
Cofając zmiany ze zdalnego repozytorium stosując git reset, należy liczyć się z tym, że usuniemy historię zmian, które zostały cofnięte.
Co jest również istotne to fakt, że nie wiemy kto w międzyczasie pobrał już nasze zmiany i naniósł na nie swoje zmiany – przez co cofanie zmian na zdalnym repozytorium potencjalnie może doprowadzić do niezłego zamieszania 🙂
Jeżeli wprowadzone niechciane zmiany zostały już wypchnięte do zdalnego repozytorium, możesz cofnąć je stosując git reset ––hard na swoich lokalnych zmianach.
Następnie wystarczy zrobić update zdalnego repozytorium z opcją „force” – wykorzystując polecenie:
git push -f <zdalne repozytorium> <nazwa branch’a>.
git reset --hard ed0b538 git push -f origin moj–branch
Takie działania powinno wykonywać się w ostateczności i osobiście bym ich nie zalecał.
Zdecydowanie bezpieczniejszą formą cofania niechcianych zmian jest komenda git revert.
Git revert
Git reset nie jest jedynym narzędziem cofającym zmiany wprowadzone przez git commit. Git oferuje nam również bezpieczniejsze rozwiązanie jakim jest git revert. Bezpieczniejsze ponieważ historia zmian zostaje zachowana, co nie zawsze ma miejsce w przypadku git reset (np. git reset ––hard).
Jeżeli chcesz bliżej zapoznać się z tematem git revert – to zapraszam do dodatkowych materiałów:
➡ ZOBACZ 👉: Git revert commit | git revert merge commit.
Git reset – podsumowanie
W ramach tego materiału przećwiczyliśmy cofanie zmian w naszym lokalnym repozytorium (ang. git reset) w zależności od potrzeby stosując jedną z trzech flag ––soft, ––mixed, ––hard.
Nauczyliśmy się również cofać zmiany, które zostały wypchnięte na zdalne repozytorium.
Jeżeli chcesz kontynuować swoją przygodę z gitem – to zapraszam do dodatkowych materiałów:
➡ ZOBACZ 👉: Git tutorial | stash, rebase, commit, merge, checkout, push i clone
20+ BONUSOWYCH materiałów z programowania
e-book – „8 rzeczy, które musisz wiedzieć, żeby dostać pracę jako programista”,
e-book – „Java Cheat Sheet”,
checklista – „Pytania rekrutacyjne”
i wiele, wiele wiecej!