Jak cofnąć zmiany z merge commit’a wypchniętego na serwer – git revert?

Opublikowane przez Tomasz Prasołek w dniu

chuxue-lu-luchuxue1997-1130016-unsplash — small

Ostatni w pracy koleżanka spytała się mnie jak może cofnąć zmiany ze złego merge commita. Zorientowała się, że jest błąd tuż po wrzuceniu kodu na serwer. Zobaczmy jak to można naprawić używając polecenia git revert.

git revert

W pierwszej chwili chciałem jej odpowiedzieć:

git revert <hash złego merge commita>

Polecenie to odwraca wszystkie zmiany podanego commita i na tej podstawie tworzy nowy commit. Jeśli usunęliśmy jakiś kod, git revert wstawi go z powrotem. Jeśli dodaliśmy kod, polecenie go usunie.

Jednak powstrzymałem się, ponieważ merge commit jest commitem, który ma dwoje rodziców. W takiej sytuacji chciałbym odwrócić moje zmiany, a zostawić te zmiany wprowadzone przez drugą osobę.

Chwila w Googlu i znalazłem rozwiązanie:

git revert -m 1 <hash złego merge commita>

Z racji tego, że merge commit ma dwoje rodziców musimy wskazać z której ścieżki chcemy zachować zmiany. Czy z brancha do którego mergujemy (-m 1 – czyli zostawiamy to co ktoś zrobił na masterze) czy z naszego brancha (-m 2 – nasze zmiany są OK, cofamy kogoś zmiany wrzucone na master).

Jak sprawdzić rodziców commita? Poleceniem git show HEAD:

git show HEAD

Rodziców commita widać w linii nr 3:

Merge: bc3caa0 f30b549

bc3caa0 – to będzie parametr -m 1
f30b549 – to będzie parametr -m 2

Cofanie swoich zmian (-m 1) – przykład

Zobaczmy jak to działa na przykładzie. W repozytorium dodałem plik test.txt. Jego treść wygląda tak:

Test 001
Test 002
Test 003
Change on master branch
Change on feature branch

Przedostatnia linia została dodana w commicie na branchu master, ostatnia została dodana w commicie na branchu feature. Historia repozytorium natomiast wygląda następująco:

git log

Najnowszy commit to tzw. merge commit, którym będziemy się zajmować. Zakładamy, że wprowadzone przez Nas zmiany są złe (czyli pochodzące z brancha feature) i chcemy je cofnąć. Mamy jednak kod już na serwerze i nie możemy skasować merge commita, poprawić zły commit i zrobić operację merge jeszcze raz. Musimy odwrócić te zmiany. Wpisujemy komendę:

git revert -m 1 c8303f1

Po naciśnięciu klawisza ENTER otwiera Nam się edytor tekstu i git wpisuje w komentarz do commita co się stanie:

Revert "Merge feature"

This reverts commit c8303f1b8ef7c6bd7fa4ba89fb9385243fd20c22, reversing
changes made to bc3caa04e135eb48cac356b69e1f4a9c46ad9711.

Zostaną odwrócone zmiany wprowadzone w megre commicie (hash: c8303f1b…) jednak z zachowanie zmian z commita “Changes on master branch” (hash: bc3caa04…).

Historia teraz wygląda tak:

A zawartość pliku test.txt:

Test 001
Test 002
Test 003
Change on master branch

Widać, że nie ma w nim linii z tekstem “Change on feature branch”. Zadziałało tak jak chcieliśmy. Można to już wrzucić na serwer i zabrać się za poprawę wprowadzonego wcześniej buga.

Cofanie zmian kogoś innego (-m 2)

A co w przypadku jeśli nasza zmiana była w porządku, a ktoś zrobił błąd? Wtedy trzeba wpisać:

git revert -m 2 c8303f1

Czyli odwracany zmiany z brancha, do którego był merge. Po wykonaniu tego polecenie nasz plik będzie wyglądał tak:

Test 001
Test 002
Test 003

Change on feature branch

Podsumowanie

W ten prosty sposób można cofnąć zmiany wprowadzone przez merge. Trzeba się tylko sprawdzić z której ścieżki chcemy wycofać zmiany i tyle.

Źródła:
https://git-scm.com/docs/git-revert.html
https://mijingo.com/blog/reverting-a-git-merge


5 Komentarzy

Sylwia · 15 lipca 2019 o 14 h 55 min

Przejrzyste i zwięzłe wyjaśnienie – bardzo przydatne, dzięki!

Revert · 8 lipca 2020 o 16 h 04 min

A co w przypadku cofania 5 ostatnich commitów z których conajmniej dwa to commit merge? Da się to zapisać w jednej linii np. z poleceniem HEAD?

    Tomasz Prasołek · 10 lipca 2020 o 6 h 53 min

    Git jest elastyczny, więc może się da zapisać takie polecenie w jednej linii. Na pewno trzeba by znaleźć opcję, które nie otwiera edytora do wpisania commit message, tylko akceptuje tą wiadomość stworzoną automatycznie.

Michał · 6 sierpnia 2020 o 11 h 55 min

Super wyjaśnione, dzięki!

Podsumowanie roku 2019 - Poznaj Gita · 22 lutego 2020 o 11 h 23 min

[…] Jak cofnąć zmiany z merge commit’a wypchniętego na serwer – git revert? – 1306 odsłon […]

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *