wake-up-neo.net

Ein altes Commit auschecken und den Kopf in der Hauptniederlassung beibehalten?

Zur Zeit für den Wechsel zu einem anderen Git-Commit (auf demselben Zweig ... eigentlich auf dem Hauptzweig!), Führe ich den Befehl aus

git checkout ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a

Nun, jedes Mal, wenn ich es tue, sagt mir dieser Idiot, dass ich jetzt einen abgetrennten Kopf habe. Wie gehe ich zu einem älteren Commit und halte den Kopf in derselben Branche?

83

Wenn ich dies tue, checke ich meistens einen temporären Zweig aus:

git checkout -b temp-branch-name ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a

Nachdem ich fertig bin, lösche ich einfach den Zweig 

188
Nick Canzoneri

Es hängt davon ab, was Sie tun möchten, wenn Sie dieses Commit abschließen. Wenn Sie es nur überprüfen, damit Sie diese Revision erstellen oder testen können, gibt es nichts Falsches daran, mit einem abgetrennten Kopf zu arbeiten. Denken Sie daran, einen tatsächlichen Zweig auszuchecken, bevor Sie ein Commit ausführen (beispielsweise git checkout master), damit Sie keine Commits erstellen, die in keinem Zweig enthalten sind.

Wenn Sie jedoch ab diesem Zeitpunkt mehr Commits ausführen möchten, sollten Sie einen Zweig erstellen. Wenn Sie Commits machen, die nicht von einem Zweig referenziert werden, können sie leicht verloren gehen und schließlich von gits Garbage-Collector bereinigt werden, da sich nichts auf sie bezieht. Sie können einen neuen Zweig erstellen, indem Sie Folgendes ausführen: 

git checkout -b newbranch ea3d5ed

Um die Visualisierung zu vereinfachen, zeigen einige Diagramme, wie sich die Arbeit an einem getrennten Kopf von der Arbeit an einem Zweig unterscheidet.

Beginnen wir mit 3 Commits für master, A, B und C. master ist der aktuelle Zweig, daher zeigt HEAD auf master, was auf das Commit C verweist.

 A B C 
 * - * - * <- Master <- HEAD 

Wenn wir jetzt ein Commit ausführen, erstellt git ein Commit mit C als übergeordnetem Element (da dies das aktuelle Commit ist, auf das von HEAD über master verwiesen wird), und aktualisiert master, um auf das neue Commit zu verweisen. Alle unsere Commits befinden sich jetzt in master, und HEAD zeigt auf das neue Commit über master.

 A B C D 
 * - * - * - * <- master <- HEAD 

Schauen wir uns B an und geben uns eine HEAD.

 A B C D 
 * - * - * - * <- master 
 ^ 
 \-- KOPF

Alles funktioniert gut hier; Wir können alle Dateien ansehen, unser Programm erstellen, testen usw. Wir können sogar neue Commits erstellen. Wenn wir dies tun, gibt es keinen Zweig, in dem wir uns befinden, und wir können keinen Zweig auf dieses neue Commit zeigen. Das einzige, was darauf zeigt, ist HEAD:

 A B C D 
 * - * - * - * <- master 
\
 * <- KOPF 
 E 

Wenn wir uns später noch einmal für master entscheiden, wird sich nichts auf E beziehen. 

 A B C D 
 * - * - * - * <- master <- HEAD 
\
 * 
 E 

Da es nichts gibt, was sich darauf bezieht, kann es schwierig sein, es zu finden, und git hält fest, dass Commits ohne Verweise aufgegeben werden müssen (diese treten sehr häufig auf, wenn Sie Patches rebasieren, Squash-Patches verwenden oder andere lustige Verlaufsmanipulationen durchführen) dass Sie sich nicht mehr interessieren). Nach einer gewissen Zeit wird git es als Müll betrachten, der bei der nächsten Ausführung der Speicherbereinigung verworfen wird.

Anstatt also eine nackte Revision auszuprobieren und einen abgehobenen Kopf zu bekommen, sollten Sie, wenn Sie das Gefühl haben, weitere Commits zu machen, git checkout -b branch B verwenden, um einen Zweig zu erstellen und auszuprobieren. Jetzt gehen Ihre Commits nicht verloren, da sie in einem Zweig enthalten sind, auf den Sie sich leicht beziehen und später zusammenführen können.

 A B C D 
 * - * - * - * <- master 
 ^ 
\- Zweig <- KOPF 

Wenn Sie dies vergessen und Commits für einen Zweig erstellen, müssen Sie sich keine Sorgen machen. Sie können mit git checkout -b branch einen Zweig erstellen, der auf die Kopfrevision verweist. Wenn Sie bereits zum Zweig master gewechselt haben und feststellen, dass Sie ein verirrtes Commit vergessen haben, können Sie es mit git reflog finden. Dort wird Ihnen eine Historie angezeigt, worauf sich HEAD in den letzten Tagen festgelegt hat. Alles, was sich noch im Reflog befindet, wird nicht aufgefangen, und im Allgemeinen werden Referenzen mindestens 30 Tage im Reflog aufbewahrt.

78
Brian Campbell

Wenn Sie einfach zu einem früheren Commit zurückkehren möchten, ohne etwas zu ändern, können Sie dies tun

git co <previous-commit-id>

nach diesem Befehl befinden Sie sich in einem Zweig namens "(kein Zweig)".

Bestätigen Sie dies mit

git br

Nachdem Sie mit diesem zuvor festgelegten Code gespielt haben, können Sie zu dem Zweig wechseln, in dem Sie sich befanden

git co <the-branch-you-were-on>

Das "(kein Zweig)" wird automatisch gelöscht. Auf diese Weise müssen Sie keinen temporären Zweig erstellen.

7
Zack Xu

Git's HEAD ist einfach ein Zeiger, der angibt, was sich im Arbeitsverzeichnis befindet. Wenn Sie ein Commit auschecken möchten, bei dem es sich nicht um den Kopf einer Zweigstelle handelt, müssen Sie einfach Ihren HEAD umleiten, um auf dieses Commit zu verweisen. Daran führt kein Weg vorbei. Sie können bei diesem Commit einen temporären Zweig erstellen, aber HEAD wird trotzdem vom Master abgewiesen.

Das ist die kurze Erklärung. Die folgende Verbosität wird hoffentlich helfen zu verstehen, wie HEAD und Master sich unterscheiden:

Normalerweise sehen die Dinge so aus:

C ← refs/heads/master ← HEAD 
↓
B
↓
A

Das heißt: „Das übergeordnete Element von C ist B und das übergeordnete Element von B ist A. Der Zweigmaster zeigt auf C, und ich habe derzeit den Inhalt von Master ausgecheckt. Wenn ich mich verpflichte, muss der Master außerdem aktualisiert werden. “

Dies schließt einige Annahmen ein, die für ein gründliches Verständnis des Commitgraphen erforderlich sind. Commits beziehen sich nämlich nur auf ihre Eltern, und der Inhalt eines Zweigs sind die Commits (und nur die Commits), die durch Folgen der übergeordneten Links erreicht werden können. Der (nicht modifizierte) Inhalt des Arbeitsbaums und des Index muss dem von HEAD benannten Commit entsprechen, entweder indirekt ("symbolisch") oder direkt ("detached").

Wenn Sie also ein altes Commit auschecken möchten, muss HEAD aktualisiert werden, um auf das gewünschte Commit zu verweisen. git-checkout macht genau das:

C ← refs/heads/master 
↓
B ← HEAD
↓
A

Jetzt haben Sie Ihren Zweig hinter sich gelassen, da Sie etwas Altes betrachten. Das ist vollkommen in Ordnung, da der Ratschlag zu "freistehendem Kopf" Ihnen ruhig sagt (Hervorhebung meines):

Sie können sich umsehen, experimentelle Änderungen vornehmen und sie festschreiben, und Sie können alle in diesem Status abgegebenen Commits verwerfen ohne Auswirkungen auf die Verzweigungen , indem Sie eine weitere Überprüfung durchführen.

Auf der anderen Seite, während das Zurücksetzen Ihres Zweigs auch HEAD dorthin führt, wo es sein muss, hätte dies einen ganz anderen Effekt!

C
↓
B ← refs/heads/master ← HEAD
↓
A

Das Commit-C wird zu Müll, da Sie erklärt haben, dass Sie nicht mehr möchten, dass es zum Master-Zweig gehört.

Kurz gesagt, alles, was Sie tun müssen, ist zu verstehen, was Git mit "KOPF" bedeutet - es ist, wo Sie sich befinden, und nicht, wo sich ein Zweig befindet. Und wenn you nicht dasselbe ist wie ein Zweig, gibt es keine andere Wahl, als einen getrennten HEAD zu verwenden.

(Vielleicht schauen Sie auch in GitHub, gitk oder gitweb nach dem Commit-Verlauf, wenn Sie HEAD weiterhin entgleisen.)

5
Josh Lee

Die Frage ist etwas vage, aber wenn Sie nur Dateien in Ihrem Arbeitsbaum ändern möchten, können Sie dies einfach tun:

git checkout [commit|branch] -- .

Sie können dann die Änderungen in Szene setzen und bei Bedarf ein neues Commit erstellen. Das ist manchmal ziemlich nützlich.

1
Lari Hotari

Ich glaube, ich verstehe deine Fragen. Hier ist, was ich gefunden habe, um es zu lösen. Es gibt keine GUI-Lösung, Sie können nur den Befehl verwenden, um es zu lösen, und es ist wirklich einfach.

schritt 1: Erstellen Sie ein Tag des alten Commits, zu dem Sie zurückkehren möchten.

wie Tag v2.0

schritt 2: git checkout v2.0

hier ist es nun, jetzt zeigt Ihr HEAD auf 'v2.0', aber der Master zeigt immer noch auf das letzte Commit.

C:\Program Files\Git\doc\git\html\git-checkout.html dieses dokument kann ihnen helfen 

oder git help <checkout> eingeben

0
Lion Lai