¿Qué son commit-ish y tree-ish en Git?

117

La pregunta

¿Cuáles son ejemplos específicos de commit-ish y tree-ish en Git?

La pregunta de Stack Overflow "¿Qué significa árbol-ish en git?" trata específicamente sobre el árbol, pero quiero comprender más sobre ambos .

Antecedentes

Usos en la documentación

La documentación de Git hace varias referencias a "commit-ish" y "tree-ish". Por ejemplo, si está examinando el código fuente de Git :

$ 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

y

$ 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

Definiciones

La documentación de Git define qué son "commit-ish" y "tree-ish" :

<tree>

Indica un nombre de objeto de árbol.

<commit>

Indica un nombre de objeto de confirmación.

<tree-ish>

Indica un árbol, un compromiso o un nombre de objeto de etiqueta. Un comando que toma un <tree-ish> argumento en última instancia, quiere operar en un <tree>objeto, pero automáticamente elimina las referencias <commit>y los <tag>objetos que apuntan a un <tree>.

<commit-ish>

Indica un nombre de objeto de confirmación o etiqueta. Un comando que toma un <commit-ish> argumento en última instancia, quiere operar en un <commit>objeto, pero automáticamente elimina las referencias a los <tag>objetos que apuntan a un <commit>.

La documentación no es lo suficientemente clara

A pesar de que la documentación anterior define lo que son "commit-ish" y "tree-ish", todavía lo encuentro demasiado vago y poco claro.

¿Cuáles son ejemplos específicos de "commit-ish" y "tree-ish", y en qué se diferencian entre sí?

Comunidad
fuente

Respuestas:

156

La respuesta corta (TL; DR)

Aquí hay una lista completa de identificadores de tipo commit-ish y tree-ish (de la documentación de revisiones de Git ):

----------------------------------------------------------------------
|    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
----------------------------------------------------------------------

Los identificadores # 1-14 son todos "commit-ish", porque todos conducen a confirmaciones, pero debido a que las confirmaciones también apuntan a árboles de directorio, todos finalmente conducen a objetos de árbol de (sub) directorio y, por lo tanto, también se pueden usar como "árbol -ish ".

# 15 también se puede usar como árbol cuando se refiere a un (sub) directorio, pero también se puede usar para identificar archivos específicos. Cuando se refiere a archivos, no estoy seguro de si todavía se considera "tipo árbol" o si actúa más como "tipo blob" (Git se refiere a archivos como "blobs").

La respuesta larga

Confirmaciones y árboles de directorios en Git

En sus niveles más bajos, Git realiza un seguimiento del código fuente utilizando cuatro objetos fundamentales:

  1. Etiquetas anotadas, que apuntan a confirmaciones.
  2. Confirma, que apunta al árbol del directorio raíz de su proyecto.
  3. Árboles, que son directorios y subdirectorios.
  4. Blobs, que son archivos.

Cada uno de estos objetos tiene su propio ID de hash sha1, ya que Linus Torvalds diseñó Git como un sistema de archivos direccionable por contenido , es decir, los archivos se pueden recuperar en función de su contenido (los ID de sha1 se generan a partir del contenido del archivo). El libro Pro Git ofrece este diagrama de ejemplo :

Figura 9-3 del libro Pro Git

Comprometerse vs Tree-ish

Muchos comandos de Git pueden aceptar identificadores especiales para confirmaciones y árboles de (sub) directorio:

  • "Commit-ish" son identificadores que en última instancia conducen a un objeto de confirmación. Por ejemplo,

    tag -> commit

  • "Tree-ish" son identificadores que finalmente conducen a objetos de árbol (es decir, directorio).

    tag -> commit -> project-root-directory

Debido a que los objetos de confirmación siempre apuntan a un objeto de árbol de directorio (el directorio raíz de su proyecto), cualquier identificador que sea "commit-ish" es, por definición, también "tree-ish". En otras palabras, cualquier identificador que conduzca a un objeto de confirmación también se puede utilizar para conducir a un objeto de árbol de (sub) directorio .

Pero dado que los objetos del árbol de directorios nunca apuntan a confirmaciones en el sistema de control de versiones de Git, no todos los identificadores que apuntan a un árbol de (sub) directorio también pueden usarse para señalar una confirmación. En otras palabras, el conjunto de identificadores de "compromiso" es un subconjunto estricto del conjunto de identificadores de "árbol".

El conjunto de identificadores de tipo árbol que no se pueden utilizar como compromiso son

  1. <rev>:<path>, que conduce directamente a árboles de directorios, no a enviar objetos. Por ejemplo HEAD:subdirectory,.

  2. Identificadores Sha1 de objetos de árbol de directorio .


fuente
3
No te olvides stash@{0}. Me gustaría saber dónde encaja eso en todo esto. ¿Hay otras cosas como el alijo ( my-thing@{0})? ¿El alijo es solo un <refname>?
Nate
No se ha dejado claro explícitamente que un identificador de tipo árbol parece ser un identificador más específico que un identificador de compromiso. Tal vez soy raro, pero esa es la única forma sensata de explicarlo, en mi opinión
Steven Lu
29

Nota para hablantes no nativos de inglés [sic!]: "-Ish" es un sufijo que se puede aplicar a un adjetivo para indicar "tener cualidades como" o "levemente" - ver http://chambers.co.uk / search /? query = ish & title = 21st

Por lo tanto, "árbol-ish" - como un "árbol" ... "commit-ish" - como un "compromiso"

por ejemplo, "Marte parece una estrella rojiza" (¡la "d" se duplica!); "la comida del plato no estaba caliente, sino tibia"

Creo que esto ayuda a explicar mejor "qué son ...", ya que explica el uso del lenguaje.

MikeW
fuente
Siempre he interpretado que "tree-ish" y "commit-ish" son análogos a decir "sueco" o "inglés". El uso que describe tiene menos sentido para mí porque esa forma de "ish" crea un adjetivo. Pero la rev no es "como" un árbol o un compromiso, es un árbol o un compromiso. Por otro lado, si piensa en "ish" como un sufijo de lenguaje, entonces tienen más sentido como sustantivos en la línea de comando, donde "tree-ish" es el lenguaje que forma el sustantivo. No sé qué interpretación fue la intención de los autores, pero así es como siempre lo he visto.
jmt
Entiendo su punto, pero solo estaba dando la impresión que tengo, ¡como hablante nativo de inglés!
MikeW