525 Stimmen

Wie kann ich einen verlorenen Commit in Git wiederherstellen?

Zuerst bekam ich "Ihr Zweig ist dem Original/Master um 3 Commits voraus", dann ist meine App zu einem früheren Zeitpunkt mit früheren Änderungen zurückgekehrt.

Wie kann ich das, was ich in den letzten 11 Stunden getan habe, zurückbekommen?

1146voto

Amber Punkte 473552

git reflog ist Ihr Freund. Suchen Sie in der Liste die Übergabe, bei der Sie dabei sein wollen, und setzen Sie sie zurück (z. B.: git reset --hard e870e41 ).

(Wenn Sie Ihre Änderungen nicht übertragen haben... könnten Sie in Schwierigkeiten geraten - übertragen Sie früh und oft!)

200voto

CodeWizard Punkte 108377

Bevor wir antworten, sollten wir einige Hintergrundinformationen geben und erklären, was diese HEAD ist.

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 einem bestimmten Zeitpunkt (außer 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 .

Enter image description here

In der Befehlszeile sieht es dann so aus - SHA-1 anstelle des Zweignamens, da die HEAD nicht auf die Spitze des aktuellen Zweigs zeigt:

Enter image description here

Enter image description here


Ein paar Möglichkeiten, wie man sich von einem abgetrennten HEAD erholen kann:


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 kommen Sie zurück zu Ihrer gewünschten Verpflichtung

Enter image description here


_git reset --hard <commit_id>_

"Bewegen" Sie Ihren HEAD 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.
  • Anmerkung: ( Seit Git 2.7 ) können Sie auch die 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 a 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 bewirkt.
Wie Sie dort sehen können, reset && checkout ändern die HEAD .

Enter image description here

60voto

Atri Punkte 5321

Eine andere Möglichkeit, zur gelöschten Übergabe zu gelangen, ist mit der git fsck Befehl.

git fsck --lost-found

Dadurch wird etwas wie in der letzten Zeile ausgegeben:

dangling commit xyz

Wir können überprüfen, ob es sich um dieselbe Übertragung handelt, indem wir reflog wie in anderen Antworten vorgeschlagen. Jetzt können wir eine git merge

git merge xyz


Wir können den Commit nicht zurückholen mit fsck wenn wir bereits eine git gc Befehl, der den Verweis auf die "Dangling Commit" entfernt.

20voto

zean_7 Punkte 156

Das ist mir gerade heute passiert, und deshalb schreibe ich hier, was sich für mich als Lebensretter erwiesen hat. Meine Antwort ist der von @Amber sehr ähnlich.

Zuerst habe ich eine git reflog und suchte nach dem Hash dieses bestimmten Commits, kopierte dann einfach diesen Hash und führte eine git cherry-pick <hash> aus dieser Branche. Dies brachte alle Änderungen aus dem verlorenen Commit in meinen aktuellen Zweig und stellte mein Vertrauen in GIT wieder her.

Einen schönen Tag noch!

17voto

Micheal Shoyemi Punkte 61

Verwenden Sie zunächst git reflog, um alle Ihre Commits aufzulisten, auch den verlorenen Commit

git reflog

Verwenden Sie dann git log HEAD@{Ihre_commit_number}, um die gesuchte Übergabe zu finden.

git log HEAD@{17}

Checken Sie in den Commit ein, nachdem Sie ihn mit git checkout HEAD@{Ihre_commit_nummer} gefunden haben, z. B.

git checkout HEAD@{17}

Möglicherweise müssen Sie Ihre Änderungen hinzufügen und festschreiben

git add .
git commit -m"quuck_fix"

Dann müssen Sie einen temporären Zweig erstellen, um die Übergabe in Ihrem Zweig wiederherzustellen

git branch temp

Zum Schluss checken Sie in Ihren bestehenden Zweig aus und führen den temporären Zweig zusammen.

#git checkout <your_existing_branch> e.g

git checkout main
git merge temp

CodeJaeger.com

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.

Powered by:

X