657 Stimmen

Was ist der Unterschied zwischen HEAD, Arbeitsbaum und Index in Git?

Kann mir jemand den Unterschied zwischen HEAD, Arbeitsbaum und Index in Git erklären?

Soweit ich weiß, sind das alles Namen für verschiedene Branchen. Ist meine Vermutung richtig?

Ich habe dies gefunden:

Ein einzelnes Git-Repository kann eine beliebige Anzahl von Zweigen verfolgen, aber Ihr Arbeitsbaum ist nur mit einem von ihnen verbunden (dem "aktuellen" oder "ausgecheckten" Zweig), und HEAD zeigt auf diesen Zweig.

Bedeutet dies, dass HEAD und Arbeitsbaum immer gleich sind?

40 Stimmen

In Bezug auf Ihre Bearbeitung: absolut nicht. HEAD ist die Übergabe an der Spitze des aktuellen Zweigs. Wenn Sie den Zweig gerade ausgecheckt haben, d.h. keine Dateien geändert haben, dann stimmt sein Inhalt mit dem Arbeitsbaum überein. Sobald Sie etwas ändern, stimmt er nicht mehr überein.

13 Stimmen

Ich glaube, Sie müssen das lesen: denke-wie-ein-git.net

9 Stimmen

Ich würde auch eine Staging Area zu dieser Liste hinzufügen. Was ist HEAD , Working Tree , Index und eine Staging Area

760voto

VonC Punkte 1117238

Ein paar weitere gute Referenzen zu diesen Themen:

workflow

Ich verwende den Index als Kontrollpunkt .

Wenn ich im Begriff bin, eine Änderung vorzunehmen, die schief gehen könnte - wenn ich eine Richtung erkunden möchte, von der ich nicht sicher bin, ob ich sie durchziehen kann oder ob sie überhaupt eine gute Idee ist, wie z. B. ein konzeptionell anspruchsvolles Refactoring oder die Änderung eines Repräsentationstyps - setze ich einen Checkpoint in den Index.

Wenn dies die erste Änderung ist, die ich seit meinem letzten Commit vorgenommen habe, kann ich das lokale Repository als Kontrollpunkt verwenden, aber oft habe ich eine konzeptionelle Änderung, die ich in mehreren kleinen Schritten umsetze.
Ich möchte nach jedem Schritt einen Checkpoint setzen, aber den Commit aufheben, bis ich wieder zu funktionierendem, getesteten Code gekommen bin.

Anmerkungen:

  1. die Arbeitsbereich ist der Verzeichnisbaum der (Quell-)Dateien, die Sie sehen und bearbeiten.

  2. Le site Index ist eine einzelne, große Binärdatei in <baseOfRepo>/.git/index die alle Dateien im aktuellen Zweig auflistet, ihre sha1 Prüfsummen, Zeitstempel und den Dateinamen - es handelt sich nicht um ein weiteres Verzeichnis mit einer Kopie von Dateien darin.

  3. Le site lokales Repository ist ein verstecktes Verzeichnis ( .git ) einschließlich einer objects Verzeichnis, das alle Versionen jeder Datei im Repo (lokale Zweige und Kopien von entfernten Zweigen) als komprimierte "Blob"-Datei enthält.

Betrachten Sie die vier "Disketten" in der obigen Abbildung nicht als separate Kopien der Repo-Dateien.

3 states

Sie sind im Grunde genommen benannte Referenzen für Git-Commits. Es gibt zwei Haupttypen von Verweisen: Tags und Heads.

  • Tags sind feste Referenzen, die einen bestimmten Punkt in der Geschichte markieren, zum Beispiel v2.6.29.
  • Vielmehr werden die Köpfe immer wieder bewegt, um den aktuellen Stand der Projektentwicklung widerzuspiegeln.

commits

(Anmerkung: als kommentiert von Timo Huovinen Diese Pfeile sind nicht das, worauf die Commits zeigen, es sind die Workflow-Bestellung , die grundsätzlich Pfeile als 1 -> 2 -> 3 -> 4 donde 1 ist die erste Übertragung und 4 ist die letzte)

Jetzt wissen wir, was bei dem Projekt passiert.
Aber um zu wissen, was genau hier und jetzt passiert, gibt es eine spezielle Referenz namens HEAD. Er dient zwei wichtigen Zwecken:

  • teilt Git mit, von welchem Commit die Dateien beim Auschecken genommen werden sollen, und
  • teilt Git mit, wo neue Commits abgelegt werden sollen, wenn Sie einen Commit durchführen.

Wenn Sie git checkout ref es zeigt HEAD zu dem von Ihnen angegebenen Speicherort und extrahiert Dateien daraus. Wenn Sie git commit wird ein neues Commit-Objekt erstellt, das ein Kind des aktuellen HEAD . Normalerweise HEAD zeigt auf einen der Köpfe, so dass alles gut klappt.

checkout

28 Stimmen

Nachdem ich viele Male über Git gelesen habe, habe ich es nie ganz verstanden und bin wirklich frustriert und möchte das F-Wort benutzen, aber ich bin in der Community! Du hast Köpfe erwähnt, aber in den Bildern oben gibt es immer nur einen HEAD, wo sind die anderen Köpfe? "Normalerweise zeigt HEAD auf einen der Köpfe, also ist alles in Ordnung." Ich bitte dich, diese Aussage zu erklären.

16 Stimmen

@neckTwi HEAD ist der aktuelle Übertragung mit dem Sie arbeiten ( stackoverflow.com/a/964927/6309 ). Normalerweise handelt es sich um einen der "branch heads" (einer der von branches referenzierten Commits, der den Tipp der genannten Zweige). Sie können aber jeden Commit auschecken (und daran arbeiten). Wenn Sie einen Commit auschecken, der nicht einer der (Zweig-)Köpfe ist, befinden Sie sich in einem "abgetrennten HEAD"-Modus: stackoverflow.com/a/3965714/6309

0 Stimmen

Sind die Pfeile nicht verkehrt herum? Sollte nicht jeder Commit auf den Commit vor ihm zurückzeigen? Ich denke, das wäre korrekter

173voto

Jakub Narębski Punkte 286531

Der Unterschied zwischen KOPF (aktueller Zweig oder letzter übertragener Zustand im aktuellen Zweig), Index (auch bekannt als Aufenthaltsbereich) und Arbeitsbaum (der Zustand der Dateien im Checkout) wird beschrieben in Abschnitt "Die drei Zustände" in den "1.3 Git-Grundlagen " Kapitel von Pro Git Buch von Scott Chacon (Creative Commons lizenziert).

Hier ist das Bild aus diesem Kapitel, das dies veranschaulicht:

Local Operations - working directory vs. staging area (index) vs git repository (HEAD)

Im obigen Bild ist das "Arbeitsverzeichnis" dasselbe wie der "Arbeitsbaum", die "Staging Area" ist ein alternativer Name für den Git-"Index", und KOPF zeigt auf den aktuell ausgecheckten Zweig, der auf die letzte Übergabe im "Git-Verzeichnis (Repository)" verweist

Beachten Sie, dass git commit -a würde Änderungen in einem Schritt durchführen und festschreiben.

2 Stimmen

"Ein Bild sagt mehr als tausend Worte". Danke Jakub.. Und danke für den Link.

7 Stimmen

Nota: working tree scheint bevorzugt zu werden gegenüber working directory Heutzutage. Siehe github.com/git/git/commit/

6 Stimmen

Dieses Bild ist nicht ganz korrekt, da der Bereitstellungsbereich in einer einzigen Datei namens "index" enthalten ist - und diese Indexdatei befindet sich zufällig im Stammverzeichnis des Git-Verzeichnisses. Wenn Sie also das Repo als das Git-Verzeichnis definieren, befindet sich der Staging-Bereich technisch gesehen innerhalb des Repo. Die dritte Spalte sollte besser mit "HEAD's Root tree object" beschriftet werden, um zu verdeutlichen, dass die ausgecheckten Dateien von einem Commit-Objekt stammen und dass das Commit einen neuen Baum in ein Commit-Objekt schreibt - beide Commit-Objekte werden von HEAD angezeigt.

87voto

Brian Campbell Punkte 304982

Ihr Arbeitsbaum ist das, was in den Dateien steht, an denen Sie gerade arbeiten.

HEAD ist ein Zeiger auf den Zweig oder die Übergabe, den/die Sie zuletzt ausgecheckt haben und der/die als Elternteil einer neuen Übergabe dienen wird, wenn Sie diese vornehmen. Wenn Sie sich zum Beispiel auf dem master Zweig, dann HEAD zeigt auf master und wenn Sie übertragen, wird diese neue Übertragung ein Nachkomme der Revision sein, die master hingewiesen, und master wird aktualisiert und verweist auf die neue Übertragung.

Le site Index ist ein Bereitstellungsbereich, in dem die neue Übertragung vorbereitet wird. Im Wesentlichen ist der Inhalt des Indexes das, was in die neue Übertragung geht (wenn Sie allerdings git commit -a Dies fügt automatisch alle Änderungen an Dateien, die Git kennt, vor dem Commit in den Index ein, so dass der aktuelle Inhalt des Arbeitsbaums übertragen wird.) git add fügt Dateien aus dem Arbeitsbaum in Ihren Index ein oder aktualisiert sie.

0 Stimmen

Vielen Dank für die Erklärung, Brian. Also, der Arbeitsbaum enthält alle nicht übertragenen Änderungen. Wenn ich meine Änderungen mit git commit -a übertrage, dann sind zu diesem Zeitpunkt mein Arbeitsbaum und mein Index identisch. Wenn ich meine Änderungen in mein zentrales Projektarchiv verschiebe, sind alle drei identisch. Liege ich da richtig?

4 Stimmen

@Vinod So ziemlich. Du kannst Dateien in deinem Arbeitsbaum haben, von denen Git nichts weiß, und diese werden nicht mit git commit -a (Sie müssen sie mit git add ), so dass Ihr Arbeitsbaum zusätzliche Dateien haben kann, die Ihr Index, Ihr lokales Projektarchiv oder Ihr entferntes Projektarchiv nicht haben.

3 Stimmen

@Vinod: Der Arbeitsbaum und der Index können übereinstimmen, ohne dass ein Commit erforderlich ist (git add aktualisiert den Index vom Arbeitsbaum aus, und git checkout <Pfad> aktualisiert den Arbeitsbaum vom Index aus). HEAD bezieht sich auf den letzten Commit, wenn Sie also einen Commit durchführen, aktualisieren Sie HEAD zu Ihrer neuen Übergabe, die mit dem Index übereinstimmt. Pushing hat damit nicht viel zu tun - es sorgt dafür, dass die Zweige im entfernten Projektarchiv mit den Zweigen in Ihrem lokalen Projektarchiv übereinstimmen.

69voto

Ashraf Alam Punkte 3340

Arbeitsbaum

Ihr Arbeitsbaum sind die Dateien, an denen Sie gerade arbeiten.

Git-Index

  • Der Git-"Index" ist der Ort, an dem Sie Dateien ablegen, die Sie in das Git-Repository übertragen wollen.

  • Der Index ist auch bekannt als Cache , Verzeichnis-Cache , Cache des aktuellen Verzeichnisses , Bereitstellungsraum , Staged Files .

  • Bevor Sie Dateien in das Git-Repository "übertragen" (einchecken), müssen Sie die Dateien zunächst in den Git-"Index" aufnehmen.

  • Der Index ist no das Arbeitsverzeichnis: Sie können einen Befehl wie den folgenden eingeben git status und git teilt Ihnen mit, welche Dateien in Ihrem Arbeitsverzeichnis in den git-Index aufgenommen wurden (z. B. mit dem Befehl git add filename Befehl).

  • Der Index ist nicht das Git-Repository: Dateien im Git-Index sind Dateien, die Git in das Git-Repository übertragen würde, wenn Sie den Git-Commit-Befehl verwenden.

1 Stimmen

Beachten Sie, dass Git 2.5 die mehrere Arbeitsbäume ( stackoverflow.com/a/30185564/6309 ). +1

3 Stimmen

Ich bin mir nicht sicher, ob "The Index Isn't The Working Directory" zu 100 % korrekt ist. Es sollte heißen: "Der Index ist nicht das Arbeitsverzeichnis, aber er enthält das gesamte Arbeitsverzeichnis + Änderungen, die als nächstes übertragen werden sollen". Beweis? Gehen Sie zu einem Git-Repository, reset --hard HEAD um sicherzustellen, dass Ihr Index == Ihr Arbeitsbaum ist. und dann: mkdir history && git checkout-index --prefix history/ -a Das Ergebnis ist eine Vervielfältigung Ihres gesamten Arbeitsbaums in Ihrem history/ Verzeichnis. Ergo git index >= git Arbeitsverzeichnis

3 Stimmen

Index ist nicht das Arbeitsverzeichnis und muss auch nicht das Arbeitsverzeichnis enthalten. Index ist nur eine Datei innerhalb des Git-Repositorys, in der die Informationen gespeichert werden, die Sie übertragen möchten.

60voto

Mehdi Ijadnazar Punkte 4007

Dies ist eine unvermeidlich lange, aber leicht verständliche Erklärung von ProGit-Buch :

Als Referenz können Sie Kapitel 7.7 des Buches lesen, Zurücksetzen entmystifiziert

Git als System verwaltet und manipuliert in seinem normalen Betrieb drei Bäume:

  • KOPF: Schnappschuss der letzten Übergabe, nächste übergeordnete Übergabe
  • Index: Vorgeschlagener nächster Commit-Snapshot
  • Arbeitsverzeichnis: Sandkasten

Der HEAD

HEAD ist die Zeiger zum Referenz der aktuellen Verzweigung , der wiederum ein Zeiger auf den letzte Übergabe in diesem Zweig . Das bedeutet, dass HEAD die Elternteil der nächsten Übergabe, die erstellt wird . Im Allgemeinen ist es am einfachsten, sich HEAD als die Schnappschuss der letzten Übertragung in diesem Zweig .

Was enthält sie?
Um zu sehen, wie dieser Snapshot aussieht, führen Sie Folgendes im Root-Verzeichnis Ihres Repositorys aus:

                                 git ls-tree -r HEAD

würde dies in etwa zu folgendem Ergebnis führen:

                       $ git ls-tree -r HEAD  
                       100644 blob a906cb2a4a904a152... README  
                       100644 blob 8f94139338f9404f2... Rakefile  
                       040000 tree 99f1a6d12cb4b6f19... lib  

Der Index

Git füllt diesen Index mit einer Liste aller Dateiinhalte, die zuletzt in Ihr Arbeitsverzeichnis ausgecheckt wurden und wie sie aussahen, als sie ursprünglich ausgecheckt wurden. Anschließend ersetzen Sie einige dieser Dateien durch neue Versionen, und Git Commit wandelt diese in den Baum für eine neue Übertragung um.

Was enthält sie?
Verwenden Sie git ls-files -s um zu sehen, wie es aussieht. Sie sollten etwa so etwas sehen:

                 100644 a906cb2a4a904a152e80877d4088654daad0c859 0 README   
                 100644 8f94139338f9404f26296befa88755fc2598c289 0 Rakefile  
                 100644 47c6340d6459e05787f644c2447d2595f5d3a54b 0 lib/simplegit.rb  

Das Arbeitsverzeichnis

Hier befinden sich Ihre Dateien und Sie können Änderungen ausprobieren, bevor Sie sie in den Staging-Bereich (Index) und dann in den Verlauf übertragen.

Visualisierte Probe

Schauen wir uns an, wie diese drei Bäume (wie sie im ProGit-Buch genannt werden) zusammenarbeiten.
Der typische Arbeitsablauf von Git besteht darin, Schnappschüsse Ihres Projekts in immer besseren Zuständen aufzuzeichnen, indem Sie diese drei Bäume manipulieren. Werfen Sie einen Blick auf dieses Bild:

enter image description here

Um ein gutes visuelles Verständnis zu erhalten, betrachten Sie folgendes Szenario. Nehmen wir an, Sie gehen in ein neues Verzeichnis mit einer einzigen Datei darin. Nennen Sie dies v1 der Datei. Sie ist in blau dargestellt. Ausführen von git init erstellt ein Git-Repository mit einer HEAD-Referenz, die auf den ungeborenen Master-Zweig verweist

enter image description here

Zu diesem Zeitpunkt hat nur der Arbeitsverzeichnisbaum einen Inhalt. Jetzt wollen wir diese Datei übertragen, also benutzen wir git add um den Inhalt des Arbeitsverzeichnisses in den Index zu kopieren.

enter image description here

Dann führen wir git commit der den Inhalt des Index als permanenten Snapshot speichert, ein Commit-Objekt erzeugt, das auf diesen Snapshot verweist, und den Master so aktualisiert, dass er auf diesen Commit verweist.

enter image description here

Wenn wir die git status wir werden sehen keine Änderungen denn alle drei Bäume sind identisch .

Der schöne Punkt

git status zeigt den Unterschied zwischen diesen Bäumen auf folgende Weise an:

  • Wenn der Arbeitsbaum nicht mit dem Index übereinstimmt, dann git status wird zeigen es gibt einige Änderungen, die nicht für die Übergabe vorgesehen sind
  • Wenn der Arbeitsbaum mit dem Index übereinstimmt, aber nicht mit HEAD übereinstimmt, dann git status zeigt einige Dateien unter zu übernehmende Änderungen Abschnitt in seinem Ergebnis
  • Wenn der Arbeitsbaum nicht mit dem Index übereinstimmt, und index nicht mit HEAD übereinstimmt, dann git status zeigt einige Dateien unter Änderungen, die nicht für die Übertragung vorgesehen sind Abschnitt und einige andere Dateien unter zu übernehmende Änderungen Abschnitt in seinem Ergebnis.

Für die ganz Neugierigen

Hinweis zu git reset Befehl
Wir hoffen, dass wir wissen, wie reset Die Kommandoarbeiten werden den Grund für die Existenz dieser drei Bäume weiter erhellen.

reset ist die Zeitmaschine in Git, mit der Sie leicht in der Zeit zurückgehen und einige alte Schnappschüsse für die Arbeit mitbringen können. Auf diese Weise ist HEAD das Wurmloch, durch das Sie in der Zeit reisen können. Sehen wir uns an einem Beispiel aus dem Buch an, wie das funktioniert:

Betrachten Sie das folgende Repository mit einer einzigen Datei und 3 Commits, die in verschiedenen Farben und mit unterschiedlichen Versionsnummern angezeigt werden:

enter image description here

Der Zustand der Bäume ist wie auf dem nächsten Bild zu sehen:

enter image description here

Schritt 1: Verschieben von HEAD (--soft):

Beim Zurücksetzen wird zunächst der Verweis auf HEAD verschoben. Dies ist nicht dasselbe wie das Ändern von HEAD selbst (was mit checkout geschieht). reset verschiebt den Zweig, auf den HEAD verweist. Das heißt, wenn HEAD auf den Master-Zweig gesetzt ist, wird durch den Aufruf von git reset 9e5e6a4 der Master-Zweig auf 9e5e6a4 verweisen. Wenn Sie reset mit --soft Option wird es hier enden, ohne dass die index y working directory . Unser Repo sieht jetzt wie folgt aus:
Hinweis: HEAD~ ist der Elternteil von HEAD

enter image description here

Wenn wir uns das Bild ein zweites Mal ansehen, können wir erkennen, dass der Befehl im Wesentlichen die letzte Übertragung rückgängig gemacht hat. Da der Arbeitsbaum und der Index derselbe sind, sich aber von HEAD unterscheiden, git status zeigt nun die Änderungen in grüner Farbe an, damit sie übertragen werden können.

Schritt 2: Aktualisierung des Index (--mixed):

Dies ist die Standardoption des Befehls

Laufen reset avec --mixed aktualisiert den Index mit dem Inhalt des Snapshots, auf den HEAD gerade verweist, wobei das Arbeitsverzeichnis intakt bleibt. Auf diese Weise sieht Ihr Projektarchiv so aus, als hätten Sie eine Arbeit durchgeführt, die nicht in den Stages enthalten ist und git status zeigt dies als Änderungen, die nicht für die Übergabe vorgesehen sind, in Rot an. Diese Option macht auch die letzte Übergabe rückgängig und hebt die Bereitstellung aller Änderungen auf. Es ist, als hätten Sie Änderungen vorgenommen, aber nicht die Option git add Befehl noch nicht. Unser Repo würde jetzt wie folgt aussehen:

enter image description here

Schritt 3: Aktualisieren des Arbeitsverzeichnisses (--hard)

Wenn Sie anrufen reset avec --hard wird der Inhalt des Schnappschusses, auf den HEAD verweist, in HEAD, index und Arbeitsverzeichnis kopiert. Nach der Ausführung des Befehls reset --hard würde dies bedeuten, dass Sie zu einem früheren Zeitpunkt zurückgekehrt sind und danach nichts mehr getan haben, siehe das folgende Bild:

enter image description here

Schlussfolgerung

Ich hoffe, Sie haben jetzt ein besseres Verständnis für diese Bäume und eine Vorstellung davon, welche Möglichkeiten sie Ihnen bieten, indem sie es Ihnen ermöglichen, Ihre Dateien in Ihrem Repository zu ändern und Dinge rückgängig zu machen oder wiederherzustellen, die Sie versehentlich getan haben.

0 Stimmen

Nur zum Vergleich, dies ist Kapitel 7.7 Git-Werkzeuge - Zurücksetzen entmystifiziert in dem Buch.

0 Stimmen

Sehr schöne Erklärung

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