Erholung vom Git-Reset - hart?

457

Gibt es eine Möglichkeit, nicht festgeschriebene Änderungen am Arbeitsverzeichnis von a wiederherzustellen git reset --hard HEAD?

Jacob Lyles
quelle
49
Ich würde empfehlen, zu verlernen git reset. Sie brauchen diesen Befehl nicht und er ist gefährlich, verwenden Sie ihn also nicht. Um die Verzweigung entweder zum vorherigen Commit zurückzukehren git rebase -iund die nicht gewünschten Commits zu git checkoutlöschen oder (den Kopf abzunehmen), gefolgt vom git branch -MVerschieben der Verzweigungsspitze. Die erste Datei wird nicht mit lokalen Änderungen ausgeführt, und die spätere Version wird nur ausgeführt, wenn sich die lokal geänderten Dateien zwischen den Versionen nicht unterscheiden.
Jan Hudec
11
@ Jan Ich glaube das nicht. Es gibt durchaus legitime Gründe, Reset zu verwenden.
Spaaarky21
4
@ spaaarky21: Ja, das gibt es. Ist git reset --hard somewhereaber einer der wenigen wirklich gefährlichen Git-Befehle.
Jan Hudec
5
@ Jan Ich stimme zu, aber gefährlich zu sein bedeutet nicht, dass du es nicht benutzen solltest. Wissen Sie einfach, was Sie tun und seien Sie vorsichtig. :)
spaaarky21
3
Nicht im Zusammenhang mit dem Rückgängigmachen eines Git-Resets --hard HEAD ~ 1 , da hier das Originalposter versucht, nicht festgeschriebene Änderungen wiederherzustellen.

Antworten:

475

Sie können nicht festgeschriebene Änderungen im Allgemeinen nicht zurückerhalten.

Zuvor bereitgestellte Änderungen ( git add) sollten von Indexobjekten wiederhergestellt werden können. Wenn Sie dies getan haben, verwenden Sie diese Option git fsck --lost-found, um die damit verbundenen Objekte zu suchen. (Dadurch werden die Objekte in das .git/lost-found/Verzeichnis geschrieben. Von dort aus können git show <filename>Sie den Inhalt jeder Datei anzeigen.)

Wenn nicht, lautet die Antwort hier: Sehen Sie sich Ihr Backup an. Vielleicht speichert dein Editor / deine IDE temporäre Kopien unter / tmp oder C: \ TEMP und ähnliches. [1]

git reset HEAD@{1}

Dadurch wird der vorherige HEAD wiederhergestellt

[1] vim speichert z. B. optional das dauerhafte Rückgängigmachen, die Eclipse- IDE speichert den lokalen Verlauf ; Solche Funktionen können Ihre a ** speichern

sehe sehen
quelle
18
Der lokale Verlauf von Eclipse - und außerdem, da einige Änderungen älter als 6 Tage waren, meine Time Machine-Sicherung des lokalen Verlaufs von Eclipse! Aus irgendeinem Grund enthielt die Time Machine-Sicherung des von git verwalteten Ordners meine vorherigen Änderungen nicht.
Christianbrodbeck
2
Sie sind ein ernsthafter Lebensretter auf dem Hinweis! Der TextWrangler hatte eine Sicherung von Dateien. Vielen Dank
Vivek Sampara
6
Die IDE (IntelliJ) hat die Änderungen lokal gespeichert, wodurch der Tag gespeichert wurde. Danke für den Tipp!
Progonkpa
1
Wow das ist beeindruckend. Es funktioniert auch dann, wenn Sie noch nie ein Commit durchgeführt haben.
Boudewijn Aasman
2
In der Tat spart die lokale Geschichte in Eclipse (in meinem Fall Intellij) meinen Tag bei der Wiederherstellung von unstrage Änderungen. Dokument hier für Intellij: blog.jetbrains.com/idea/2008/01/…
Richard
449

Antwort von diesem SO

$ git reflog show
93567ad HEAD@{0}: reset: moving to HEAD@{6}    
203e84e HEAD@{1}: reset: moving to HEAD@{1}    
9937a76 HEAD@{2}: reset: moving to HEAD@{2}
203e84e HEAD@{3}: checkout: moving from master to master
203e84e HEAD@{4}: reset: moving to HEAD~1
9937a76 HEAD@{5}: reset: moving to HEAD~1
d5bb59f HEAD@{6}: reset: moving to HEAD~1
9300f9d HEAD@{7}: commit: fix-bug

# said the commit to be recovered back is on 9300f9d (with commit message fix-bug)
$ git reset HEAD@{7}

Du hast deinen Tag zurück! :)

Ken
quelle
24
Nur um diese Antwort zu ergänzen, würde dies Menschen helfen, die tatsächlich Änderungen vorgenommen haben, die durch Hard-Reset weggeworfen wurden.
Murki
9
Großartig - aber in meinem Fall waren die Dateien komplett verschwunden. Mit git checkout HEAD@{19}konnte ich die verlorenen Dateien in einem getrennten Zustand auschecken. Dann werden git checkout -b new-branch-namesie im "angehängten" Zustand wieder zum Repo hinzugefügt.
NightOwl888
@ NightOwl888: Git Neuling hier und ich hatte das gleiche Problem, dass meine Dateien noch weg waren. Können Sie genauer erklären, wie Sie Ihre Dateien in einen "angehängten" Zustand zurückversetzt haben (oder können Sie erklären, was dies tatsächlich bedeutet)? Ich danke dir sehr!
OhDaeSu
3
@ user3385759 - Wenn Sie in Git den Befehl checkout für alles verwenden, was kein Zweig ist, wird er in einen speziellen "Detached Head" -Modus versetzt. Dies bedeutet, dass Sie nicht auf einen Zweig zeigen, sondern anzeigen können, was im Status der Entität eingecheckt wurde (in diesem Fall ein Reflog-Eintrag). Von diesem Status aus können Sie daraus einen "echten" Zweig machen, zu dem Sie mithilfe von wieder zurückkehren können git checkout -b new-branch-name. Das Buch Pragmatic Version Control Using Git ist gut darin, Git in einfachen Worten zu erklären.
NightOwl888
2
Ja, was NomNomCameron und Jesse Adelman gesagt haben. Ich dachte fälschlicherweise, der Reset würde auf mein letztes Commit zurückgesetzt. Nee. Es hat alles ausgelöscht. Diese Antwort ersparte mir ein oder zwei Tage Zeit, meine Arbeit neu zu erschaffen.
VeteranCoder
308

Ich git reset --hardbin heute auch versehentlich auf meinem Repo gelaufen, während ich heute auch nicht festgeschriebene Änderungen hatte. Um es zurückzubekommen, rannte ich git fsck --lost-foundlos und schrieb alle nicht referenzierten Blobs an <path to repo>/.git/lost-found/. Da die Dateien nicht festgeschrieben waren, fand ich sie im otherVerzeichnis innerhalb der <path to repo>/.git/lost-found/. Von dort aus kann ich die nicht festgeschriebenen Dateien mit sehen git show <filename>, die Blobs kopieren und umbenennen.

Hinweis: Dies funktioniert nur, wenn Sie die Dateien, die Sie speichern möchten, zum Index hinzugefügt haben (mithilfe von git add .). Wenn die Dateien nicht im Index enthalten waren, gehen sie verloren.

Justin
quelle
4
Ich habe nur Dateien mit Commit-Referenzen in lost-found. Aber ich könnte dann tun git show, um Inhalte zu bekommen.
Mitar
6
Nur um Zeit zu sparen#!/bin/bash cd PATH_TO_PROJECT/.git/lost-found/other FILES=* COUNTER = 0 for f in $FILES do echo "Processing $f file..." git show $f > "PATH_TO_RECOVERY_DIRECTORY/$COUNTER.m" let COUNTER=COUNTER+1 done
am
209

Ja, Sie können nach einem Hard-Reset in Git wiederherstellen .

Verwenden:

git reflog

um die Kennung Ihres Commits zu erhalten. Dann benutze:

git reset --hard <commit-id-retrieved-using-reflog>

Dieser Trick hat mir ein paar Mal das Leben gerettet.

Die Dokumentation zum Reflog finden Sie HIER .

Gabe
quelle
9
Bisher denke ich, dass dies die beste und prägnanteste Antwort ist. Es mag kontraintuitiv erscheinen, sich von git reset --hardeinem anderen wiederherzustellen , git reset --hardaber wenn Sie den --hardSchalter nicht verwenden , bleiben Einträge in Ihrem Arbeitsbereich übrig, die die gerade wiederhergestellte Arbeit effektiv zurücksetzen würden.
Ryan H.
2
Klappt wunderbar! Die vorherige Antwort ( stackoverflow.com/questions/5788037/recover-from-git-reset-hard/… ) hat bei mir nicht funktioniert.
Codemax
3
Diese Antwort ist nicht korrekt. Dieser Ansatz stellt nur zuvor festgeschriebene Änderungen wieder her. Nicht festgeschriebene Änderungen können nicht wiederhergestellt werden (worum es in dieser Frage geht).
Alderath
2
Diese Lösung funktioniert bei mir. Ich habe einen Hard-Reset durchgeführt und dann bei der Verwendung git logdie ID des Commits nicht gesehen. Mit git reflogkonnte ich die Commit-ID sehen
dboscanv
2
das funktioniert bei mir. Vielen Dank!!!!!!
RedEyed
60

Während ich an einem lokalen Projekt arbeitete, wollte ich es nach GitHub verschieben und dann ein neues Repository erstellen. Während ich versuchte, alle diese Dateien mit .gitignore zum neuen Repository hinzuzufügen, habe ich versehentlich eine falsche Datei hinzugefügt und dann versucht, sie zu löschen.

Ich rannte git reset --hard origin/master: P.

Dann wurden alle meine lokalen Dateien gelöscht, weil das Repo leer war. Ich dachte alles wäre weg.

Das hat mir das Leben gerettet:

git reflog show
git reset HEAD@{1} 
git push 

Hoffe, es rettet ein anderes Leben.

Orcun
quelle
Für mich war es git reset HEAD@\{27\} , danke!
4oby
1
Ich habe 7 Commits zurückzusetzen, ich benutze git reflog show, um zu überprüfen und von diesem ersten Commit verwende ichgit reset HEAD@{number}
Vishwas Nahar
38

Wenn Sie so etwas wie IntelliJ verwenden:

Wählen Sie im Kontextmenü Lokaler Verlauf und klicken Sie im Untermenü auf Verlauf anzeigen:

Die lokale Verlaufsansicht für ein Projekt oder einen Ordner zeigt Ihnen alles, was Sie in den letzten Tagen getan haben. Wählen Sie in der Spalte Aktion im unteren Teil des Dialogfelds die Aktion aus, die Sie zurücksetzen möchten. [...] Dabei zeigt der obere Teil des Dialogfelds die Baumansicht geänderter Dateien. Wenn Sie unabhängig von den anderen seitdem vorgenommenen Änderungen nur die gelöschte Datei wiederherstellen möchten, können Sie die Datei Lost.txt in der Baumansicht auswählen und auf die Schaltfläche Zurücksetzen klicken.

http://blog.jetbrains.com/idea/2008/01/using-local-history-to-restore-deleted-files/

Das hat gerade meinen Arsch aus dem Feuer geholt!

JonathanTien
quelle
Dies ist bei weitem die beste Antwort für IntelliJ-Benutzer! Vielen Dank, das hat perfekt funktioniert. Ich habe jede andere Lösung ausprobiert und keine davon hat gut funktioniert. git refloghat nicht funktioniert, weil ich die Änderungen nicht übernommen habe. git fsck --lost-foundarbeitete für bereitgestellte Dateien, aber nicht alle wurden bereitgestellt. IntelliJs Local History hat meine nicht gespeicherten Dateien perfekt wiederhergestellt. Ich bin so dankbar für diese Funktion
Denes Papp,
30

Ich habe gerade git reset --hardalle meine nicht festgeschriebenen Änderungen verloren. Zum Glück verwende ich einen Editor (IntelliJ) und konnte die Änderungen aus dem lokalen Verlauf wiederherstellen. Eclipse sollte es Ihnen ermöglichen, dasselbe zu tun.

user1147827
quelle
20

Per Definition git reset --hardwerden nicht festgeschriebene Änderungen verworfen, ohne dass Git sie wiederherstellen kann (Ihr Backup-System kann helfen, Git jedoch nicht).

Tatsächlich gibt es nur sehr wenige Fälle, in denen git reset --hardeine gute Idee vorliegt. In den meisten Fällen gibt es einen sichereren Befehl, um dasselbe zu tun:

  • Wenn Sie Ihre nicht festgeschriebenen Änderungen wegwerfen möchten, verwenden Sie git stash. Es wird eine Sicherungskopie dieser Änderungen erstellt, die nach einiger Zeit abläuft, wenn Sie ausgeführt werden git gc. Wenn Sie zu 99,9% sicher sind, dass Sie diese Änderungen nie wieder benötigen, git stashist dies immer noch Ihr Freund für den Fall von 0,1%. Wenn Sie 100% sicher sind, dann git stashist immer noch Ihr Freund, weil diese 100% einen Messfehler haben ;-).

  • Wenn Sie Ihre HEADund die Spitze des aktuellen Zweigs in der Geschichte verschieben möchten , dann git reset --keepist Ihr Freund. Es wird das Gleiche tun wie git reset --hard, aber Ihre lokalen Änderungen werden nicht verworfen.

  • Wenn du beides machen willst, dann git stash && git reset --keepist dein Freund.

Bringen Sie Ihren Fingern bei, nicht zu benutzen git reset --hard, es wird sich eines Tages auszahlen.

Matthieu Moy
quelle
Wenn man das tut git stash && git reset --hard, würde das alle versteckten Inhalte auslöschen, ist das richtig?
Jxramos
1
Nein, git reset --hardwirft den Vorrat nicht weg. git stashist ein Ersatz für git reset --hardin dem Sinne, dass nicht festgeschriebene Änderungen aus Ihrem Arbeitsbaum entfernt werden, außer dass sie sicher aufbewahrt werden, anstatt sie dauerhaft zu verwerfen.
Matthieu Moy
oder übernehmen Sie einfach Ihre Änderungen, bevor Sie sie hart zurücksetzen, und sie werden immer noch in Ihrem lokalen Repo sein
ThaJay
11

Wenn Sie ein Commit versehentlich hart zurückgesetzt haben, gehen Sie wie folgt vor:

git reflog show
git reset HEAD@{2} // i.e where HEAD used to be two moves ago - may be different for your case

Angenommen, HEAD@{2}Sie möchten in den Zustand zurückkehren

Edwin Ikechukwu Okonkwo
quelle
Dies funktionierte perfekt für mich, wenn Sie dies auf PowerShell tun. Stellen Sie sicher, dass Sie es wie folgt schreiben: 'HEAD @ {2}' wird zurückgesetzt. Andernfalls funktioniert es nicht in Powershell
VectorX
10

Dies ist, was ich normalerweise mache, wenn ich einige Änderungen verliere.

git reflog
git checkout <commit id> // now you are in where you want but you cannot push from detached branch to master
manually copy and paste changes from detached branch to master or working branch
git reset --hard HEAD // if needed
git add ... > git commit ... > git push ...

um den Zeiger zurück zu Ihren vorherigen Commits zu bewegen, aber die Änderungen, die Sie bisher in Ihrer letzten Commit-Prüfung vorgenommen haben, beizubehalten git reset --soft dadada

Drachenritter
quelle
8

Die Informationen gehen verloren.

Da Sie kein Commit durchgeführt haben, hat Ihr .git diese Informationen nie gespeichert. Also, gitkann es im Grunde nicht für Sie wiederherstellen.

Wenn Sie dies gerade getan haben git diff, gibt es eine Möglichkeit, die Verwendung des Terminalausgangs mit den folgenden drei einfachen Schritten wiederherzustellen.

  1. Scrollen Sie durch Ihr Terminal und suchen Sie nach dem O / P von git diff. Speichern Sie das O / P in einer Datei namens diff.patch
  2. Suchen und ersetzen Sie alle 7 Leerzeichen und 8 Leerzeichen durch Tabulatorzeichen (\ t) und speichern Sie die Änderungen.
  3. Gehen Sie in Ihr Git-Repository. Wende das diff.patch ( patch -p1 < diff.patch) an

Du bist gerettet! :) :)

Hinweis: Achten Sie beim Kopieren der Daten vom Terminal in eine Datei darauf, dass die Daten kontinuierlich ausgegeben werden und keine redundanten Daten enthalten (aufgrund des Drückens der Aufwärts- und Abwärtspfeile). Andernfalls könnten Sie es vermasseln.

mk ..
quelle
7

Ich bin auf dasselbe Problem gestoßen und wurde fast wahnsinnig. Anfangs habe ich das Projekt festgeschrieben und zusammengeführt. Später, als ich versuchte, es git push --set-upstream origin master auszuführen, bekam ich diesen Fehler

  fatal: refusing to merge unrelated histories

Also lief ich git reset --hard HEADund es löschte ein 3 Wochen Projekt, aber diese wenigen Befehle unten retten den Tag:

git reset HEAD@{1}         //this command unstage changes after reset
git fsck --lost-found      //I got the dangling commit fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b
git show <dangling commit something like-> fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b>
git rebase fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b

hoffe das hilft

Slycreator
quelle
6

Sie können ein Commit zurückerhalten, nachdem Sie a ausgeführt haben reset --hard HEAD.

Verwenden Sie " git reflog", um den Verlauf der HEADin der Filiale zu überprüfen .

Hier sehen Sie Ihr Commit und seine ID.

Mach a

git reset {commit Id of the commit you want to bring back}
Rachana Acharya
quelle
5

Wenn Sie zum Glück dieselben Dateien in einem anderen Editor (z. B. Sublime Text) geöffnet haben, versuchen Sie es mit Strg-Z. Es hat mich nur gerettet ..

Gabe
quelle
3

Ich habe auf die harte Tour herausgefunden, dass nicht festgeschriebene Dateien, bevor git reset --hard <commit>sie aus dem Git-Verlauf entfernt werden. Ich hatte jedoch das Glück, meine Code-Editor-Sitzung während der gesamten Zeit, in der ich mir die Haare auszog, offen zu halten. Dabei stellte ich fest, dass eine einfache control + zDatei in jeder der betroffenen Dateien den Status der Datei auf die Version vor Git zurückbrachte verbindlich alles zurücksetzen, worum ich nicht speziell gebeten habe.Hooray!!

Freundlicher Roboter
quelle
3

Wenn Sie versuchen, den folgenden Code zu verwenden:

git reflog show
# head to recover to
git reset HEAD@{1} 

und aus irgendeinem Grund bekommen:

Fehler: unbekannter Schalter `e '

Versuchen Sie dann, HEAD@{1}in Anführungszeichen zu setzen

git reset 'HEAD@{1}'
Rost
quelle
3
 git reset HEAD@{4}

4 ist Änderungen vor 4 Schritten. Wenn Sie einen richtigen Schritt auswählen, sollte die Liste der Dateien angezeigt werden, die Sie von hard entfernt haben. dann mach:

$ git reflog show

Es zeigt Ihnen den lokalen Commit-Verlauf, den wir bereits erstellt haben. mach jetzt:

$ git reset --hard 8c4d112

8c4d112 ist ein Code, den Sie dort festsetzen möchten. Schauen wir uns https://www.theserverside.com/video/How-to-use-the-git-reset-hard-command-to-change-a-commit-history an, um weitere Informationen zu erhalten.

mohammad
quelle
Vielen Dank @mohammad, es hat mich gerettet. Ich konnte meine Quelldateien früher nicht sehen, aber mit den obigen Schritten konnte ich alle Quelldateien wiederherstellen.
Gaurav Bansal
2

Korrekte Antworten. OK, jetzt mag ich git. :-) Hier ist ein einfacheres Rezept.

git log HEAD@{2}
git reset --hard  HEAD@{2}

Wobei "2" die Nummer ist, an der Sie Ihre Änderungen vorgenommen haben. In meinem Fall von einem Kollegen und Chef unterbrochen, um beim Debuggen eines Build-Problems zu helfen. so wurde ein Reset durchgeführt - zweimal hart; HEAD und HEAD @ {1} wurden also überschrieben. Puh, hätte unsere harte Arbeit verloren.

TimJowers2
quelle
2

Ich habe versehentlich git reset --harddas falsche Projekt gemacht (ich weiß ...). Ich hatte gerade an einer Datei gearbeitet und sie war während und nach dem Ausführen des Befehls noch geöffnet.

Obwohl ich nicht festgeschrieben hatte, konnte ich die alte Datei mit der einfachen abrufen COMMAND + Z.

Daniel Segura
quelle
0

Referenzantwort von diesem SO,

Nachdem Sie git reflog show ausgeführt haben, sagen Sie, dass Sie 9300f9d festschreiben möchten

Nach dem Ausführen von Git Reset 9300f9d

Sie können den Git-Status ausführen. Anschließend müssen Sie möglicherweise Ihre Datei (en) auschecken, um Ihre Änderungen wiederherzustellen

Git Checkout - Dateipfad / Name

Daniel
quelle
0

Wenn Sie auf Netbeans entwickeln, schauen Sie zwischen den Registerkarten der Datei und dem Bearbeitungsbereich der Datei. Es gibt eine "Quelle" und eine "Geschichte". In "Verlauf" sehen Sie Änderungen, die mit der Versionskontrolle (git / other) vorgenommen wurden, aber auch Änderungen, die lokal vorgenommen wurden. In diesem Fall können Sie durch lokale Änderungen gerettet werden.

Pedro Alvares
quelle
0

( Antwort geeignet für eine Untergruppe von Benutzern )

Wenn Sie unter (einem neueren) MacOS arbeiten und sich nicht auf Ihrer Time Machine-Festplatte befinden, hat das Betriebssystem stündliche Sicherungen gespeichert, die als lokale Snapshots bezeichnet werden .

Geben Sie Time Machine ein und navigieren Sie zu der Datei, die Sie verloren haben. Das Betriebssystem wird Sie dann fragen:

The location to which you're restoring "file.ext" already contains an
item with the same name. Do you want to replace it with the one you're
restoring?

Sie sollten in der Lage sein, die verlorenen Dateien wiederherzustellen.

Calaf
quelle
0

Wenn Sie eine IDE mit demselben Code geöffnet hatten, versuchen Sie, für jede einzelne Datei, an der Sie Änderungen vorgenommen haben, Strg + Z zu drücken. Es hat mir geholfen, meine nicht festgeschriebenen Änderungen nach dem Zurücksetzen des Git wiederherzustellen - hart.

dwarakesh tp
quelle
-3

Wenn wir git reset durchführen, wird --hard und alle lokalen nicht festgeschriebenen Änderungen gelöscht. Um die Änderungen wiederherzustellen, klicken Sie in der IDE auf die Datei, vergleichen Sie die Datei mit dem lokalen Verlauf, in dem die Änderungen nach Datum aufgelistet sind, und wir können die Daten wiederherstellen. Dein Tag ist gerettet!

Roopa
quelle
1
Diese Antwort wiederholt zwei frühere.
Isherwood