Was sind Commit-ish und Tree-ish in Git?

115

Die Frage

Was sind spezifische Beispiele für Commit-ish und Tree-ish in Git?

Die Stapelüberlauf-Frage "Was bedeutet baumartig in Git?" befasst sich speziell mit Baum-ish, aber ich möchte mehr über beide verstehen .

Hintergrund

Verwendung in der Dokumentation

Die Git-Dokumentation enthält mehrere Verweise auf "commit-ish" und "tree-ish". Wenn Sie beispielsweise den Git-Quellcode untersuchen :

$ git grep --files-with-matches --extended-regexp "commit(-)*ish"
config.txt
git-describe.txt
git-fast-import.txt
git-name-rev.txt
git-push.txt
git-rebase.txt
git-rev-parse.txt
git.txt
gitcli.txt
glossary-content.txt
howto/revert-branch-rebase.txt
revisions.txt

und

$ git grep --files-with-matches --extended-regexp "tree(-)*ish" | \
$ grep --invert-match RelNotes
diff-format.txt
diff-generate-patch.txt
git-archive.txt
git-cat-file.txt
git-checkout.txt
git-diff-index.txt
git-diff-tree.txt
git-ls-files.txt
git-ls-tree.txt
git-merge-tree.txt
git-read-tree.txt
git-reset.txt
git-svn.txt
git.txt
gitcli.txt
gittutorial-2.txt
glossary-content.txt
revisions.txt

Definitionen

Die Git-Dokumentation definiert, was "Commit-ish" und "Tree-ish" sind :

<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 Dokumentation ist nicht klar genug

Obwohl die obige Dokumentation definiert, was "Commit-ish" und "Tree-ish" sind, finde ich es immer noch zu vage und unklar.

Was sind spezifische Beispiele für "Commit-ish" und "Tree-ish" und wie unterscheiden sie sich voneinander?

Gemeinschaft
quelle

Antworten:

155

Die kurze Antwort (TL; DR)

Hier ist eine vollständige Liste der Commit-ish- und Tree-ish-Bezeichner (aus der Dokumentation zu Git-Revisionen ):

----------------------------------------------------------------------
|    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.txt, master:sub-directory/
----------------------------------------------------------------------
|         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 "Baum-ish" betrachtet wird oder ob es sich eher wie "blob-ish" verhält (Git bezeichnet Dateien als "blobs").

Die lange Antwort

Commits und Verzeichnisbäume in Git

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

Commit-ish vs Tree-ish

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.

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 .


quelle
3
Vergiss nicht stash@{0}. Ich würde gerne wissen, wo das in all das passt. Gibt es noch andere Dinge wie das Versteck ( my-thing@{0})? Ist das Versteck nur ein <refname>?
Nate
Es wurde nicht explizit klargestellt, dass ein baumartiger Bezeichner ein spezifischerer Bezeichner zu sein scheint als ein festgeschriebener Bezeichner. Vielleicht bin ich komisch, aber das ist der einzig vernünftige Weg, es zu erklären IMO
Steven Lu
28

Hinweis für nicht-englische Muttersprachler: "-ish" ist ein Suffix, das auf ein Adjektiv angewendet werden kann, um "mit Eigenschaften wie" oder "leicht" anzuzeigen - siehe http://chambers.co.uk / search /? query = ish & title = 21st

Daher "tree-ish" - wie ein "tree" .... "commit-ish" - wie ein "commit"

zB "Mars erscheint wie ein rötlicher Stern" ("d" wird verdoppelt!); "Das Essen auf dem Teller war nicht heiß, aber warm"

Ich glaube, dass dies hilft, "was sind ..." besser zu erklären, indem es den Sprachgebrauch erklärt.

MikeW
quelle
Ich habe "tree-ish" und "commit-ish" immer so interpretiert, dass sie "schwedisch" oder "englisch" sind. Die Verwendung, die Sie beschreiben, ist für mich weniger sinnvoll, da diese Form von "ish" ein Adjektiv erzeugt. Aber die Rev ist nicht "wie" ein Baum oder ein Commit, es ist ein Baum oder ein Commit. Wenn Sie sich andererseits "ish" als Sprachsuffix vorstellen, sind sie als Substantive in der Befehlszeile sinnvoller, wobei "tree-ish" die Sprache ist, die das Substantiv bildet. Ich weiß nicht, welche Interpretation die Absicht der Autoren war, aber so habe ich es immer gesehen.
22.