O que significa tree-ish no Git?

122

Estou muito confuso sobre como usar git archive.

Eu tenho um repositório git com a pasta Foo , Bar e Baz no nível superior. Preciso exportar a pasta Foo de uma maneira SVN-ish para uma rápida implantação de teste.

Aprendi que eu poderia usar git-archivede uma maneira de exportação SVN-ish .

Mas aqui está o seguinte: O seguinte funciona bem:

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

isso resulta em pastas Foo , Bar , Baz na pasta de destino .

No entanto, o seguinte erro ocorrerá com fatal not a valid object name:

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

A documentação

Olhando como a sinopse do git archiveprograma, vejo que ele pode ter um <tree-ish> [path]como parâmetro (sinopse resumida em partes relevantes):

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

Se master/foo não for tree-ish, então o que é?

dkinzer
fonte
2
master:fooé árvore, mas é melhor você usar master foocomo i <tree-ish> <path>.
Jakub Narębski 28/10/10
1
Eu tinha interpretado <tree-ish> como e adjetivo de [path]. Foi aí que eu errei. E todos os exemplos que eu vi usavam apenas a parte <tree-ish> do comando, então eu assumi erroneamente que eles estavam usando um caminho '<tree-ish>. Oh semântica :)
dkinzer 28/10/10
3
Eu tenho um problema com essa pergunta porque o título pergunta sobre o que é o tree-ish no git, mas então ele começa e parece ser principalmente sobre algum comando. Além disso, a resposta aceita não parece abordar exatamente o que o termo árvore significa. O título da pergunta deve mudar ou a pergunta deve mudar. Sugiro que o título seja melhor adaptado ao que realmente interessa a pergunta e qual foi a resposta aceita. Ou talvez alterando a resposta aceita para o que realmente é o título da pergunta. Ou a resposta deve abordar o título da pergunta.
Charlie Parker
@CharlieParker, aparentemente, as páginas de manual do git archivecomando não se referem mais ao tree-ish, mas quando eu fiz essa pergunta, elas o fizeram. E com relação à resposta aceita; na época, ninguém mais se incomodou em responder à pergunta. Mais de dois anos depois, outra resposta foi publicada.
dkinzer

Respostas:

166

A resposta curta (TL; DR)

"Tree-ish" é um termo que se refere a qualquer identificador (como especificado na documentação de revisões do Git ) que finalmente leva a uma (sub) árvore de diretório (Git refere-se a diretórios como "árvores" e "objetos de árvore").

No caso do pôster original, foo é um diretório que ele deseja especificar. A maneira correta de especificar um diretório (sub) no Git é usar esta sintaxe "tree-ish" (item 15 da documentação de revisões do Git ):

<rev>:<path>, Por exemplo HEAD:README, :README,master:./README

Um sufixo :seguido de um caminho nomeia o blob ou a árvore no caminho especificado no objeto tree-ish nomeado pela parte antes dos dois pontos.

Portanto, em outras palavras, master:fooé a sintaxe correta, não master/foo.

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

Aqui está uma lista completa dos identificadores commit-ish e tree-ish (da documentação de revisões do Git , obrigado ao LopSae por apontá-lo ):

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

Os identificadores 1-14 são todos "commit-ish", porque todos levam a confirmações, mas como confirmações também apontam para árvores de diretório, todos acabam levando a objetos da (sub) árvore de diretório e, portanto, também podem ser usados ​​como "árvore". -ish ".

O número 15 também pode ser usado como árvore quando se refere a um diretório (sub), mas também pode ser usado para identificar arquivos específicos. Quando se refere a arquivos, não tenho certeza se ainda é considerado "tree-ish" ou se funciona mais como "blob-ish" (Git se refere a arquivos como "blobs").

A resposta longa

Nos níveis mais baixos, o Git mantém o controle do código-fonte usando quatro objetos fundamentais:

  1. Tags anotadas, que apontam para confirmações.
  2. Confirmações, que apontam para a árvore de diretórios raiz do seu projeto.
  3. Árvores, que são diretórios e subdiretórios.
  4. Blobs, que são arquivos.

Cada um desses objetos possui seu próprio ID de hash sha1, pois Linus Torvalds projetou o Git como um sistema de arquivos endereçável por conteúdo , ou seja, os arquivos podem ser recuperados com base em seu conteúdo (os IDs sha1 são gerados a partir do conteúdo do arquivo). O livro Pro Git fornece este exemplo de diagrama :

Figura 9-3 do livro Pro Git

Muitos comandos Git podem aceitar identificadores especiais para confirmações e (sub) árvores de diretório:

  • "Commit-ish" são identificadores que levam a um objeto de confirmação. Por exemplo,

    tag -> commit

  • "Tree-ish" são identificadores que levam a objetos de árvore (ou seja, diretório).

    tag -> commit -> project-root-directory

Como os objetos de confirmação sempre apontam para um objeto de árvore de diretório (o diretório raiz do seu projeto), qualquer identificador que seja "commit-ish" é, por definição, também "tree-ish". Em outras palavras, qualquer identificador que leve a um objeto de confirmação também pode ser usado para levar a um objeto de árvore (sub) de diretório .

Mas como os objetos da árvore de diretórios nunca apontam para confirmações no sistema de versão do Git, nem todo identificador que aponta para uma (sub) árvore de diretórios também pode ser usado para apontar para uma confirmação. Em outras palavras, o conjunto de identificadores "commit-ish" é um subconjunto estrito do conjunto de identificadores "tree-ish".

Conforme explicado na documentação ( obrigado a Trebor por me ajudar a encontrá-lo ):

<tree>

Indica um nome de objeto de árvore.

<commit>

Indica um nome de objeto de confirmação.

<tree-ish>

Indica uma árvore, confirmar ou marcar o nome do objeto. Um comando que aceita um <tree-ish> argumento, em última análise, deseja operar um <tree>objeto, mas desreferencias automaticamente <commit>e <tag>objetos que apontam para a <tree>.

<commit-ish>

Indica um nome de objeto de confirmação ou marca. Um comando que aceita um <commit-ish> argumento basicamente deseja operar em um <commit>objeto, mas desreferencia automaticamente os <tag>objetos que apontam para a <commit>.

O conjunto de identificadores tree-ish que não podem ser usados ​​como commit-ish são

  1. <rev>:<path>, que leva diretamente a árvores de diretório, não confirma objetos. Por exemplo HEAD:subdirectory,.

  2. Identificadores Sha1 de objetos da árvore de diretórios .

Comunidade
fonte
E a entrada 16 na sua mesa? Isso significa que você não tem certeza se é uma árvore ou não? O 0 refere-se ao estado de mesclagem, e esse conceito se aplica apenas a blobs, pois o índice nem contém diretórios. Consulte: stackoverflow.com/a/25806452/895245 . Portanto, a questão se resume a: todos os blob-ishes também são árvores? Tanto quanto eu posso dizer sim: todas as páginas homem que usam <tree-ish>aceitar ambos, e man gitrevisionsdefine: trees ("directories of files").
Ciro Santilli escreveu:
Observe que git-archivediz que é preciso um <tree-ish>mas não permite a <sha1>. Então eu acho que deveria pedir um <tree-ish-ish>. stackoverflow.com/a/12073669/680464
juanitogan 14/11
No entanto, eu me pergunto sobre o que acontece quando eu uso <rev>: (sem qualquer caminho ?. Ele funciona como tentou - mas não consigo encontrar a seção relevante na documentação.
Martin Vejmelka
49

Um tree-ish é uma maneira de nomear uma árvore específica, que pode ser uma das seguintes:

  • Referências como:
    • CABEÇA
    • Tag
    • Nomes das filiais
    • Nomes de filiais com controles remotos, como origin/somebranch
  • Cerquilha
  • Hash curto

No topo de que, qualquer um dos acima pode ser acrescentado com ^, ~. As referências também podem usar a @{}notação para alguns recursos adicionais:

  • HEAD^ou HEAD^1será resolvido para o primeiro pai do HEAD.
  • HEAD^2 resolverá para o segundo pai
  • HEAD^3será resolvido para o terceiro pai e assim por diante, o que é mais raro e o produto da fusão com a estratégia de polvo .
  • HEAD~ou HEAD~1resolverá para o primeiro pai da cabeça
  • HEAD~2resolverá para o primeiro pai do primeiro pai do HEAD. Isso seria o mesmo queHEAD^^
  • HEAD@{0} resolverá para o HEAD atual
  • HEAD@{1}resolverá para o cabeçalho anterior. Isso pode ser usado apenas por referências, pois faz uso do log de referência. No caso de HEADcada confirmação, mesclagem, o checkout alterará o valor de HEAD e, portanto, o adicionará ao log. git reflog HEADexibirá o log de referência onde você pode ver todos os movimentos do HEAD e corretamente o que @{1}e assim por diante resolverá.

A maioria dos acima pode ser ainda combinada enquanto faz sentido em seu repositório, por exemplo: HEAD@{2}~3, somebranch^2~4, c00e66e~4^2, anotherbranch~^~^~^.

Portanto, qualquer um dos descritos acima, e suas combinações, é o que se entende na documentação como uma árvore-ish, que é apenas uma maneira de dizer qual árvore (ou revisão) é aquela que deve ser usada para a maioria dos comandos git.

Mais informações em Seleção de revisão no livro Git .

LopSae
fonte
1
Essa resposta explica as revisões (commit-ishes) em geral e perde o caso crucial:, master:path/to/directoryque é um tree-ish, mas não um commit-ish. Cupcake torna isso mais claro.
Ciro Santilli escreveu:
11

Você provavelmente quer

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

A expressão master/foonão faz sentido: masteré um nome de filial e fooé um nome de diretório, como presumo.

Editar : (Removido link quebrado. Ver comentários.)

Sven Marnach
fonte
A palavra "árvore" não é mais encontrada no link "Git Treeishes". FYI
Robert
Treeish geralmente se refere à árvore de revisão, não a um layout de diretório.
Jürgen Strobel
6
@ JürgenStrobel: Isso não é verdade. Não se referia a nenhum dos dois - no passado, porque o termo não é mais usado na versão atual da documentação. (É também por isso que o link está quebrado.) Anteriormente, um treeish se referia a algo que poderia ser resolvido para um objeto de árvore no repositório de objetos do git. Isso incluiu qualquer especificação de confirmação, pois cada confirmação se refere a um único objeto de árvore. O objeto em árvore contém informações sobre a árvore de diretórios desse commit - consulte a seção sobre objetos git em "Pro Git" para obter detalhes.
Sven Marnach 19/09/12
6

Para definições <tree-ish>e <commit-ish>consulte a página do manual git (1) . Você precisará procurar os termos. Em geral, <tree-ish>significa uma referência a um objeto de árvore git, mas se você passar um tipo de objeto que faz referência a uma árvore (como uma confirmação ou ramificação), o git usará automaticamente a árvore referenciada.

Trebor Rude
fonte
E gitrevisions(7).
Xiong Chiamiov 13/09
0

Eu sou um novato no controle de origem e git. Isto é o que eu sei. Uma árvore é a estrutura dos arquivos em um repositório. É semelhante a um diretório em um sistema de arquivos. Consulte - Qual ferramenta git gerou essa visualização em árvore?

Árvore-ish significa como uma árvore. Refere uma parte ou confirmação de uma árvore. Você pode fazer referência a uma consolidação usando qualquer um destes: total ou parte do hash SHA-1 de uma consolidação, ponteiro HEAD, referência de ramificação, referência de marca. Outro método usa qualquer um dos métodos mencionados, juntamente com os ancestrais ou os pais de uma confirmação. Exemplo de antepassados: insira a descrição da imagem aqui

stack1
fonte
0

Do glossário do Git, tree-ish é "Um objeto de árvore ou um objeto que pode ser desreferenciado recursivamente a um objeto de árvore". commit, HEAD e tag são exemplos de objetos de árvore.

user2494386
fonte