GIT stellt zuletzt abgelösten HEAD wieder her

84

Bitte, ich habe ein großes Problem in meinem Projekt: Dies ist das Szenario. Ich habe ein Xcode-Projekt unter GIT. Heute habe ich festgestellt, dass das letzte Commit einige Tests gebrochen hat, also habe ich das vorherige Commit überprüft. Ich habe SourceTree verwendet und dies ist die Warnung

Wenn Sie dies tun, wird Ihre Arbeitskopie zu einem "abgetrennten KOPF", was bedeutet, dass Sie sich nicht mehr in einem Zweig befinden. Wenn Sie danach ein Commit durchführen möchten, möchten Sie wahrscheinlich entweder einen Zweig erneut auschecken oder einen neuen Zweig erstellen. Ist das ok?

Ich habe einen ganzen Tag gearbeitet und am Ende alles getan. Also musste ich meine Arbeit am Entwicklungszweig zusammenführen, damit ich den Entwicklungszweig auscheckte und ... meine Arbeit verschwand sofort :(

Ich weiß, dass es falsch war, meinen KOPF abzunehmen, und Sourcetree hat mich gewarnt ... aber gibt es eine Möglichkeit, meine Arbeit wiederherzustellen?

IgnazioC
quelle
Ein verwandter Thread für das gleiche Problem hier und die technischen Details dazu, wie es hier passiert .
RBT

Antworten:

253

Wenn Sie eingeben git reflog, wird Ihnen der Verlauf der Revisionen HEADangezeigt, auf die verwiesen wurde. Ihr losgelöster Kopf sollte dort drin sein. Wenn Sie es gefunden haben, tun Sie git checkout -b my-new-branch abc123oder git branch my-new-branch abc123(wo abc123ist der SHA-1 des abgetrennten KOPFES), um einen neuen Zweig zu erstellen, der auf Ihren abgetrennten Kopf zeigt. Jetzt können Sie diesen Zweig nach Belieben zusammenführen.

Wenn Sie einen Zweig nach der Arbeit an einem abgetrennten Kopf auschecken, sollte Git Ihnen im Allgemeinen das Commit von dem abgetrennten Kopf mitteilen, auf dem Sie sich befunden haben, damit Sie ihn bei Bedarf wiederherstellen können. Ich habe SourceTree noch nie verwendet, daher weiß ich nicht, ob es diese Nachricht weiterleitet. Wenn diese Nachricht jedoch angezeigt wurde, sollten Sie sie verwenden können, um das Commit zu finden, und erneut einen Zweig aus diesem Commit verwenden git checkout -boder git brancherstellen.

Brian Campbell
quelle
4
Vielen Dank, Brian. Du hast meinen Tag gerettet.
Muzammil
Brian, du hast mein Leben gerettet! Vielen Dank!!
Cldrr
Ich bin neu in Git .. Ich bekomme fatal: A branch named 'mybranch' already exists.Wie in bestehenden Zweig hinzufügen?
Ramesh Murugesan
1
Als PSA für alle, die sich bei Brian bedanken: Wenn Sie Arbeiten ausführen, die Sie nicht verlieren möchten, schieben Sie sie alle paar Stunden auf eine Fernbedienung (z. B. Github). Wenn ein Meteor auf Ihren Computer fällt, werden Sie es nicht bereuen. Wenn Sie noch nicht bereit sind, es mit Mitarbeitern zu teilen, legen Sie es einfach in einem Zweig ab, von dem derzeit niemand weiß, und leiten Sie es später erneut an den Master weiter.
MatrixManAtYrService
1
Wenn es sich um ein einzelnes verlorenes Commit handelt, das gerade verschwunden ist und Sie es dort gefunden haben, können Sie es mit zurückbringen git cherry-pick e5b2f7b, wo e5b2f7bsich der SHA-1 des Commits dort befindet.
Aidin
10

In Sourcetree können Sie dies über die GUI tun.

Suchen Sie zuerst das "verlorene" Commit, indem Sie im Befehlsverlauf nach einer Nachricht suchen (Ansicht: Befehlsausgabe anzeigen). Es wird wahrscheinlich im Befehl "Switching Branch" nach dem Commit sein, das Sie verloren haben. In dieser Nachricht wird hoffentlich der Festschreibungskommentar mit einer Festschreibungs-ID von 1234567 angezeigt.

Nehmen Sie diese Commit-ID mit dem nächsten Schritt.

Klicken Sie auf die Schaltfläche "Verzweigen" in der oberen Symbolleiste und Sie sollten ein Dialogfeld "Neuer Zweig" erhalten, in dem Sie ein bestimmtes Commit angeben können. Geben Sie diese Commit-ID dort ein, geben Sie einen neuen Zweigstellennamen an, klicken Sie auf Zweig erstellen und Sie sollten einen neuen Zweig mit Ihrem verlorenen Commit erhalten!

Geben Sie hier die Bildbeschreibung ein

blalond
quelle
funktioniert tatsächlich. Stellen Sie sicher, dass Sie den richtigen Kommentar mit der Festschreibungs-ID sehen.
Hammad Khan
@blalond Hallo, nachdem ich Ihre Antwort gelesen habe, habe ich eine kleine Frage: Wenn ich in SourceTree auf ein vorheriges Commit doppelklicke (um es zu überprüfen), erhalte ich die gleiche Meldung, dass dies einen abgetrennten Kopf verursachen würde, also frage ich mich Was bedeutet es, wenn Leute sagen, dass Sie mit git einfach zu einer früheren Revision zurückkehren können? Wie rolle ich dann zu einem bestimmten Commit zurück? Danke
5

Wenn Sie keine Änderungen am getrennten HEAD beibehalten möchten und zum neuesten Branch Commit wechseln möchten, verwenden Sie den folgenden Befehl direkt.

git checkout - 

Hinweis: Ich werde alle Ihre Änderungen im abgetrennten HEAD löschen.

Wüstenrose
quelle
Das OP hat darum gebeten, ihre Arbeit beizubehalten. Dies beantwortet nicht die ursprüngliche Frage. Das Hinzufügen der Option, dies in einem Zweig zu behalten, würde diese Antwort nützlich machen.
Manuelvigarcia
1

Ein Kollege von mir hatte gerade diese Situation. In seinem Fall gab es Commits in losgelöstem Kopf - sie arbeiten in R-Studio - und das Tool warnte sie, dass sie den Zweig mit dieser und jener SHA-Referenz erstellen könnten ... aber da die einzige Option "Schließen" war. --duh !! Es war eine Infobox - sie schlossen den Dialog und verloren die Informationen für immer ...

Dank des reflogBefehls konnten wir sehen, dass die Änderungen nicht verloren gingen. Aber in unserem Fall hat das git branchnicht wie erwartet funktioniert ... oder ein Eingang git pullhat es irgendwie durcheinander gebracht. Wir mussten die Änderungen vom Reflog zum neu erstellten Zweig fischen:

 git cherry-pick 0b823d42..3cce27fc

das platzierte alle Commits, die wir in der Niederlassung wollten. Dann könnten wir den Zweig developohne Probleme zusammenführen.

Nur für den Fall, dass dies für irgendjemanden informativ ist, haben wir die Commits auf dem abgetrennten Kopf in der identifiziert, indem wir uns reflogdie zwischen den mit "checkout" gekennzeichneten Commits angesehen haben (die die Zweigverschiebung identifizieren):

e09f183b HEAD@{3}: pull: Fast-forward
b5bf3e1d HEAD@{4}: checkout: moving from lost_changes to develop
b5bf3e1d HEAD@{5}: checkout: moving from 3cce27fca50177a288df0252f02edd5da5ee64fd to lost_changes
3cce27fc HEAD@{6}: commit: add statistics
417a99a4 HEAD@{7}: commit: add test
0b823d42 HEAD@{8}: commit: new utility class
d9ea8a63 HEAD@{9}: checkout: moving from develop to d9ea8a635d4c2349fcb05b3339a6d7fad5ae2a09
b5bf3e1d HEAD@{10}: pull: Fast-forward

Diejenigen , wollten wir waren HEAD@{8}auf HEAD@{6}(beide inklusive). Also haben wir sie bekommen von:

git cherry-pick 0b823d42..3cce27fc

Dann ließen uns die üblichen Zusammenführungslösungen und das endgültige Festschreiben mit branch lost_changes zurück, in denen die Arbeit mit losgelöstem Kopf gehostet wurde, die wir für verloren hielten. Diesmal war es ein schneller Vorlauf, dies in die Entwicklung zu integrieren.

manuelvigarcia
quelle
0

Ich habe dieses Szenario ausprobiert und finde, dass Git mir SHA-1 vom letzten Commit erzählt:

vors@localhost:~/git-test$ git checkout master 
Warning: you are leaving 1 commit behind, not connected to
any of your branches:

  ec600e6 333

If you want to keep them by creating a new branch, this may be a good time
to do so with:

 git branch new_branch_name ec600e6eb2473dd4f3732539c5c1fa5829f631b7

Switched to branch 'master'

Hast du diese Nachricht gesehen?

xvorsx
quelle
Nein. oder vielleicht achte ich nicht darauf. Ich suche nach einem Backup auf Timemachine; (
IgnazioC
1
@IgnazioC Sie müssen sich kein Backup ansehen. Hast du dir meine Antwort angesehen? git reflogsollte Ihnen zeigen, was Sie brauchen.
Brian Campbell
0

Abgenommener Kopf ist in Ordnung, solange Sie keine Änderung vornehmen möchten.

Wenn Sie ein Commit zurücksetzen möchten, können Sie git revert für einen bestimmten Zweig verwenden

Wenn Sie den abgetrennten Kopf abarbeiten und Commits ausführen möchten; Erstellen Sie einen neuen Zweig (und führen Sie ihn später zusammen).

forvaidya
quelle
Ja! Wir kennen die Regeln. Aber wenn die Kollegen den abgetrennten Kopf abarbeiten und dann diese Commits verlassen, fragen sie nach Antworten, nicht nach Regeln.
Manuelvigarcia
0
  1. Führen Sie zunächst git reflogden Verlauf aus.
  2. Die älteste Revision ist die letzte in der Liste.
  3. git checkout -b temp e35d2b3Wechseln Sie hier zu Ihrem gewünschten Commit. E35dd23 ist der Hash-Wert Ihres Commits.
  4. Das ist es. Jetzt einfach git hinzufügen. etc....

Akzeptieren Sie es als Antwort, wenn es Ihr Problem löst. Ansonsten teilen Sie bitte Ihren Kommentar.

Sohaib
quelle