Frage Wie kann ich git reset --hard HEAD ~ 1 rückgängig machen?


Ist es möglich, die durch den folgenden Befehl verursachten Änderungen rückgängig zu machen? Wenn das so ist, wie?

git reset --hard HEAD~1

911
2017-08-07 23:22


Ursprung


Antworten:


Pat Notz hat Recht. Sie können das Commit so lange zurückholen, wie es innerhalb von ein paar Tagen war. git nur Müll sammelt sich nach etwa einem Monat oder so, es sei denn, Sie sagen ihm explizit, dass er neuere Blobs entfernen soll.

$ git init
Initialized empty Git repository in .git/

$ echo "testing reset" > file1
$ git add file1
$ git commit -m 'added file1'
Created initial commit 1a75c1d: added file1
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file1

$ echo "added new file" > file2
$ git add file2
$ git commit -m 'added file2'
Created commit f6e5064: added file2
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file2

$ git reset --hard HEAD^
HEAD is now at 1a75c1d... added file1

$ cat file2
cat: file2: No such file or directory

$ git reflog
1a75c1d... HEAD@{0}: reset --hard HEAD^: updating HEAD
f6e5064... HEAD@{1}: commit: added file2

$ git reset --hard f6e5064
HEAD is now at f6e5064... added file2

$ cat file2
added new file

Sie können im Beispiel sehen, dass die Datei2 als Ergebnis des Hard-Resets entfernt wurde, aber beim Zurücksetzen über den Reflog wieder eingefügt wurde.


1398
2017-08-22 04:36



Was Sie tun möchten, ist das sha1 des Commits anzugeben, das Sie wiederherstellen möchten. Sie können den sha1 durch Überprüfen des Reflog (git reflog) und dann machen

git reset --hard <sha1 of desired commit>

Aber warte nicht zu lange ... nach ein paar Wochen wird Git endlich sehen, dass Commit als nicht referenziert und lösche alle Blobs.


313
2017-08-09 05:30



Die Antwort ist in der detaillierten Antwort oben versteckt, Sie können einfach tun:

$> git reset --hard HEAD@{1}

(Siehe die Ausgabe von git reflog show)


123
2018-02-26 15:13



Es ist möglich, es wiederherzustellen, wenn Git noch keinen Müll gesammelt hat.

Verschaffen Sie sich einen Überblick über dangling commits mit fsck:

$ git fsck --lost-found
dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

Wiederherstellen der dangling commit mit Rebase:

$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

82
2017-08-22 06:11



Wenn Sie wirklich Glück haben, wie ich war, können Sie zurück in Ihren Texteditor gehen und "Rückgängig machen" drücken.

Ich weiß, das ist nicht wirklich eine richtige Antwort, aber es hat mir die Arbeit eines halben Tages erspart, also hoffe ich, dass es das Gleiche für jemand anderen tut!


33
2018-01-13 00:48



Beispiel für einen IRL-Fall:

$ git fsck --lost-found

Checking object directories: 100% (256/256), done.
Checking objects: 100% (3/3), done.
dangling blob 025cab9725ccc00fbd7202da543f556c146cb119
dangling blob 84e9af799c2f5f08fb50874e5be7fb5cb7aa7c1b
dangling blob 85f4d1a289e094012819d9732f017c7805ee85b4
dangling blob 8f654d1cd425da7389d12c17dd2d88d318496d98
dangling blob 9183b84bbd292dcc238ca546dab896e073432933
dangling blob 1448ee51d0ea16f259371b32a557b60f908d15ee
dangling blob 95372cef6148d980ab1d7539ee6fbb44f5e87e22
dangling blob 9b3bf9fb1ee82c6d6d5ec9149e38fe53d4151fbd
dangling blob 2b21002ca449a9e30dbb87e535fbd4e65bac18f7
dangling blob 2fff2f8e4ea6408ac84a8560477aa00583002e66
dangling blob 333e76340b59a944456b4befd0e007c2e23ab37b
dangling blob b87163c8def315d40721e592f15c2192a33816bb
dangling blob c22aafb90358f6bf22577d1ae077ad89d9eea0a7
dangling blob c6ef78dd64c886e9c9895e2fc4556e69e4fbb133
dangling blob 4a71f9ff8262701171d42559a283c751fea6a201
dangling blob 6b762d368f44ddd441e5b8eae6a7b611335b49a2
dangling blob 724d23914b48443b19eada79c3eb1813c3c67fed
dangling blob 749ffc9a412e7584245af5106e78167b9480a27b
dangling commit f6ce1a403399772d4146d306d5763f3f5715cb5a    <- it's this one

$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a

commit f6ce1a403399772d4146d306d5763f3f5715cb5a
Author: Stian Gudmundsen Høiland <stian@Stians-Mac-mini.local>
Date:   Wed Aug 15 08:41:30 2012 +0200

    *MY COMMIT MESSAGE IS DISPLAYED HERE*

diff --git a/Some.file b/Some.file
new file mode 100644
index 0000000..15baeba
--- /dev/null
+++ b/Some.file
*THE WHOLE COMMIT IS DISPLAYED HERE*

$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a

First, rewinding head to replay your work on top of it...
Fast-forwarded master to f6ce1a403399772d4146d306d5763f3f5715cb5a.

27
2017-08-15 07:01



Soweit ich weiss, --hard verwirft nicht festgeschriebene Änderungen. Da diese nicht von Git verfolgt werden. aber du kannst das rückgängig machen discarded commit.

$ git reflog

Willenslisten:

b0d059c HEAD@{0}: reset: moving to HEAD~1
4bac331 HEAD@{1}: commit: added level introduction....
....

woher 4bac331 ist der discarded commit.

Bewegen Sie jetzt den Kopf zu diesem Commit:

$ git reset --hard 4bac331

25
2018-04-02 08:57



In den meisten Fällen ja.

Abhängig von dem Status, in dem sich Ihr Repository befand, als Sie den Befehl ausgeführt haben, sind die Auswirkungen von git reset --hard kann von trivial bis zur rückgängigmachung reichen, bis praktisch unmöglich.

Im Folgenden habe ich eine Reihe verschiedener möglicher Szenarien aufgeführt und wie Sie diese wiederherstellen können.

Alle meine Änderungen wurden vorgenommen, aber jetzt sind die Commits weg!

Diese Situation tritt normalerweise beim Ausführen auf git reset mit einem Argument, wie in git reset --hard HEAD~. Mach dir keine Sorgen, das ist leicht zu erholen!

Wenn du gerade gelaufen bist git reset und seitdem nichts anderes getan hast, kannst du mit diesem One-Liner wieder dahin zurückkehren, wo du warst:

git reset --hard @{1}

Dadurch wird Ihre aktuelle Verzweigung zurückgesetzt, unabhängig davon, in welchem ​​Zustand sie sich vor der letzten Änderung befand (in Ihrem Fall wäre die letzte Änderung an der Verzweigung der Hard-Reset, den Sie rückgängig machen möchten).

Wenn Sie jedoch haben andere Änderungen an Ihrem Zweig seit dem Zurücksetzen gemacht haben, wird der oben genannte Einzeiler nicht funktionieren. Stattdessen sollten Sie laufen git reflog  <branchname> um eine Liste aller letzten Änderungen zu sehen, die an Ihrer Zweigstelle vorgenommen wurden (einschließlich Zurücksetzungen). Diese Liste sieht ungefähr so ​​aus:

7c169bd master@{0}: reset: moving to HEAD~
3ae5027 master@{1}: commit: Changed file2
7c169bd master@{2}: commit: Some change
5eb37ca master@{3}: commit (initial): Initial commit

Suchen Sie die Operation in dieser Liste, die Sie rückgängig machen möchten. Im obigen Beispiel wäre es die erste Zeile, die "Reset: Umzug nach HEAD ~" sagt. Kopieren Sie dann die Darstellung des Commits Vor (unten) diese Operation. In unserem Fall wäre das so master@{1}(oder 3ae5027, sie repräsentieren beide das gleiche commit) und laufen git reset --hard <commit> um den aktuellen Zweig auf dieses Commit zurückzusetzen.

Ich habe meine Änderungen mit inszeniert git add, aber nie begangen. Jetzt sind meine Änderungen weg!

Dies ist ein bisschen schwieriger zu erholen. Git tut Sie haben Kopien der Dateien, die Sie hinzugefügt haben, aber da diese Kopien nie an ein bestimmtes Commit gebunden waren, können Sie die Änderungen nicht auf einmal wiederherstellen. Stattdessen müssen Sie die einzelnen Dateien in der git-Datenbank suchen und sie manuell wiederherstellen. Sie können dies mit verwenden git fsck.

Einzelheiten hierzu finden Sie unter Rückgängig machen git reset --hard mit nicht übergebenen Dateien im Staging-Bereich.

Ich hatte Änderungen an Dateien in meinem Arbeitsverzeichnis, mit denen ich nie inszeniert habe git addund nie begangen. Jetzt sind meine Änderungen weg!

Oh oh. Ich hasse es, dir das zu sagen, aber du hast wahrscheinlich kein Glück. git speichert keine Änderungen, die Sie nicht hinzufügen oder festschreiben, und gemäß Dokumentation für git reset:

--hart

Setzt den Index und den Arbeitsbaum zurück. Änderungen an verfolgten Dateien im Arbeitsbaum seit <commit> werden verworfen.

Es ist möglich, dass Sie Macht in der Lage sein, Ihre Änderungen mit einer Art Festplattenwiederherstellungsdienstprogramm oder einem professionellen Datenwiederherstellungsdienst wiederherzustellen, aber zu diesem Zeitpunkt ist das wahrscheinlich mehr Ärger als es wert ist.


23
2018-01-16 18:37



Wenn Sie Ihr Repository noch nicht mit Müll gesammelt haben (z. B. mit git repack -d oder git gc, aber beachte, dass Garbage Collection auch automatisch passieren kann), dann ist deine Commit immer noch da - sie ist einfach nicht mehr über den HEAD erreichbar.

Sie können versuchen, Ihr Commit zu finden, indem Sie die Ausgabe von git fsck --lost-found.

Neuere Versionen von Git haben etwas namens "Reflog", das ein Protokoll aller Änderungen ist, die an den Referenzen vorgenommen werden (im Gegensatz zu Änderungen, die an den Inhalten des Repositories vorgenommen werden). So, zum Beispiel, jedes Mal, wenn Sie Ihren Kopf wechseln (d. H. Jedes Mal, wenn Sie a git checkout um Zweige zu wechseln), die protokolliert werden. Und natürlich deine git reset manipulierte auch den HEAD, also wurde es auch protokolliert. Sie können auf ältere Status Ihrer Referenzen ähnlich zugreifen, indem Sie auf einen älteren Status Ihres Repositorys zugreifen @ Zeichen anstelle von a ~, mögen git reset HEAD@{1}.

Ich brauchte eine Weile um zu verstehen, was der Unterschied zwischen HEAD @ {1} und HEAD ~ 1 ist, also hier eine kleine Erklärung:

git init
git commit --allow-empty -mOne
git commit --allow-empty -mTwo
git checkout -b anotherbranch
git commit --allow-empty -mThree
git checkout master # This changes the HEAD, but not the repository contents
git show HEAD~1 # => One
git show HEAD@{1} # => Three
git reflog

Damit, HEAD~1 bedeutet "Gehe zum Commit vor dem Commit, auf den HEAD momentan zeigt", while HEAD@{1} bedeutet "gehe zu dem Commit, auf den HEAD zeigte, bevor er auf den Punkt zeigte, auf den er gerade zeigt".

Das wird Ihnen leicht erlauben, Ihr verlorenes Commit zu finden und es wiederherzustellen.


20
2017-08-27 03:45



Ich weiß, dass dies ein alter Thread ist ... aber da viele Leute nach Wegen suchen, Dinge in Git rückgängig zu machen, denke ich immer noch, dass es eine gute Idee ist, hier weiter Tipps zu geben.

Wenn Sie in git gui einen "git add" ausführen oder etwas von links oben nach links bewegen, wird der Inhalt der Datei in einem Blob gespeichert und der Dateiinhalt kann von diesem Blob wiederhergestellt werden.

So ist es möglich, eine Datei wiederherzustellen, auch wenn sie nicht festgeschrieben wurde, aber hinzugefügt werden muss.

git init  
echo hello >> test.txt  
git add test.txt  

Jetzt wird das Blob erstellt, aber es wird vom Index referenziert, so dass es nicht mit git fsck aufgelistet wird, bis wir es zurücksetzen. Also wir zurücksetzen ...

git reset --hard  
git fsck  

Du wirst einen baumelnden Blob bekommen ce013625030ba8dba906f756967f9e9ca394464a

git show ce01362  

gibt dir den Dateiinhalt "Hallo" zurück

Um unreferenzierte Commits zu finden, habe ich irgendwo einen Tipp gefunden, der darauf hinweist.

gitk --all $(git log -g --pretty=format:%h)  

Ich habe es als Werkzeug in git gui und es ist sehr praktisch.


10
2018-01-20 06:27



Bevor Sie antworten, können Sie etwas Hintergrund hinzufügen und erklären, was das ist HEAD.

First of all what is HEAD?

HEAD ist einfach eine Referenz auf das aktuelle Commit (aktuell) der aktuellen Filiale.
Es kann nur einen einzigen geben HEAD jederzeit. (ohne git worktree)

Der Inhalt von HEAD ist innen gespeichert .git/HEAD und es enthält die 40 Bytes SHA-1 des aktuellen Commits.


detached HEAD

Wenn Sie nicht auf dem neuesten Commit sind - das heißt HEAD zeigt auf einen vorherigen Commit in der Geschichte seiner aufgerufenen detached HEAD.

enter image description here

In der Befehlszeile sieht es wie folgt aus: SHA-1 anstelle des Zweignamens seit dem HEAD zeigt nicht auf die Spitze des aktuellen Zweiges

enter image description here


Einige Optionen zum Wiederherstellen von einem getrennten HEAD:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Dadurch wird der neue Zweig, der auf den gewünschten Commit zeigt, ausgecheckt.
Dieser Befehl wird zu einem gegebenen Commit auschecken.
An dieser Stelle können Sie eine Verzweigung erstellen und von diesem Punkt an arbeiten.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Sie können immer die reflog auch.
git reflog zeigt alle Änderungen an, die das Update aktualisiert haben HEAD und das Auschecken des gewünschten Reflog-Eintrags setzt den HEAD zurück zu diesem Commit.

Jedes Mal, wenn der HEAD geändert wird, erscheint ein neuer Eintrag in der reflog

git reflog
git checkout HEAD@{...}

Dies bringt Sie zurück zu Ihrem gewünschten Commit

enter image description here


git reset HEAD --hard <commit_id>

Bewegen Sie Ihren Kopf zurück zum gewünschten Commit.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
  • Hinweis: (Seit Git 2.7)
    Sie können auch die git rebase --no-autostash auch.


git revert <sha-1>

"Rückgängig" den angegebenen Commit oder Commit-Bereich.
Der Reset-Befehl "rückgängig" macht alle Änderungen, die an dem gegebenen Commit vorgenommen wurden.
Ein neues Commit mit dem Rückgängig-Patch wird ausgeführt, während das ursprüngliche Commit auch im Verlauf verbleibt.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Dieses Schema veranschaulicht, welcher Befehl was macht.
Wie Sie dort sehen können reset && checkout modifiziere den HEAD.

enter image description here


4
2018-04-21 16:30