Ist es möglich, die durch den folgenden Befehl verursachten Änderungen rückgängig zu machen? Wenn ja, wie?
git reset --hard HEAD~1
Ist es möglich, die durch den folgenden Befehl verursachten Änderungen rückgängig zu machen? Wenn ja, wie?
git reset --hard HEAD~1
Wenn Sie Ihr Repository noch nicht in den Müll geworfen haben (z. B. mit git repack -d
o git gc
(aber beachten Sie, dass die Garbage Collection auch automatisch erfolgen kann), dann ist Ihr Commit immer noch da - er ist nur nicht mehr über den HEAD erreichbar.
Sie können versuchen, Ihren Commit zu finden, indem Sie sich die Ausgabe von git fsck --lost-found
.
Neuere Versionen von Git verfügen über ein so genanntes "reflog", das alle Änderungen an den Referenzdateien protokolliert (im Gegensatz zu den Änderungen am Inhalt des Repositorys). So wird zum Beispiel jedes Mal, wenn Sie Ihren HEAD wechseln (d.h. jedes Mal, wenn Sie eine git checkout
zu wechseln), die protokolliert werden. Und, natürlich, Ihr git reset
manipulierte auch den HEAD, so dass dies ebenfalls protokolliert wurde. Sie können auf ältere Zustände Ihrer Refs auf ähnliche Weise zugreifen wie auf ältere Zustände Ihres Repositorys, indem Sie eine @
Zeichen anstelle eines ~
, wie git reset HEAD@{1}
.
Es hat eine Weile gedauert, bis ich den Unterschied zwischen HEAD@{1} und HEAD~1 verstanden habe, deshalb 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
Also, HEAD~1
bedeutet "Gehe zu dem Commit vor dem Commit, auf das HEAD gerade zeigt", während HEAD@{1}
bedeutet: "Gehe zu der Übergabe, auf die HEAD gezeigt hat, bevor er auf den aktuellen Punkt gezeigt hat".
So können Sie Ihre verlorene Übertragung leicht finden und wiederherstellen.
Eine andere Erklärung, die meiner Meinung nach klarer wäre: HEAD~1 bedeutet "zum Elternteil von HEAD gehen", während HEAD@{1} "einen Schritt zurück in der Geschichte von HEAD gehen" bedeutet.
Das Problem ist, dass der Begriff "Geschichte" in VCS wirklich überladen ist. Eine andere Möglichkeit, dies auszudrücken, wäre, dass ~ rückwärts geht in Geschichte schreiben , während @ rückwärts in chronologische oder zeitliche Geschichte . Aber keine der drei Versionen ist besonders gut.
Bevor wir antworten, sollten wir einige Hintergrundinformationen hinzufügen, um zu erklären, was dies ist HEAD
.
First of all what is HEAD?
HEAD
ist einfach ein Verweis auf die aktuelle Übertragung (latest) auf dem aktuellen Zweig.
Es kann nur eine einzige HEAD
zu jedem beliebigen Zeitpunkt. (ausgenommen git worktree
)
Der Inhalt von HEAD
ist gespeichert in .git/HEAD
und enthält die 40 Bytes SHA-1 der aktuellen Übertragung.
detached HEAD
Wenn Sie nicht auf dem neuesten Stand sind - was bedeutet, dass HEAD
auf eine frühere Übertragung in der Historie verweist, heißt es detached HEAD
.
In der Befehlszeile sieht es dann so aus - SHA-1 anstelle des Zweignamens, da die HEAD
nicht auf die Spitze des aktuellen Zweigs zeigt
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 ein neuer Zweig ausgecheckt, der auf den gewünschten Commit verweist.
Dieser Befehl führt einen Checkout zu einem bestimmten Commit durch.
An dieser Stelle können Sie eine Verzweigung erstellen und ab diesem Punkt mit der Arbeit beginnen.
# 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 jederzeit die reflog
auch.
git reflog
werden alle Änderungen angezeigt, die die HEAD
und das Auschecken des gewünschten Reflog-Eintrags setzt die HEAD
zurück zu diesem Commit.
Jedes Mal, wenn der HEAD geändert wird, wird ein neuer Eintrag in der reflog
git reflog
git checkout HEAD@{...}
So gelangen Sie zurück zu Ihrer gewünschten Verpflichtung
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.
git rebase --no-autostash
auch.git revert <sha-1>
"Rückgängig machen" des angegebenen Commits oder Commit-Bereichs.
Der Befehl reset macht alle Änderungen, die in der gegebenen Übertragung vorgenommen wurden, "rückgängig".
Ein neuer Commit mit dem rückgängig gemachten Patch wird übertragen, während der ursprüngliche Commit ebenfalls in der Historie 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 tut.
Wie Sie sehen können, gibt es reset && checkout
ändern die HEAD
.
Es scheint, dass Ihr git reset HEAD --hard <commit_id>
Das Beispiel stammt aus stackoverflow.com/questions/4114095/ - Wenn das der Fall ist, könnten Sie bitte die Quellenangabe einfügen?
Ich weiß, dass dies ein alter Thread ist... aber da viele Leute nach Möglichkeiten suchen, Dinge in Git rückgängig zu machen, denke ich, dass es immer noch eine gute Idee sein kann, hier weiterhin Tipps zu geben.
Wenn Sie ein "git add" ausführen oder in der Git-GuI etwas von links oben nach links unten verschieben, wird der Inhalt der Datei in einem Blob gespeichert, und der Inhalt der Datei kann aus diesem Blob wiederhergestellt werden.
Es ist also möglich, eine Datei wiederherzustellen, auch wenn sie nicht übertragen wurde, aber hinzugefügt worden sein muss.
git init
echo hello >> test.txt
git add test.txt
Jetzt ist der Blob erstellt, aber er wird vom Index referenziert, so dass er mit git fsck nicht aufgelistet wird, bis wir ihn zurücksetzen. Wir setzen also zurück...
git reset --hard
git fsck
erhalten Sie einen baumelnden Klecks ce013625030ba8dba906f756967f9e9ca394464a
git show ce01362
gibt Ihnen den Inhalt der Datei "hello" zurück
Um nicht referenzierte Commits zu finden, habe ich irgendwo einen Tipp gefunden, der dies vorschlägt.
gitk --all $(git log -g --pretty=format:%h)
Ich habe es als Werkzeug in der Git-GUI und es ist sehr praktisch.
Ich habe ein kleines Skript erstellt, um das Auffinden des gesuchten Commits etwas zu erleichtern:
git fsck --lost-found | grep commit | cut -d ' ' -f 3 | xargs -i git show \{\} | egrep '^commit |Date:'
Ja, man kann es mit awk oder ähnlichem wesentlich hübscher machen, aber es ist einfach und ich brauchte es einfach. Vielleicht spart jemand anderes 30 Sekunden.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
15 Stimmen
Ich habe eine vollständige Anleitung zur Wiederherstellung eines verlorenen Commits mit Git geschrieben. Es gibt sogar Illustrationen :-) [Check it out][fixLink] [fixLink]: programblings.com/2008/06/07/
39 Stimmen
--hard
verwirft unbestätigte Änderungen. Da diese nicht von Git verfolgt werden, gibt es keine Möglichkeit, sie mit Git wiederherzustellen.0 Stimmen
stackoverflow.com/questions/34519665/
1 Stimmen
Este ist ein großartiger Artikel, der Sie bei der Wiederherstellung Ihrer Dateien unterstützt.
2 Stimmen
Dies ist eine großartige Ressource direkt von Github: Wie man (fast) alles mit Git rückgängig macht
0 Stimmen
Vergessen Sie nicht Ihren Terminal-Zeilenpuffer, wenn Sie vor kurzem git diff ausgeführt haben. Das hat mich gerade gerettet.
0 Stimmen
Sehen Sie sich das an: youtube.com/watch?v=MijDnC4mz9w . Es hat meine Situation wirklich gerettet!!
0 Stimmen
Vielleicht kann man darüber streiten, aber ich neige dazu, diese Frage als ein Duplikat von stackoverflow.com/q/2510276 .
0 Stimmen
Wenn Sie eine IDE wie PHPStorm verwenden, können Sie mit Heimatkunde um sie rückgängig zu machen.
0 Stimmen
@Zaz Die Aussage "
--hard
verwirft nicht übermittelte Änderungen" ist nicht uneingeschränkt korrekt. Staged, uncommitted changes sind Git bekannt und können als dangling blobs identifiziert werden, wie in einigen der Antworten hier erwähnt.0 Stimmen
Für diejenigen, die das Pech hatten, die Änderungen nicht zu übertragen und alle ihre lokalen Änderungen zu verlieren. Sie können die geänderten Dateien immer noch wiederherstellen, indem Sie die Änderungen im Editor rückgängig machen.