Sie sehen die Git-Dokumentation, die Dinge wie sagt
Der Zweig muss vollständig in HEAD zusammengeführt werden.
Aber was HEAD
genau ist Git ?
Sie sehen die Git-Dokumentation, die Dinge wie sagt
Der Zweig muss vollständig in HEAD zusammengeführt werden.
Aber was HEAD
genau ist Git ?
Antworten:
Sie können sich den HEAD als "aktuellen Zweig" vorstellen. Wenn Sie Zweige mit wechseln git checkout
, ändert sich die HEAD-Revision so, dass sie auf die Spitze des neuen Zweigs zeigt.
Sie können sehen, worauf HEAD zeigt, indem Sie Folgendes tun:
cat .git/HEAD
In meinem Fall lautet die Ausgabe:
$ cat .git/HEAD
ref: refs/heads/master
HEAD kann auf eine bestimmte Revision verweisen, die keinem Zweigstellennamen zugeordnet ist. Diese Situation wird als losgelöster KOPF bezeichnet .
Um andere Leute zu zitieren :
Ein Kopf ist einfach eine Referenz auf ein Festschreibungsobjekt. Jeder Kopf hat einen Namen (Filialname oder Tag-Name usw.). Standardmäßig befindet sich in jedem Repository ein Kopf namens master. Ein Repository kann eine beliebige Anzahl von Köpfen enthalten. Zu jedem Zeitpunkt wird ein Kopf als "aktueller Kopf" ausgewählt. Dieser Kopf ist auf HEAD ausgerichtet, immer in Großbuchstaben. "
Beachten Sie diesen Unterschied: Ein „Kopf“ (Kleinbuchstaben) bezieht sich auf einen der genannten Köpfe im Repository. "HEAD" (Großbuchstaben) bezieht sich ausschließlich auf den aktuell aktiven Kopf. Diese Unterscheidung wird häufig in der Git-Dokumentation verwendet.
Eine weitere gute Quelle, die schnell das Innenleben von Git (und damit ein besseres Verständnis von Köpfen / KOPF) abdeckt, finden Sie hier . Verweise (Ref. :) oder Köpfe oder Zweige können als Haftnotizen betrachtet werden, die auf Commits im Commit-Verlauf geklebt sind. Normalerweise zeigen sie auf die Spitze einer Reihe von Commits, aber sie können mit git checkout
oder git reset
usw. verschoben werden .
git checkout HEAD~2
), bei der es sich nicht um die Festschreibungs-ID eines bekannten Kopfes handelt. Eine ausführlichere Erklärung finden Sie im Artikel unter eagain.net/articles/git-for-computer-scientists .
git revert
ist jedoch kein gutes Beispiel für das Verschieben eines Zweigs, um nicht an der Spitze zu sein, da git revert
nur einige neue Commits erstellt werden und der aktuelle Zweig weiterhin an der (neuen) Spitze verbleibt.
commit
s, reset
s usw. beeinflussen.
Ich empfehle diese Definition von Github Entwickler Scott Chacon [ Video - Referenz ]:
Kopf ist Ihre aktuelle Niederlassung. Es ist eine symbolische Referenz. Es ist ein Verweis auf einen Zweig. Sie haben immer HEAD, aber HEAD zeigt auf einen dieser anderen Zeiger, auf einen der Zweige, auf denen Sie sich befinden. Es ist das übergeordnete Element Ihres nächsten Commits. Es sollte das sein, was zuletzt in Ihr Arbeitsverzeichnis eingecheckt wurde ... Dies ist der letzte bekannte Status Ihres Arbeitsverzeichnisses.
Das ganze Video wird eine faire Einführung in das gesamte Git-System geben, daher empfehle ich Ihnen auch, alles anzuschauen, wenn Sie Zeit dazu haben.
HEAD ist nur ein spezieller Zeiger, der auf den lokalen Zweig verweist, in dem Sie sich gerade befinden.
Aus dem Pro Git- Buch, Kapitel 3.1 Git-Verzweigung - Verzweigungen auf den Punkt gebracht , im Abschnitt Erstellen einer neuen Verzweigung :
Was passiert, wenn Sie einen neuen Zweig erstellen? Dadurch wird ein neuer Zeiger erstellt, mit dem Sie sich bewegen können. Angenommen, Sie erstellen einen neuen Zweig namens "Testen". Sie tun dies mit dem Befehl git branch:
$ git branch testing
Dadurch wird ein neuer Zeiger bei demselben Commit erstellt, auf dem Sie sich gerade befinden
Woher weiß Git, in welchem Zweig Sie sich gerade befinden? Es enthält einen speziellen Zeiger namens HEAD. Beachten Sie, dass dies sich stark von dem Konzept von HEAD in anderen VCS unterscheidet, an die Sie möglicherweise gewöhnt sind, z. B. Subversion oder CVS. In Git ist dies ein Zeiger auf den lokalen Zweig, in dem Sie sich gerade befinden. In diesem Fall sind Sie immer noch auf dem Master. Der Befehl git branch hat nur einen neuen Zweig erstellt - er hat nicht zu diesem Zweig gewechselt.
34ac2
im obigen Beispiel auschecken, zeigt HEAD jetzt auf dieses Commit und es wird als getrennter HEAD bezeichnet. In diesem Zustand können Sie auch Änderungen vornehmen, experimentieren und Änderungen festschreiben. Wenn Sie jedoch einen anderen Zweig auschecken, gehen alle Änderungen verloren, es sei denn, Sie erstellen einen neuen Zweig.
git log
und bekam so etwas wie commit ad0265... HEAD -> foo ...
das wäre die mittlere foo
Zweig ist eine Referenz - ID zu begehen ad0265
. Das Auschecken der Textreferenz foo
ist kein losgelöster Kopf. Das Auschecken der Festschreibungs-ID ad0265
würde zu einem abgetrennten Kopf führen. Vielleicht fehlt mir etwas Feines von dem, was Sie kommunizieren. Ich hoffe, diese Textwand hilft herauszufinden, wo ich verloren bin.
Unter der Annahme, dass es sich nicht um einen Sonderfall handelt, der als "losgelöster KOPF" bezeichnet wird, bedeutet dies, wie im O'Reilly Git-Buch, 2. Ausgabe, S. 69, angegeben HEAD
:
HEAD
bezieht sich immer auf das letzte Commit für den aktuellen Zweig. Wenn Sie Zweige wechseln,HEAD
wird aktualisiert, um auf das letzte Commit des neuen Zweigs zu verweisen.
damit
HEAD
ist die "Spitze" des aktuellen Zweigs .
Beachten Sie, dass wir verwenden können HEAD
, um auf das letzte Commit zu verweisen und es HEAD~
als Commit vor dem Tipp und HEAD~~
oder HEAD~2
als Commit noch früher usw. zu verwenden.
Es gibt ein vielleicht subtiles, aber wichtiges Missverständnis in einer Reihe dieser Antworten. Ich dachte, ich würde meine Antwort hinzufügen, um es zu klären.
Was ist
HEAD
?
HEAD
ist eine symbolische Referenz, die darauf verweist, wo immer Sie sich in Ihrem Commit-Verlauf befinden. Es folgt dir, wohin du auch gehst, was auch immer du tust, wie ein Schatten. Wenn Sie ein Commit machen, HEAD
wird sich bewegen. Wenn Sie etwas auschecken, HEAD
wird sich bewegen. Was auch immer Sie tun, wenn Sie in Ihrem Commit-Verlauf an einen neuen Ort gezogen sind, HEAD
ist mit Ihnen mitgezogen. Um ein häufiges Missverständnis anzusprechen: Sie können sich nicht davon lösen HEAD
. Das ist nicht das, was ein losgelöster HEAD-Zustand ist. Wenn Sie jemals denken: "Oh nein, ich bin in losgelöstem KOPF! Ich habe meinen KOPF verloren!" Denken Sie daran, es ist Ihr Kopf. KOPF bist du. Sie haben sich nicht vom KOPF gelöst, Sie und Ihr KOPF haben sich von etwas anderem gelöst.
HEAD
kann auf ein Commit verweisen, ja, aber normalerweise nicht. Lassen Sie mich das noch einmal sagen. Verweist HEAD
normalerweise nicht auf ein Commit. Es zeigt auf eine Zweigreferenz. Es ist an diesen Zweig angehängt , und wenn Sie bestimmte Dinge tun (z. B. commit
oder reset
), bewegt sich der angehängte Zweig mit HEAD
. Sie können sehen, worauf es zeigt, indem Sie unter die Haube schauen.
cat .git/HEAD
Normalerweise bekommst du so etwas:
ref: refs/heads/master
Manchmal bekommst du so etwas:
a3c485d9688e3c6bc14b06ca1529f0e78edd3f86
Das passiert, wenn HEAD
direkt auf ein Commit verwiesen wird. Dies wird als losgelöster HEAD bezeichnet, da HEAD
er auf etwas anderes als eine Verzweigungsreferenz verweist. Wenn Sie in diesem Status ein Commit durchführen master
und nicht mehr an dieses gebunden sind HEAD
, wird es nicht mehr mit Ihnen mitgehen. Es spielt keine Rolle, wo sich dieses Commit befindet. Sie befinden sich möglicherweise im selben Commit wie Ihr Hauptzweig. Wenn Sie HEAD
jedoch auf den Commit und nicht auf den Zweig verweisen, wird dieser getrennt und ein neuer Commit wird keiner Zweigreferenz zugeordnet.
Sie können dies grafisch betrachten, wenn Sie die folgende Übung versuchen. Führen Sie dies in einem Git-Repository aus. Sie werden etwas anderes bekommen, aber die Schlüsselbits werden da sein. Wenn es Zeit ist, das Commit direkt auszuchecken, verwenden Sie einfach den abgekürzten Hash, den Sie von der ersten Ausgabe erhalten (hier ist er a3c485d
).
git checkout master
git log --pretty=format:"%h: %d" -1
# a3c485d: (HEAD -> master)
git checkout a3c485d -q # (-q is for dramatic effect)
git log --pretty=format:"%h: %d" -1
# a3c485d: (HEAD, master)
OK, hier gibt es einen kleinen Unterschied in der Ausgabe. Wenn Sie das Commit direkt (anstelle des Zweigs) auschecken, erhalten Sie ein Komma anstelle eines Pfeils. Was denkst du, sind wir in einem freistehenden HEAD-Zustand? HEAD bezieht sich immer noch auf eine bestimmte Revision, die einem Filialnamen zugeordnet ist. Wir sind immer noch in der Hauptniederlassung, nicht wahr?
Versuchen Sie jetzt:
git status
# HEAD detached at a3c485d
Nee. Wir befinden uns im Status "freistehender KOPF".
Sie können die gleiche Darstellung von (HEAD -> branch)
vs. (HEAD, branch)
mit sehen git log -1
.
HEAD
bist du Es zeigt auf alles, was Sie ausgecheckt haben, wo immer Sie sind. In der Regel handelt es sich nicht um ein Commit, sondern um einen Zweig. Wenn HEAD
tut Punkt zu einem Commit (oder Tag), auch wenn es die gleichen commit (oder Tag) , dass ein Zweig auch Punkte, Sie (und HEAD
) haben aus diesem Zweig abgelöst worden. Da Ihnen kein Zweig zugeordnet ist, folgt der Zweig Ihnen nicht, wenn Sie neue Commits vornehmen. HEAD
wird jedoch.
.git/HEAD
ist das, was die Software als HEAD betrachtet.
HEAD
bezieht sich auf das aktuelle Commit, auf das Ihre Arbeitskopie verweist, dh auf das Commit, das Sie derzeit ausgecheckt haben. Aus der offiziellen Linux-Kernel-Dokumentation zum Spezifizieren von Git-Revisionen :
HEAD
Benennt das Commit, auf dem Sie die Änderungen im Arbeitsbaum basieren.
Beachten Sie jedoch, dass in der kommenden Version 1.8.4 von Git @
auch eine Abkürzung für verwendet werden kann HEAD
, wie Git-Mitarbeiter Junio C Hamano in seinem Git Blame-Blog feststellte :
Anstatt "HEAD" einzugeben, können Sie stattdessen "@" sagen, z. B. "git log @".
Der Stapelüberlaufbenutzer VonC fand in seiner Antwort auf eine andere Frage auch einige interessante Informationen darüber, warum @
er als Abkürzung ausgewählt wurde .
Interessant ist auch, dass in einigen Umgebungen keine Kapitalisierung erforderlich ist HEAD
, insbesondere bei Betriebssystemen, bei denen Dateisysteme ohne Berücksichtigung der Groß- und Kleinschreibung verwendet werden, insbesondere Windows und OS X.
Schauen Sie sich das Erstellen und Spielen mit Zweigen an
HEAD ist eigentlich eine Datei, deren Inhalt bestimmt, wo sich die HEAD-Variable bezieht:
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed
In diesem Repository bezieht sich der Inhalt der HEAD-Datei auf eine zweite Datei mit dem Namen refs / Heads / Master . Die Datei refs / Heads / Master enthält den Hash des letzten Commits im Master-Zweig.
Das Ergebnis ist, dass HEAD-Punkte auf das Commit des Master-Zweigs aus der Datei .git / refs / Heads / Master verweisen.
Ich möchte nur ein paar Dinge in Greg Hewgils akzeptierter Antwort detailliert beschreiben. Laut Git Pocket Guide
Ast:
Der Zweig selbst ist definiert als alle Punkte, die im Festschreibungsdiagramm vom benannten Festschreiben (der „Spitze“ des Zweigs) aus erreichbar sind.
KOPF: Eine spezielle Art von Ref
Der spezielle Ref HEAD bestimmt, in welchem Zweig Sie sich befinden ...
Refs
Git definiert zwei Arten von Referenzen oder benannten Zeigern, die es "refs" nennt:
- Eine einfache Referenz, die direkt auf eine Objekt-ID verweist (normalerweise ein Commit oder Tag).
- Eine symbolische Referenz (oder Symref), die auf eine andere Referenz verweist (entweder einfach oder symbolisch)
Wie Greg erwähnte, kann sich HEAD in einem "getrennten Zustand" befinden. HEAD kann also entweder ein einfacher Ref (für einen abgetrennten HEAD) oder ein Symref sein.
Wenn HEAD eine symbolische Referenz für einen vorhandenen Zweig ist, befinden Sie sich in diesem Zweig. Wenn es sich bei HEAD hingegen um einen einfachen Ref handelt, der ein Commit direkt anhand seiner SHA-1-ID benennt, befinden Sie sich nicht in einem Zweig, sondern im Modus "Getrennter HEAD", der beim Auschecken eines früheren Zweigs auftritt verpflichten sich zu prüfen.
Ich denke, 'HEAD' ist das aktuelle Check-out-Commit. Mit anderen Worten, 'HEAD' zeigt auf das Commit, das gerade ausgecheckt ist.
Wenn Sie gerade geklont und nicht ausgecheckt haben, weiß ich nicht, worauf es hinweist, wahrscheinlich auf einen ungültigen Speicherort.
HEAD
ist das Commit, das Sie gerade ausgecheckt haben. Einzelheiten finden Sie im Handbuch (der entsprechende Absatz folgt unmittelbar auf Abb. 3.4).
master
Zweig - HEAD zeigt also auf master.
master
, aber es ist nicht immer. Sieheremote set-head
remote set-head
, der sich nur auf den lokalen Standardzweig auswirkt und den Standard auf dem Server nicht ändert.
Der Kopf zeigt auf die Spitze des aktuell ausgecheckten Zweigs.
In Ihrem Repository befindet sich ein .git-Ordner. Öffnen Sie die Datei an diesem Speicherort: .git \ refs \ Heads. Der (sha-1-Hash-) Code in dieser Datei (in den meisten Fällen Master) ist das letzte Commit, dh das in der Ausgabe des Befehls angezeigte git log
. Weitere Informationen zum Ordner .git: http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html
git reset HEAD^
, und dann wird das letzte Commit (der frühere Tipp) nicht mehr von der Spitze des Zweigs angezeigt.
Nachdem ich alle vorherigen Antworten gelesen hatte, wollte ich noch mehr Klarheit. Dieser Blog auf der offiziellen Git-Website http://git-scm.com/blog gab mir das, wonach ich suchte:
Der HEAD in Git ist der Zeiger auf die aktuelle Verzweigungsreferenz, die wiederum ein Zeiger auf das letzte von Ihnen vorgenommene Commit oder das letzte Commit ist, das in Ihr Arbeitsverzeichnis ausgecheckt wurde. Das bedeutet auch, dass es das übergeordnete Element des nächsten Commits ist, das Sie ausführen. Es ist im Allgemeinen am einfachsten, sich das vorzustellen, da HEAD die Momentaufnahme Ihres letzten Commits ist.
HEAD
ist kein Commit; es zeigt auf eins.
checkout HEAD^
, zeigt HEAD jetzt nicht einmal auf den letzten Commit-Snapshot in einem Zweig.
commit
, merge
, rebase
, log
, etc. Aber konzeptionell vielleicht „(Zeiger auf) die aktuelle Position“ ist eine gute Zusammenfassung.
Es scheint, dass dies HEAD
nur ein Tag für das letzte Commit ist, das Sie ausgecheckt haben.
Dies kann die Spitze eines bestimmten Zweigs sein (z. B. "Master") oder ein Zwischen-Commit eines Zweigs ("losgelöster Kopf").
Zusätzlich zu allen Definitionen fiel mir beim Festschreiben ein, dass GIT ein Festschreibungsobjekt im Repository erstellt. Commit-Objekte sollten ein übergeordnetes Element haben (oder mehrere übergeordnete Objekte, wenn es sich um ein Merge-Commit handelt). Woher kennt git das übergeordnete Element des aktuellen Commits? HEAD ist also ein Zeiger auf die (Referenz des) letzten Commits, der das übergeordnete Commit des aktuellen Commits wird.
Diese beiden können Sie verwirren:
Kopf
Verweisen auf benannte Referenzen eines kürzlich eingereichten Zweigs. Sofern Sie nicht die Paketreferenz verwenden, werden die Köpfe normalerweise in $ GIT_DIR / refs / Heads / gespeichert.
KOPF
Der aktuelle Zweig oder Ihr Arbeitsbaum wird normalerweise aus dem Baum generiert, auf den HEAD zeigt. Der KOPF muss auf einen Kopf zeigen, es sei denn, Sie verwenden einen abgenommenen KOPF.
Schauen Sie sich http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is an
Abbildung 3-5. HEAD-Datei, die auf den Zweig zeigt, in dem Sie sich befinden.
HEAD
bezieht, hängt davon ab, ob es sich um ein nacktes oder ein nicht nacktes Repo handelt. Im Kontext eines nicht nackten Repos bezieht es sich effektiv auf das aktuell ausgecheckte Commit, für das kein Zweig erforderlich ist (dh wenn es sich im getrennten HEAD
Zustand befindet).
Ein Zweig ist eigentlich ein Zeiger, der eine Festschreibungs- ID wie 17a5 enthält . HEAD ist ein Zeiger auf einen Zweig, an dem der Benutzer gerade arbeitet.
HEAD hat eine Referenzdatei, die folgendermaßen aussieht:
ref:
Sie können diese Dateien überprüfen, indem Sie auf .git/HEAD
.git/refs
die Dateien in dem Repository zugreifen , in dem Sie arbeiten.
Git
dreht sich alles um Commits.
Und Head
verweist auf das Commit, das Sie gerade ausgecheckt haben.
$ git cat-file -t HEAD
commit
Wenn Sie einen Zweig auschecken, zeigt der HEAD auf das letzte Commit für diesen Zweig. Der Inhalt von HEAD kann wie folgt überprüft werden (für Hauptzweig):
$ cat .git/refs/heads/master
b089141cc8a7d89d606b2f7c15bfdc48640a8e25
Als Konzept ist der Kopf die neueste Version in einer Branche. Wenn Sie mehr als einen Kopf pro benanntem Zweig haben, haben Sie ihn wahrscheinlich erstellt, wenn Sie lokale Commits ohne Zusammenführung ausführen und so einen unbenannten Zweig erstellen.
Um ein "sauberes" Repository zu haben, sollten Sie einen Kopf pro benanntem Zweig haben und immer zu einem benannten Zweig zusammengeführt werden, nachdem Sie lokal gearbeitet haben.
Dies gilt auch für Mercurial .