Jak mogę cofnąć polecenie `git commit` lokalnie i na pilocie po` git push`

242

Wystąpiłem, git commita następnie git push. Jak mogę przywrócić tę zmianę w lokalnych i zdalnych repozytoriach?

$ git log
commit 364705c23011b0fc6a7ca2d80c86cef4a7c4db7ac8
Author: Michael Silver <Michael [email protected]>
Date:   Tue Jun 11 12:24:23 2011 -0700
Michael
źródło

Odpowiedzi:

400
git reset --hard HEAD~1
git push -f <remote> <branch>

(Przykład przycisku: git push -f origin bugfix/bug123)

Spowoduje to cofnięcie ostatniego zatwierdzenia i przekazanie zaktualizowanej historii do pilota. Musisz przekazać, -fponieważ zastępujesz historię nadrzędną na pilocie.

Alexander Groß
źródło
24
Alternatywnie użyj git reset --hard <the-sha-you-want-to-return-to>.
Alexander Groß
2
Odniesienie nazywa się HEAD (
wielkość
26
Uważaj też - AFAIK nie powinieneś tego robić, jeśli inni ludzie wycofali się z repozytorium.
Amadan
1
@BipinVayalu Wpływa na oddział, w którym aktualnie się znajdujesz. Dokładniej HEAD. HEAD jest najczęściej „dołączany” do gałęzi (wskazuje na nazwę gałęzi zamiast bezpośrednio na zatwierdzenie). Ogólnie rzecz biorąc, wpłynie to na oddział, na który wskazuje HEAD. Użyj, git log --decorate --onelineaby dowiedzieć się, gdzie wskazuje HEAD.
Alexander Groß
4
git reset HEAD~1jeśli nie chcesz, aby twoje zmiany zniknęły (zmiany niestacjonarne). Zmień, zatwierdź i pchnij ponowniegit push -f [origin] [branch]
softvar
161

Zasadniczo dokonaj „odwrotnego” zatwierdzenia, używając:

git revert 364705c

następnie wyślij go do pilota jak zwykle:

git push

Nie spowoduje to usunięcia zatwierdzenia: powoduje dodatkowe zatwierdzenie, które powoduje cofnięcie tego, co zrobiło pierwsze zatwierdzenie. Wszystko inne, niezbyt bezpieczne, szczególnie gdy zmiany zostały już rozpowszechnione.

Amadan
źródło
9
Jest to bezpieczniejsza (a więc prawdopodobnie lepsza) odpowiedź niż odpowiedź Aleksandra Großa (wybrana odpowiedź).
Graeck
6
@Graeck Każde z rozwiązań ma swoje implikacje i zalety.
Alexander Groß
5
To powinna być zaakceptowana odpowiedź, najlepiej jest nigdy nie nadpisywać historii, a nawet więcej, jeśli współpracujesz z zespołem. git resetjest akceptowane tylko, jeśli zmiany nie zostały jeszcze przesłane do serwera.
Josue Alexander Ibarra
17
@JosueIbarra Nie zgadzam się we wszystkich przypadkach. W większości przypadków tak nie należy zastępować historii. Uważam jednak, że istnieją uzasadnione przypadki, w których absolutnie powinieneś. Na przykład przypadkowo popełniasz i przesuwasz swój plik sekretów. To nie powinno być w repozytorium git. Możesz więc szybko go usunąć, korzystając z zaakceptowanej odpowiedzi tutaj.
bfcoder
11
@bfcoder, jeśli przekazałeś „sekret” do zdalnego repozytorium, nie jest to już tajemnica. Właściwą poprawką jest stworzenie nowego sekretu, a nie próba ukrycia błędu.
erbsman,
41

Po pierwsze, zrelaksuj się.

„Nic nie jest pod naszą kontrolą. Nasza kontrola jest jedynie iluzją.”, „Błędem jest człowiek”

Rozumiem, że przypadkowo popchnąłeś swój kod remote-master. TO będzie w porządku.

1. Najpierw uzyskaj SHA-1wartość zatwierdzenia, które próbujesz zwrócić, np. Zatwierdzenie do gałęzi master. Uruchom to:

git log

zobaczysz kilka „f650a9e398ad9ca606b25513bd4af9fe ...” jak ciągi wraz z każdym z zatwierdzeń. skopiuj ten numer z zatwierdzenia, który chcesz zwrócić .

2. Teraz wpisz poniższe polecenie:

git reset --hard your_that_copied_string_but_without_quote_mark

powinieneś zobaczyć komunikat „HEAD jest teraz w”. jesteś czysty. To, co właśnie zrobił, to lokalne odzwierciedlenie tej zmiany.

3. Teraz wpisz poniższe polecenie:

git push -f

powinieneś zobaczyć jak

"ostrzeżenie: push.default jest rozbrojony; jego wartość domyślna zmieniła się w ..... ... Razem 0 (delta 0), ponownie użyta 0 (delta 0) ... ... twoja_nazwa_gałęzi - - master (wymuszona aktualizacja) . ”

Teraz wszystko jasne. Sprawdź ponownie master za pomocą „git log”, twoje fixed_destination_commit powinno znajdować się na górze listy.

Serdecznie zapraszamy (z góry;))

AKTUALIZACJA:

Teraz zmiany, które wprowadziłeś, zanim te wszystkie się zaczęły, zniknęły. Jeśli chcesz przywrócić te ciężkie prace, jest to możliwe. Dzięki git reflog i git komendom cherry-pick .

W tym celu sugeruję śledzenie tego bloga lub tego postu .

kmonsoor
źródło
podczas wykonywania polecenia „git push -f” dobrze jest też określić pilota i gałąź, ale „git push -f” i tak będzie działać przez większość czasu
Robson
8

git reset HEAD~1jeśli nie chcesz, aby twoje zmiany zniknęły (zmiany niestacjonarne). Zmień, zatwierdz i wciśnij ponowniegit push -f [origin] [branch]

softvar
źródło
3

Możesz zrobić interaktywną bazę:

git rebase -i <commit>

Spowoduje to wyświetlenie domyślnego edytora. Wystarczy usunąć wiersz zawierający zatwierdzenie, które chcesz usunąć, aby usunąć to zatwierdzenie.

Będziesz oczywiście potrzebował dostępu do zdalnego repozytorium, aby również zastosować tę zmianę.

Zobacz to pytanie: Git: usuwanie wybranych zatwierdzeń z repozytorium

Jack Edmonds
źródło
3

Spróbuj użyć

git reset --hard <commit id> 

Uwaga: tutaj identyfikator zatwierdzenia będzie identyfikatorem zatwierdzenia, do którego chcesz przejść, ale nie identyfikatorem, który chcesz zresetować. to był jedyny punkt, w którym również utknąłem.

następnie pchnij

git push -f <remote> <branch>
Mohit Dhawan
źródło
2

Alternatywnie:

git push origin +364705c23011b0fc6a7ca2d80c86cef4a7c4db7ac8^:master

Wymuś odgałęzienie źródłowego zdalnego repozytorium na element nadrzędny ostatniego zatwierdzenia

MicRum
źródło