Jak cofnąć commit w Git bez utraty zmian

Commit cofniesz poleceniem git reset, jeśli jest tylko na Twoim komputerze, albo git revert, jeśli jest już na serwerze. Zobacz, kiedy użyć --soft, --mixed i --hard, jak bezpiecznie wymusić zapis na serwerze i jak odzyskać commit z git reflog.

Commit, który jest tylko na Twoim komputerze, cofniesz poleceniem git reset. Opcja --soft zostawia zmiany w poczekalni, --mixed zostawia je w plikach, a --hard usuwa je razem z commitem. Commit, który jest już na serwerze, cofnij poleceniem git revert: Git dopisze nowy commit odwracający zmiany i nie przepisze historii, z której korzysta zespół. Nawet commit usunięty przez git reset --hard odzyskasz z dziennika git reflog, jeśli od usunięcia nie minęło 30 dni, bo tyle Git domyślnie przechowuje takie wpisy.

Opis poleceń opieramy na dokumentacji Git z serwisu git-scm.com, a każde polecenie Git sprawdziliśmy w wersji 2.43. Poniżej znajdziesz tabelę wyboru metody, polecenia dla commitu lokalnego i wysłanego na serwer, sposób odzyskania usuniętego commitu oraz to, czego Git nie cofnie na stronie WordPress.

Którą metodę cofnięcia commitu wybrać

Najpierw ustal, czy commit jest już na serwerze, np. w GitHub, GitLab albo Bitbucket. Uruchom git fetch, a potem git status. Komunikat, że gałąź jest "do przodu" względem origin/main (w angielskiej wersji Git: "Your branch is ahead of 'origin/main'"), oznacza, że najnowsze commity są tylko u Ciebie. Listę takich commitów pokaże git log origin/main..HEAD. Pobranie jest potrzebne, bo Git porównuje gałąź ze stanem serwera z chwili ostatniego git fetch (Pro Git, rozdział 3.5).

W poleceniach poniżej HEAD oznacza commit, na którym teraz pracujesz, a HEAD~1 commit przed nim (dokumentacja gitrevisions). Poczekalnia (ang. staging area, indeks) to lista zmian przygotowanych do następnego commitu.

SytuacjaPolecenieCo stanie się ze zmianami
Chcesz poprawić opis ostatniego commitu albo dodać do niego plik, a commit nie jest na serwerzegit commit --amendTrafią do nowego commitu, który zastąpi poprzedni
Chcesz cofnąć commit i od razu zatwierdzić zmiany ponowniegit reset --soft HEAD~1Zostaną w poczekalni
Chcesz cofnąć commit i przejrzeć zmiany przed kolejnym commitemgit reset HEAD~1Zostaną w plikach, poza poczekalnią
Chcesz cofnąć commit i usunąć jego zmianygit reset --hard HEAD~1Znikną, razem z niezatwierdzonymi zmianami w śledzonych plikach
Commit jest na serwerzegit revert <hash>Odwróci je nowy commit, a historia zostanie bez zmian
Commit jest na serwerze i musi zniknąć z historiigit reset i git push --force-with-leaseZnikną z gałęzi na serwerze, a zespół musi zsynchronizować swoje kopie

Jak cofnąć commit, który jest tylko na Twoim komputerze

Dopóki commit nie trafił na serwer, możesz zmienić historię bez wpływu na pracę innych osób. Polecenie git reset przenosi bieżącą gałąź na wskazany commit, a opcja decyduje, co stanie się ze zmianami z cofniętych commitów. Domyślną opcją jest --mixed (dokumentacja polecenia git reset).

Poprawienie ostatniego commitu: git commit --amend

git add zapomniany-plik.php
git commit --amend

Git zastąpi ostatni commit nowym, który zawiera dodany plik, i pozwoli poprawić opis. Sam opis zmienisz od razu opcją -m, np. git commit --amend -m "Poprawiony opis". Używaj --amend tylko dla commitów, których nie wysłałeś na serwer: Pro Git (rozdział 2.4) ostrzega, że poprawienie wysłanego commitu i wymuszony zapis na serwerze utrudnią pracę współpracownikom.

Cofnięcie commitu ze zmianami w poczekalni: git reset --soft

git reset --soft HEAD~1

Commit znika z historii, a jego zmiany zostają w poczekalni, gotowe do ponownego zatwierdzenia. Dokumentacja polecenia git reset podaje ten wariant jako sposób na poprawienie niekompletnego commitu albo literówki w jego opisie.

Cofnięcie commitu ze zmianami w plikach: git reset --mixed

git reset HEAD~1

Commit znika, a zmiany zostają w plikach, ale poza poczekalnią. Przed kolejnym commitem wybierasz poleceniem git add, które pliki zatwierdzić. Zapis git reset --mixed HEAD~1 działa tak samo, bo --mixed jest opcją domyślną.

Cofnięcie commitu razem ze zmianami: git reset --hard

git reset --hard HEAD~1

Commit i jego zmiany znikają z plików. Opcja --hard nadpisuje też zmiany w śledzonych plikach, których jeszcze nie zatwierdziłeś, a tych nie odzyskasz z dziennika reflog. Jeśli masz takie zmiany, odłóż je przed resetem poleceniem git stash, a po resecie przywróć poleceniem git stash pop.

Cofnięcie kilku commitów i repozytorium z jednym commitem

Aby cofnąć więcej commitów, zmień liczbę: HEAD~3 oznacza trzy commity wstecz, więc git reset --soft HEAD~3 cofnie trzy ostatnie commity. W repozytorium, które ma tylko jeden commit, HEAD~1 nie istnieje i Git zgłosi błąd "ambiguous argument 'HEAD~1'". Taki commit popraw poleceniem git commit --amend.

Jak cofnąć commit, który jest już na serwerze

Commit wysłany na serwer mogły już pobrać inne osoby. Jeśli usuniesz go z historii, ich kopie przestaną zgadzać się z serwerem. Dlatego na wspólnej gałęzi bezpieczniej jest odwrócić zmiany nowym commitem.

Bezpieczne cofnięcie przez git revert

git log --oneline
git revert a1b2c3d
git push origin main

git log --oneline pokazuje skrócone identyfikatory (hashe) commitów. git revert tworzy nowy commit, który odwraca zmiany wskazanego commitu, a oryginalny commit zostaje w historii (dokumentacja polecenia git revert). W ten sposób odwrócisz dowolny commit, nie tylko ostatni. Przed uruchomieniem zatwierdź albo odłóż poleceniem git stash swoje niezatwierdzone zmiany, bo dokumentacja wymaga czystego katalogu roboczego. W przykładzie zastąp a1b2c3d hashem swojego commitu, a main nazwą swojej gałęzi.

Cofnięcie kilku commitów jednym commitem

git revert --no-commit HEAD~2..HEAD
git commit -m "Cofnięcie dwóch ostatnich commitów"

Zakres HEAD~2..HEAD obejmuje dwa ostatnie commity. Opcja --no-commit odwraca zmiany w plikach i poczekalni bez tworzenia commitów, więc całość zatwierdzasz jednym commitem.

Cofnięcie commitu scalającego (merge)

git revert -m 1 a1b2c3d

Commit scalający ma dwóch rodziców, więc Git musi wiedzieć, względem którego odwrócić zmiany. Bez opcji -m zgłosi błąd. -m 1 wskazuje pierwszego rodzica, czyli gałąź, do której scalano, i usuwa zmiany wniesione przez scaloną gałąź. Dokumentacja ostrzega, że kolejne scalenie tej samej gałęzi wniesie tylko nowe commity, a nie te, których zmiany odwróciłeś.

Usunięcie commitu z historii na serwerze: git push --force-with-lease

git reset --hard HEAD~1
git push --force-with-lease origin main

Po git reset zwykły git push zostanie odrzucony, bo na serwerze jest commit, którego nie ma już w Twojej gałęzi. Wymuszony zapis (ang. force push) nadpisuje historię na serwerze. Opcja --force może usunąć z serwera commity innych osób (dokumentacja polecenia git push). Opcja --force-with-lease odmówi zapisu, jeśli od Twojego ostatniego pobrania ktoś wysłał na serwer nowe commity. Ta ochrona nie działa, gdy w tle automatycznie uruchamia się git fetch, np. jako zaplanowane zadanie.

Przed takim zapisem uprzedź zespół: każdy, kto pobrał usunięty commit, musi zsynchronizować swoją kopię. Pro Git (rozdział 3.6) zaleca, by nie przepisywać historii, która jest już poza Twoim repozytorium i na której inni mogli oprzeć swoją pracę.

Jak odzyskać commit po git reset --hard

Git zapisuje w dzienniku reflog każdą zmianę położenia HEAD i gałęzi w Twoim repozytorium (dokumentacja polecenia git reflog). Dzięki temu commit usunięty z gałęzi nadal da się wskazać i przywrócić.

git reflog
git reset --hard HEAD@{1}

git reflog pokazuje listę ostatnich operacji. HEAD@{1} oznacza położenie HEAD sprzed ostatniej operacji. Zamiast niego możesz podać hash commitu z listy. Tuż po resecie zadziała też git reset --hard ORIG_HEAD, bo Git zapisuje w ORIG_HEAD położenie sprzed operacji git reset (dokumentacja gitrevisions).

Dziennik reflog ma trzy ograniczenia:

  • działa tylko w Twoim lokalnym repozytorium, nie na serwerze,
  • wpisy o commitach, do których nie prowadzi już żadna gałąź, Git domyślnie przechowuje przez 30 dni (ustawienie gc.reflogExpireUnreachable), a pozostałe przez 90 dni (gc.reflogExpire),
  • nie przywróci zmian, których nie zatwierdziłeś przed git reset --hard.

Czego cofnięcie commitu nie cofnie na stronie WordPress

Git śledzi pliki w repozytorium, np. motyw i wtyczki strony WordPress. Treści i ustawienia strony są w bazie danych. Dokumentacja WordPressa podaje, że baza zawiera wpisy, komentarze i dane tworzone na stronie, a do pełnego odtworzenia strony potrzebne są zarówno pliki, jak i baza. Dlatego git revert i git reset cofną kod, ale nie cofną zmian, które aktualizacja albo wtyczka zapisała w bazie.

Przed wdrożeniem zmian zrób kopię bazy, np. poleceniem WP-CLI, które zapisuje bazę do pliku .sql (dokumentacja WP-CLI):

wp db export

Więcej o pracy z WordPressem z wiersza poleceń przeczytasz we wpisie "Instalacja i wstępna konfiguracja WordPressa za pomocą WP-CLI", a o ochronie plików strony we wpisie "Zabezpieczenie WordPressa za pomocą .htaccess". Pozostałe notatki o Git i WordPressie znajdziesz w kategorii GIT, np. wpis Kupony rabatowe w WordPressie: jak wykorzystać vouchery do pozyskiwania klientów?.

FAQ - o to najczęściej pytacie

Czym różni się git reset od git revert?

git reset przenosi gałąź na wcześniejszy commit, więc późniejsze commity znikają z jej historii. git revert dopisuje nowy commit, który odwraca zmiany, a historia zostaje. Reset stosuj do commitów lokalnych, a revert do commitów, które są już na serwerze.

Wysłałem na serwer commit z hasłem lub kluczem API. Czy wystarczy go cofnąć?

Nie. Po git revert hasło nadal jest w historii repozytorium, a po przepisaniu historii może zostać w kopiach i forkach. Dokumentacja GitHub i GitLab zaleca najpierw unieważnić albo zmienić ujawniony sekret, a dopiero potem decydować o czyszczeniu historii.

Co zrobić, gdy git revert zgłasza konflikt?

Rozwiąż konflikt w plikach, dodaj je poleceniem git add i uruchom git revert --continue. Jeśli chcesz zrezygnować, git revert --abort przywróci stan sprzed rozpoczęcia operacji.

Jak cofnąć zmiany w jednym pliku zamiast całego commitu?

Użyj polecenia git restore --source a1b2c3d -- sciezka/do/pliku, podając hash commitu i ścieżkę pliku. Git przywróci plik w wersji z podanego commitu, a pozostałe pliki zostaną bez zmian. Zmianę zatwierdzasz zwykłym commitem.

Czy po git push --force współpracownicy stracą swoją pracę?

Commity, które wysłali na serwer po Twoim ostatnim pobraniu, znikną z gałęzi na serwerze, ale zostaną w ich lokalnych kopiach. Dlatego używaj --force-with-lease, który w takiej sytuacji odrzuci zapis, i uprzedź zespół przed przepisaniem historii.

Co oznacza HEAD~1 i czym różni się od HEAD^?

Oba zapisy wskazują commit poprzedzający bieżący. Różnią się przy liczbach: HEAD~2 to commit dwa kroki wstecz, a HEAD^2 to drugi rodzic commitu scalającego (dokumentacja gitrevisions).

Czy mogę cofnąć commit, który nie jest ostatni?

Tak, poleceniem git revert <hash>: odwrócisz tylko ten commit, a późniejsze zostaną. git reset do starszego commitu usunąłby z gałęzi także wszystkie commity, które powstały po nim.

Źródła

Dostęp do wszystkich źródeł: 7 listopada 2026 r. Polecenia sprawdziliśmy w Git 2.43.0 i WP-CLI 2.12.0.

Dokumentacja Git

Bezpieczeństwo repozytorium i WordPress

To już koniec tego wpisu - ale mam dla Ciebie jeszcze coś

Mam tu dla Ciebie wybrane najważniejsze wpisy z kategorii "GIT". Dzięki przejrzystemu podziałowi szybko znajdziesz to, czego szukasz, więc jeśli:

... dopiero układasz sobie całość w głowie albo chcesz sprawdzić, czy nie pomijasz czegoś ważnego, polecam się zapoznać z tym:

... albo może chcesz wiedzieć, co ma największy sens w Twoim przypadku?

Jeśli po przeczytaniu tych materiałów zastanawiasz się, jak to wygląda w Twoim przypadku - napisz mi kilka słów w formularzu, a ja podpowiem Ci kierunek działania. Bez zobowiązań. Formularz znajdziesz tutaj

Rafał Skonieczka

Rafał Skonieczka

Zanim zająłem się marketingiem, przez prawie 10 lat służyłem jako żołnierz zawodowy. Zostały mi z tego dyscyplina i nawyki, które przydają się do dziś. Od 2006 roku prowadzę EVILLAGE.PL, a w tym czasie przeprowadziłem ponad 1000 projektów, w tym wprowadzenie produktów na 19 rynków europejskich. Skończyłem trzy kierunki studiów związanych z zarządzaniem. Jestem pasjonatem efektywności. Dziś pomagam zdobywać klientów w internecie.

Po godzinach resetuję głowę w górach i na korcie badmintonowym.

🖖 Niech konwersja będzie z Tobą!