Cosa sono il commit e il tree-ish in Git?


117

La domanda

Quali sono esempi specifici di commit e tree-ish in Git?

La domanda di Stack Overflow "Cosa significa tree-ish in git?" si occupa specificamente di tree-ish, ma voglio saperne di più su entrambi .

sfondo

Usi nella documentazione

La documentazione di Git fa diversi riferimenti a "commit-ish" e "tree-ish". Ad esempio, se stai esaminando il codice sorgente di 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

e

$ 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

definizioni

La documentazione di Git definisce cosa sono "commit-ish" e "tree-ish" :

<tree>

Indica il nome di un oggetto albero.

<commit>

Indica il nome di un oggetto di commit.

<tree-ish>

Indica un nome di oggetto albero, commit o tag. Un comando che accetta un <tree-ish> argomento alla fine vuole operare su un <tree>oggetto ma dereferenzia automaticamente <commit>e gli <tag>oggetti che puntano a <tree>.

<commit-ish>

Indica un nome di oggetto di commit o tag. Un comando che accetta un <commit-ish> argomento alla fine vuole operare su un <commit>oggetto ma dereferenzia automaticamente gli <tag>oggetti che puntano a <commit>.

La documentazione non è abbastanza chiara

Anche se la documentazione sopra definisce cosa sono "commit-ish" e "tree-ish", trovo ancora che sia troppo vago e poco chiaro.

Quali sono esempi specifici di "commit-ish" e "tree-ish" e in che modo sono diversi l'uno dall'altro?

Risposte:


156

La risposta breve (TL; DR)

Ecco un elenco completo di identificatori di commit e tree-ish (dalla documentazione delle revisioni di 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
----------------------------------------------------------------------

Gli identificatori # 1-14 sono tutti "commit-ish", perché tutti portano a commit, ma poiché i commit puntano anche ad alberi di directory, alla fine portano tutti a oggetti (sotto) albero di directory, e possono quindi essere usati anche come "albero -ish".

# 15 può anche essere usato come tree-ish quando fa riferimento a una (sotto) directory, ma può anche essere usato per identificare file specifici. Quando si riferisce ai file, non sono sicuro che sia ancora considerato "tree-ish", o se agisce più come "blob-ish" (Git si riferisce ai file come "blob").

La lunga risposta

Commit e alberi di directory in Git

Ai suoi livelli più bassi, Git tiene traccia del codice sorgente utilizzando quattro oggetti fondamentali:

  1. Tag annotati, che puntano ai commit.
  2. Commits, che puntano all'albero della directory principale del progetto.
  3. Alberi, che sono directory e sottodirectory.
  4. Blob, che sono file.

Ciascuno di questi oggetti ha il proprio hash ID sha1, poiché Linus Torvalds ha progettato Git come un filesystem indirizzabile al contenuto , ovvero i file possono essere recuperati in base al loro contenuto (gli ID sha1 sono generati dal contenuto del file). Il libro Pro Git fornisce questo diagramma di esempio :

Figura 9-3 dal libro Pro Git

Commit-ish vs Tree-ish

Molti comandi Git possono accettare identificatori speciali per commit e (sotto) alberi di directory:

  • "Commit-ish" sono identificatori che alla fine portano a un oggetto di commit. Per esempio,

    tag -> commit

  • "Tree-ish" sono identificatori che alla fine portano a oggetti ad albero (cioè directory).

    tag -> commit -> project-root-directory

Poiché gli oggetti commit puntano sempre a un oggetto albero di directory (la directory principale del progetto), qualsiasi identificatore "commit-ish" è, per definizione, anche "tree-ish". In altre parole, qualsiasi identificatore che porta a un oggetto commit può essere utilizzato anche per portare a un (sotto) oggetto albero di directory .

Ma poiché gli oggetti dell'albero di directory non puntano mai a commit nel sistema di controllo delle versioni di Git, non tutti gli identificatori che puntano a un (sotto) albero di directory possono anche essere usati per puntare a un commit. In altre parole, l'insieme di identificatori "commit-ish" è un sottoinsieme rigoroso dell'insieme di identificatori "tree-ish".

L'insieme di identificatori ad albero che non possono essere usati come commit-ish sono

  1. <rev>:<path>, che porta direttamente agli alberi di directory, non agli oggetti di commit. Ad esempio HEAD:subdirectory,.

  2. Identificatori Sha1 degli oggetti dell'albero di directory .


3
Non dimenticare stash@{0}. Mi piacerebbe sapere dove si inserisce tutto questo. Ci sono altre cose come stash ( my-thing@{0})? La scorta è solo una <refname>?
Nate

Non è stato chiarito esplicitamente che un identificatore tree-ish sembra essere un identificatore più specifico di un identificatore commit-ish. Forse sono strano, ma questo è l'unico modo sensato per spiegarlo IMO
Steven Lu

29

Nota per chi parla inglese [sic!] Non madrelingua: "-ish" è un suffisso che può essere applicato a un aggettivo per indicare "avere qualità come" o "leggermente" - vedi http://chambers.co.uk / Ricerca /? query = ish & title = 21

Quindi "tree-ish" - come un "albero" .... "commit-ish" - come un "commit"

es. "Marte appare come una stella rossastra" ("d" è raddoppiata!); "il cibo nel piatto non era caldo, ma caldo"

Credo che questo aiuti a spiegare meglio "cosa sono ...", in quanto spiega l'uso della lingua.


Ho sempre interpretato "tree-ish" e "commit-ish" come analoghi a dire "svedese" o "inglese". L'utilizzo che descrivi ha meno senso per me perché quella forma di "ish" crea un aggettivo. Ma il rev non è "come" un albero o un commit, è un albero o un commit. D'altra parte, se pensi a "ish" come suffisso della lingua, hanno più senso come sostantivi sulla riga di comando, dove "tree-ish" è la lingua che forma il sostantivo. Non so quale interpretazione fosse l'intento degli autori, ma è così che l'ho sempre vista.
jmt

Capisco il tuo punto, ma stavo solo dando l'impressione di avere, come madrelingua inglese!
MikeW
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.