Jak przywrócić początkowe zatwierdzenie git?

357

Po raz pierwszy zobowiązuję się do repozytorium git; Następnie żałuję zatwierdzenia i chcę go cofnąć. próbuję

# git reset --hard HEAD~1

Dostaję tę wiadomość:

fatal: ambiguous argument 'HEAD~1': unknown revision or path not in the working tree.

To zatwierdzenie jest pierwszym zatwierdzeniem z repozytorium. Masz pomysł, jak cofnąć początkowe zatwierdzenie gita?

Chau Chee Yang
źródło

Odpowiedzi:

565

Musisz tylko usunąć gałąź, na której jesteś. Nie możesz użyć, git branch -Dponieważ ma to kontrolę bezpieczeństwa przed zrobieniem tego. Możesz użyć update-refdo tego.

git update-ref -d HEAD

Czy nie używać rm -rf .gitalbo coś takiego jak to będzie całkowicie wytrzeć całego repozytorium, w tym wszystkich innych oddziałów, jak również gałęzi, które próbują przywrócić.

CB Bailey
źródło
1
Próbowałem tego podczas rebase - chciał podzielić pierwsze zatwierdzenie - potem zrobiłem git statusi, ku mojemu zaskoczeniu, powiedział git fatal: Not a git repository (or any parent up to mount point ...)!
Matt Fenwick
1
to nie działało dla mnie. Twórz pliki, w tym niektóre, które powinny być ignorowane, ale nie .gitignore. git add ., git commit -m "initial commit", git update-ref -D HEADUtwórz .gitignorezauważyć, że git nadal widzi plików Warto dodać, że wcześniej należy ignorować. Innymi słowy, git update-ref -d HEADnie zabrał mnie z powrotem do stanu przed pierwszym zatwierdzeniem.
gman
1
Ale o to chodzi w pierwotnym pytaniu. Wracając do stanu tuż przed początkowym zatwierdzeniem.
gman
2
git reset --hard HEAD~1usuną dodane pliki dla wszystkich innych zatwierdzeń. Oczywiście pytanie brzmi: jak dojść do tego samego stanu, w którym to polecenie działa we wszystkich innych przypadkach. Zobacz ten wykaz, aby udowodnić, że Twoje rozwiązanie nie działa gist.github.com/greggman/522fa69a21d6cfb3ff0b
gman
11
W przypadku, gdy ktoś pogubi przez G-Man za komentarze: git update-ref -d HEAD czy rzeczywiście przywrócić początkowy popełnić, ale zachowuje wszystkie poprzednio popełnione zmiany dodane do indeksu. Jeśli chcesz również usunąć te zmiany, po prostu wykonaj następujące czynności git reset --hard. Nawet jeśli jest niekompletna, ta odpowiedź jest rzeczywiście najlepsza, więc unikaj jej rm -fr .git(chyba że wiesz, co robisz).
rsenna
62

Możesz usunąć HEAD i przywrócić repozytorium do nowego stanu, w którym możesz utworzyć nowe wstępne zatwierdzenie:

git update-ref -d HEAD

Po utworzeniu nowego zatwierdzenia, jeśli już wypchnąłeś na zdalne, będziesz musiał wymusić je na pilocie, aby zastąpić poprzednie wstępne zatwierdzenie:

git push --force origin
frazras
źródło
1
Warto zauważyć ... to jest prawidłowe polecenie, ale nie usuwa HEAD ... usuwa ref (znajdujące się w .git \ refs \ heads), że plik .git \ HEAD został wypisany. Po uruchomieniu tego polecenia nadal możesz znaleźć plik HEAD wskazujący na plik refs / heads / <nazwa>, który usunąłeś, ale jeśli podążasz tą ścieżką, zobaczysz, że ref głowy już nie istnieje.
DanK
15

To pytanie zostało powiązane z tym postem na blogu i zaproponowano alternatywne rozwiązanie dla nowszych wersji Git:

git branch -m master old_master
git checkout --orphan master
git branch -D old_master

To rozwiązanie zakłada, że:

  1. Masz tylko jeden zatwierdzenie w swoim masteroddziale
  2. Nie ma oddziału o nazwie, old_masterwięc mogę swobodnie używać tej nazwy

Zmieni nazwę istniejącej gałęzi na old_masteri utworzy nową, osieroconą gałąź master (tak jak jest tworzona dla nowych repozytoriów), po czym możesz swobodnie usunąć old_master... lub nie. Zależy od Ciebie.

Uwaga: Przeniesienie lub skopiowanie gałęzi git zachowuje swój dziennik rejestrowania (zobacz ten kod ) podczas usuwania, a następnie tworzenia nowej gałęzi niszczy ją. Ponieważ chcesz wrócić do pierwotnego stanu bez historii, prawdopodobnie chcesz usunąć gałąź, ale inni mogą rozważyć tę małą notatkę.

nonsensickle
źródło
11

Zgodnie z warunkami określonymi w pytaniu:

  • Zatwierdzenie jest pierwszym zatwierdzeniem w repozytorium.
  • Co oznacza, że ​​wykonano bardzo niewiele poleceń:
    • a git init,
    • przypuszczalnie niektóre git addoperacje,
    • a git commit,
    • i to wszystko!

Jeśli te warunki wstępne zostaną spełnione, najprostszym sposobem cofnięcia początkowego zatwierdzenia byłoby:

rm -fr .git

z katalogu, w którym zrobiłeś git init. Następnie możesz powtórzyć, git initaby odtworzyć repozytorium Git, i powtórzyć dodatki z wszelkimi zmianami, które są uzasadnione, że żałowałeś, że nie zrobiłeś za pierwszym razem, i powtórzyć początkowe zatwierdzenie.

NIEBEZPIECZEŃSTWO! Spowoduje to usunięcie katalogu repozytorium Git.

Usuwa katalog repozytorium Git na stałe i nieodwracalnie, chyba że gdzieś masz kopie zapasowe. Zgodnie z warunkami wstępnymi nie ma nic, co chcesz przechowywać w repozytorium, więc nic nie tracisz. Wszystkie dodane pliki są nadal dostępne w działających katalogach, przy założeniu, że ich jeszcze nie zmodyfikowałeś i nie usunąłeś itp. Jednak wykonanie tego jest bezpieczne tylko wtedy, gdy nie masz nic innego w repozytorium. W okolicznościach opisanych w pytaniu „zatwierdzaj repozytorium po raz pierwszy - potem pożałuj”, jest to bezpieczne. Bardzo często jednak nie jest to bezpieczne.

Można to również bezpiecznie zrobić, aby usunąć niechciane sklonowane repozytorium; nie powoduje uszkodzenia repozytorium, z którego zostało sklonowane. Wyrzuca wszystko, co zrobiłeś w kopii, ale inaczej nie wpływa na oryginalne repozytorium.

Bądź ostrożny, ale jest bezpieczny i skuteczny, gdy spełnione są warunki wstępne.

Jeśli zrobiłeś inne rzeczy z repozytorium, które chcesz zachować, to nie jest to odpowiednia technika - twoje repozytorium nie spełnia już warunków wstępnych.

Jonathan Leffler
źródło
9
To zła rada. Co jeśli w repozytorium są inne rzeczy, których nie chcesz stracić?
Matt Fenwick
5
To nie byłby początkowy zatwierdzenie, prawda. Jest tylko jedno wstępne zatwierdzenie.
Jonathan Leffler
9
„To nie byłby początkowy zatwierdzenie” - tak, rzeczywiście tak. Pomijasz bardzo częsty przypadek wielu gałęzi. Zobacz odpowiedź Charlesa.
Matt Fenwick
2
Pomocne jednak powinno być ostrzeżenie.
Simon Bengtsson,
5
To faktycznie działa. Przyjęta odpowiedź nie. Patrz komentarz
gman
3

Nie możesz Więc:

rm -rf .git/
git init
git add -A
git commit -m 'Your new commit message'
ma11hew28
źródło
1
Próbował powiedzieć git reset --hard, więc dlaczego miałby git add -A?
Arystoteles Pagaltzis
3

W końcu wrzucę to, co dla mnie zadziałało. Musiałem usunąć początkowe zatwierdzenie z repozytorium, ponieważ dane poddane kwarantannie zostały zgubione, zatwierdzenie zostało już wypchnięte.

Upewnij się, że aktualnie znajdujesz się we właściwej gałęzi.

git checkout master

git update-ref -d HEAD

git commit -m "Initial commit

git push -u origin master

To było w stanie rozwiązać problem.

Ważny

Miało to miejsce w wewnętrznym repozytorium, które nie było publicznie dostępne. Jeśli Twoje repozytorium było publicznie dostępne, załóż, że wszystko, co musisz przywrócić, zostało już usunięte przez kogoś innego.

Edward
źródło
1

Zastanawiam się, dlaczego „poprawka” nie jest sugerowana i została przekreślona przez @damkrat, ponieważ poprawka wydaje mi się właściwym sposobem na jak najskuteczniejsze rozwiązanie problemu leżącego u podstaw naprawienia błędnego zatwierdzenia, ponieważ nie ma celu, aby nie mieć początkowej popełnić. Jak niektórzy podkreślają, powinieneś modyfikować gałąź „publiczną” jak master, jeśli nikt nie sklonował twojego repo ...

git add <your different stuff>
git commit --amend --author="author name <[email protected]>"-m "new message"
Richard
źródło
- autor jest wymagany tylko wtedy, gdy ktoś może skorygować autorstwo zatwierdzenia
Richard
0

git reset - twardo wprowadź zmiany, a następnie wykonaj

git add -A
git commit --amend --no-edit 

lub

git add -A
git commit --amend -m "commit_message"

i wtedy

git push origin master --force

--force przepisuje to zatwierdzenie, które zresetowałeś w pierwszym kroku.

Nie rób tego, ponieważ masz zamiar sprzeciwić się całej idei systemów VCS, aw szczególności git. Jedyną dobrą metodą jest utworzenie nowej i usunięcie niepotrzebnej gałęzi. Zobacz git help branchinformacje.

damkrat
źródło
-1

Wszystko, co musisz zrobić, to cofnąć zatwierdzenie.

git revert {commit_id}'

Następnie wciśnij

git push origin -f
abdallah Nofal
źródło
Nie można tego zrobić przy pierwszym zatwierdzeniu.
Użytkownik, który nie jest użytkownikiem,