Was bedeutet baumartig in Git?

122

Ich bin sehr verwirrt darüber, wie man es benutzt git archive.

Ich habe ein Git-Repository mit den Ordnern Foo , Bar und Baz auf der obersten Ebene. Ich muss den Ordner Foo auf eine SVN-artige Weise exportieren , um eine schnelle Testbereitstellung zu ermöglichen.

Ich habe gelernt, dass ich git-archiveeine Art SVN-artigen Export verwenden kann .

Aber hier ist die Sache: Folgendes funktioniert gut:

git archive master | tar -x -C ~/destination

es ergibt sich Foo , Bar , Baz Ordner im Zielordner.

Der folgende Fehler tritt jedoch auf fatal not a valid object name:

git archive master/foo | tar -x -C ~/destination

Die Dokumentation

Als Synopse für das git archiveProgramm sehe ich, dass es einen <tree-ish> [path]als Parameter annehmen kann (Synopse in relevanten Teilen zusammengefasst):

git archive <tree-ish> [path...]

Wenn master/foo nicht tree-ish, was dann?

dkinzer
quelle
2
master:fooist baumartig, aber du verwendest es besser master fooals ich <tree-ish> <path>.
Jakub Narębski
1
Ich hatte <tree-ish> als und Adjektiv von [path] interpretiert. Dort habe ich mich geirrt. Und alle Beispiele, die ich sah, verwendeten nur den <tree-ish> -Teil des Befehls, also hatte ich fälschlicherweise angenommen, dass sie einen '<tree-ish> -Pfad verwenden. Oh Semantik :)
Dkinzer
3
Ich habe ein Problem mit dieser Frage, weil der Titel fragt, was Tree-ish in Git ist, aber dann beginnt er und scheint hauptsächlich von einem Befehl zu handeln. Darüber hinaus scheint die akzeptierte Antwort nicht genau zu sagen, was der Begriff baumartig genau bedeutet. Entweder muss sich der Titel der Frage ändern oder die Frage muss sich ändern. Ich schlage vor, dass der Titel besser an das angepasst ist, worum es bei der Frage wirklich geht und wie die akzeptierte Antwort lautete. Oder ändern Sie die akzeptierte Antwort auf den eigentlichen Fragentitel. Oder die Antwort sollte den Titel der Frage adressieren.
Charlie Parker
@CharlieParker Anscheinend beziehen sich die Manpages für git archiveBefehle nicht mehr auf Tree-ish, aber als ich diese Frage stellte, taten sie es. Und in Bezug auf die akzeptierte Antwort; Zu der Zeit machte sich sonst niemand die Mühe, die Frage zu beantworten. Es war über zwei Jahre später, als sogar eine andere Antwort veröffentlicht wurde.
Dkinzer

Antworten:

166

Die kurze Antwort (TL; DR)

"Tree-ish" ist ein Begriff, der sich auf einen Bezeichner bezieht (wie in der Dokumentation zu Git-Revisionen angegeben ), der letztendlich zu einem (Unter-) Verzeichnisbaum führt (Git bezeichnet Verzeichnisse als "Bäume" und "Baumobjekte").

Im Fall des Originalplakats handelt es sich foo um ein Verzeichnis , das er angeben möchte. Die korrekte Methode zum Angeben eines (Unter-) Verzeichnisses in Git ist die Verwendung dieser "baumartigen" Syntax (Element Nr. 15 aus der Git-Revisionsdokumentation ):

<rev>:<path>, Zum Beispiel HEAD:README, :README,master:./README

Ein Suffix :gefolgt von einem Pfad benennt den Blob oder Baum am angegebenen Pfad im baumartigen Objekt, das von dem Teil vor dem Doppelpunkt benannt wird.

Mit anderen Worten, master:fooist also die richtige Syntax, nicht master/foo.

Andere "Tree-ish" (Plus Commit-ish)

Hier ist eine vollständige Liste der Commit-ish- und Tree-ish-Bezeichner (aus der Git-Revisionsdokumentation , danke an LopSae für den Hinweis ):

----------------------------------------------------------------------
|    Commit-ish/Tree-ish    |                Examples
----------------------------------------------------------------------
|  1. <sha1>                | dae86e1950b1277e545cee180551750029cfe735
|  2. <describeOutput>      | v1.7.4.2-679-g3bee7fb
|  3. <refname>             | master, heads/master, refs/heads/master
|  4. <refname>@{<date>}    | master@{yesterday}, HEAD@{5 minutes ago}
|  5. <refname>@{<n>}       | master@{1}
|  6. @{<n>}                | @{1}
|  7. @{-<n>}               | @{-1}
|  8. <refname>@{upstream}  | master@{upstream}, @{u}
|  9. <rev>^                | HEAD^, v1.5.1^0
| 10. <rev>~<n>             | master~3
| 11. <rev>^{<type>}        | v0.99.8^{commit}
| 12. <rev>^{}              | v0.99.8^{}
| 13. <rev>^{/<text>}       | HEAD^{/fix nasty bug}
| 14. :/<text>              | :/fix nasty bug
----------------------------------------------------------------------
|       Tree-ish only       |                Examples
----------------------------------------------------------------------
| 15. <rev>:<path>          | HEAD:README, :README, master:./README
----------------------------------------------------------------------
|         Tree-ish?         |                Examples
----------------------------------------------------------------------
| 16. :<n>:<path>           | :0:README, :README
----------------------------------------------------------------------

Die Bezeichner Nr. 1-14 sind alle "Commit-ish", da sie alle zu Commits führen. Da Commits jedoch auch auf Verzeichnisbäume verweisen, führen sie letztendlich alle zu (Unter-) Verzeichnisbaumobjekten und können daher auch als "Baum" verwendet werden -ish ".

# 15 kann auch als Baum verwendet werden, wenn es sich auf ein (Unter-) Verzeichnis bezieht, aber es kann auch verwendet werden, um bestimmte Dateien zu identifizieren. Wenn es sich auf Dateien bezieht, bin ich mir nicht sicher, ob es immer noch als "baumartig" betrachtet wird oder ob es sich eher wie "blob-ish" verhält (Git bezeichnet Dateien als "blobs").

Die lange Antwort

Auf den niedrigsten Ebenen verfolgt Git den Quellcode mithilfe von vier grundlegenden Objekten:

  1. Kommentierte Tags, die auf Commits verweisen.
  2. Commits, die auf den Stammverzeichnisbaum Ihres Projekts verweisen.
  3. Bäume, die Verzeichnisse und Unterverzeichnisse sind.
  4. Blobs, die Dateien sind.

Jedes dieser Objekte hat seine eigene sha1-Hash-ID, da Linus Torvalds Git wie ein inhaltsadressierbares Dateisystem entworfen hat, dh Dateien können basierend auf ihrem Inhalt abgerufen werden (sha1-IDs werden aus Dateiinhalten generiert). Das Pro Git-Buch enthält dieses Beispieldiagramm :

Abbildung 9-3 aus dem Pro Git-Buch

Viele Git-Befehle können spezielle Bezeichner für Commits und (Unter-) Verzeichnisbäume akzeptieren:

  • "Commit-ish" sind Bezeichner, die letztendlich zu einem Commit-Objekt führen. Beispielsweise,

    tag -> commit

  • "Tree-ish" sind Bezeichner, die letztendlich zu Baumobjekten (dh Verzeichnisobjekten) führen.

    tag -> commit -> project-root-directory

Da Commit-Objekte immer auf ein Verzeichnisbaumobjekt (das Stammverzeichnis Ihres Projekts) verweisen, ist jeder Bezeichner, der "commit-ish" lautet, per Definition auch "tree-ish". Mit anderen Worten, jeder Bezeichner, der zu einem Festschreibungsobjekt führt, kann auch verwendet werden, um zu einem (Unter-) Verzeichnisbaumobjekt zu führen .

Da Verzeichnisbaumobjekte im Versionssystem von Git niemals auf Commits verweisen, kann nicht jeder Bezeichner, der auf einen (Unter-) Verzeichnisbaum verweist, auch verwendet werden, um auf ein Commit zu verweisen. Mit anderen Worten, die Menge der "Commit-ish" -Kennungen ist eine strikte Teilmenge der Menge der "Tree-ish" -Kennungen.

Wie in der Dokumentation erläutert ( danke an Trebor, der mir bei der Suche geholfen hat ):

<tree>

Gibt einen Baumobjektnamen an.

<commit>

Gibt einen Commit-Objektnamen an.

<tree-ish>

Gibt einen Baum-, Commit- oder Tag-Objektnamen an. Ein Befehl, der ein <tree-ish> Argument akzeptiert, möchte letztendlich ein <tree>Objekt bearbeiten, aber automatisch Dereferenzen <commit>und <tag>Objekte, die auf a zeigen <tree>.

<commit-ish>

Gibt einen Commit- oder Tag-Objektnamen an. Ein Befehl, der ein <commit-ish> Argument akzeptiert, möchte letztendlich ein <commit>Objekt bearbeiten <tag>, dereferenziert jedoch automatisch Objekte, die auf a zeigen <commit>.

Die Menge der baumartigen Bezeichner, die nicht als festgeschrieben werden können, sind

  1. <rev>:<path>, was direkt zu Verzeichnisbäumen führt , keine Objekte festschreiben. Zum Beispiel HEAD:subdirectory.

  2. Sha1-Bezeichner von Verzeichnisbaumobjekten .

Gemeinschaft
quelle
Was ist mit Eintrag 16 auf Ihrem Tisch? Bedeutet das, dass Sie nicht sicher sind, ob es ein Baum ist oder nicht? Die 0 bezieht sich auf den Zusammenführungsstatus, und dieses Konzept gilt nur für Blobs, da der Index nicht einmal Verzeichnisse enthält. Siehe: stackoverflow.com/a/25806452/895245 . Die Frage lautet also: Sind alle Kleckse auch Baumwäschen? Soweit ich ja sagen kann: Alle Manpages, <tree-ish>die beide verwenden, akzeptieren beide und man gitrevisionsdefinieren : trees ("directories of files").
Ciro Santilli 法轮功 冠状 病 六四 事件 18
Beachten Sie, git-archivedass es a braucht, <tree-ish>aber a nicht erlaubt <sha1>. Also denke ich, es sollte stattdessen nach einem fragen <tree-ish-ish>. stackoverflow.com/a/12073669/680464
juanitogan
Ich frage mich jedoch, was passiert, wenn ich <rev> verwende: (ohne Pfad?. Es funktioniert wie versucht - aber ich kann keinen relevanten Abschnitt in der Dokumentation finden.
Martin Vejmelka
49

Ein Baum ist eine Möglichkeit, einen bestimmten Baum zu benennen, der einer der folgenden sein kann:

  • Referenzen wie:
    • KOPF
    • Stichworte
    • Filialnamen
    • Filialnamen mit Fernbedienungen, wie origin/somebranch
  • Hash
  • Kurze Hashes

Darüber hinaus kann jeder der oben genannten Punkte mit ^, ~. Referenzen können die @{}Notation auch für einige zusätzliche Funktionen verwenden:

  • HEAD^oder HEAD^1wird an den ersten Elternteil von HEAD aufgelöst.
  • HEAD^2 wird zum zweiten Elternteil aufgelöst
  • HEAD^3wird zum dritten Elternteil und so weiter aufgelöst, was seltener ist und aus Verschmelzungen mit der Octopus-Strategie resultiert .
  • HEAD~oder HEAD~1wird zum ersten Elternteil des Kopfes aufgelöst
  • HEAD~2wird zum ersten Elternteil des ersten Elternteils von HEAD aufgelöst. Dies wäre das gleiche wieHEAD^^
  • HEAD@{0} wird auf den aktuellen HEAD aufgelöst
  • HEAD@{1}wird zum vorherigen Kopf aufgelöst. Dies kann nur von Referenzen verwendet werden, da das Referenzprotokoll verwendet wird. Bei HEADjedem Commit, Merge und Checkout wird der Wert von HEAD geändert und somit dem Protokoll hinzugefügt. git reflog HEADzeigt das Referenzprotokoll an, in dem Sie alle Bewegungen von HEAD sehen können und in was @{1}und so weiter aufgelöst wird.

Die meisten der oben weiter , so lange kombiniert werden , wie es sinnvoll , in Ihrem Repository macht, zum Beispiel: HEAD@{2}~3, somebranch^2~4, c00e66e~4^2, anotherbranch~^~^~^.

Jede der oben beschriebenen und ihre Kombinationen ist in der Dokumentation als baumartig gemeint. Dies ist nur eine Möglichkeit zu sagen, welcher Baum (oder welche Revision) für die meisten git-Befehle verwendet werden sollte.

Weitere Informationen unter Revisionsauswahl im Git-Buch .

LopSae
quelle
1
Diese Antwort erklärt Revisionen (Commit-ishes) im Allgemeinen und übersieht den entscheidenden Fall: Dies master:path/to/directoryist ein Tree-ish, aber kein Commit-ish. Cupcake's macht das klarer.
Ciro Santilli 法轮功 冠状 病 六四 事件 18
11

Sie wollen wahrscheinlich

git archive master foo | tar -x -C ~/destination

Der Ausdruck master/foomacht keinen Sinn: masterist ein Filialname und fooein Verzeichnisname, wie ich vermute.

Bearbeiten : (Defekter Link entfernt. Siehe Kommentare.)

Sven Marnach
quelle
Das Wort "Baum" wird in Ihrem Link "Git Treeishes" nicht mehr gefunden. Zu Ihrer Information
Robert
Treeish bezieht sich im Allgemeinen auf den Revisionsbaum und nicht auf ein Verzeichnislayout.
Jürgen Strobel
6
@ JürgenStrobel: Das stimmt nicht. Es bezog sich auf keine der beiden - in der Vergangenheitsform, da der Begriff in der aktuellen Version der Dokumentation nicht mehr verwendet wird. (Das ist auch der Grund, warum die Verknüpfung unterbrochen ist.) Früher bezog sich ein Baum auf etwas, das in ein Baumobjekt im Objektspeicher von git aufgelöst werden konnte. Dies schloss jede Festschreibungsspezifikation ein, da sich jede Festschreibung auf ein einzelnes Baumobjekt bezieht. Das Baumobjekt enthält Informationen zum Verzeichnisbaum dieses Commits. Weitere Informationen finden Sie im Abschnitt zu Git-Objekten in "Pro Git" .
Sven Marnach
6

Für Definitionen <tree-ish>und <commit-ish>finden Sie in der git (1) man - Seite. Sie müssen nach den Begriffen suchen. Im Allgemeinen <tree-ish>bedeutet dies einen Verweis auf ein Git-Baumobjekt. Wenn Sie jedoch einen Objekttyp übergeben, der auf einen Baum verweist (z. B. ein Commit oder eine Verzweigung), verwendet git automatisch den referenzierten Baum.

Trebor unhöflich
quelle
Und gitrevisions(7).
Xiong Chiamiov
0

Ich bin ein Neuling in der Quellcodeverwaltung und Git. Das weiß ich. Ein Baum ist die Struktur von Dateien in einem Repository. Es ähnelt einem Verzeichnis in einem Dateisystem. Siehe - Welches Git-Tool hat diese Baumansicht generiert?

Baumartig bedeutet wie ein Baum. Es verweist auf einen Teil oder ein Commit eines Baums. Sie können auf ein Commit verweisen, indem Sie eines der folgenden Elemente verwenden: den SHA-1-Hash eines Commits, einen HEAD-Zeiger, eine Verzweigungsreferenz oder eine Tag-Referenz vollständig oder teilweise. Eine andere Methode verwendet eine der genannten Methoden zusammen mit Vorfahren oder Eltern eines Commits. Beispiel der Vorfahren: Geben Sie hier die Bildbeschreibung ein

stack1
quelle
0

Aus dem Git-Glossar ist tree-ish "Ein Baumobjekt oder ein Objekt, das rekursiv auf ein Baumobjekt dereferenziert werden kann." Commit, HEAD und Tag sind Beispiele für baumartige Objekte.

user2494386
quelle