在Git中树是什么意思? [英] What does tree-ish mean in Git?

查看:136
本文介绍了在Git中树是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很困惑如何使用 git archive



我有一个包含文件夹的git存储库 Foo Bar Baz 在顶层。我需要以SVN-ish的方式导出文件夹 Foo 以进行快速测试部署。



我知道我可以使用 git-archive 在(感谢Trebor帮助
找到了
):


 < tree> 

表示树形对象名称。

 <提交> 

表示一个提交对象名称。

 <树肥胖型> 

表示树,提交或标记对象名称。采用< tree-ish>
参数的命令最终希望在< tree> 对象,但自动
dereferences < commit> < tag> < tree>

 < commit-ish> 

表示提交或标记对象名称。采用< commit-ish>
参数的命令最终希望对< commit> 对象,但自动为
dereferences < tag> 指向< commit> 的对象。


不能用作commit-ish的树形标识符
$ b


  1. < rev>:<路径> ,它直接将 导向目录树,而不是提交
    对象。例如, HEAD:子目录


  2. 目录树的Sha1标识符 对象。



I'm very confused about how to use git archive.

I have a git repository with folder Foo, Bar and Baz at the top level. I need to export folder Foo in a SVN-ish sort of way for quick test deployment.

I learned that I could use git-archive in an SVN-ish export sort of way.

But here's the thing, The following works fine:

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

it results in Foo, Bar, Baz folders in the destination folder.

However, the following will error out with fatal not a valid object name:

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

The Documentation

Looking as the synopsis for the git archive program I see that it can take a <tree-ish> [path] as a parameter (synopsis summarized to relevant parts):

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

If master/foo is not tree-ish, then what is?

解决方案

The Short Answer (TL;DR)

"Tree-ish" is a term that refers to any identifier (as specified in the Git revisions documentation) that ultimately leads to a (sub)directory tree (Git refers to directories as "trees" and "tree objects").

In the original poster's case, foo is a directory that he wants to specify. The correct way to specify a (sub)directory in Git is to use this "tree-ish" syntax (item #15 from the Git revisions documentation):

<rev>:<path>, e.g. HEAD:README, :README, master:./README

A suffix : followed by a path names the blob or tree at the given path in the tree-ish object named by the part before the colon.

So, in other words, master:foo is the correct syntax, not master/foo.

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

Here's a complete list of commit-ish and tree-ish identifiers (from the Git revisions documentation, thanks to LopSae for pointing it out):

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

Identifiers #1-14 are all "commit-ish", because they all lead to commits, but because commits also point to directory trees, they all ultimately lead to (sub)directory tree objects, and can therefore also be used as "tree-ish".

#15 can also be used as tree-ish when it refers to a (sub)directory, but it can also be used to identify specific files. When it refers to files, I'm not sure if it's still considered "tree-ish", or if acts more like "blob-ish" (Git refers to files as "blobs").

The Long Answer

At its lowest levels, Git keeps track of source code using four fundamental objects:

  1. Annotated tags, which point to commits.
  2. Commits, which point to the root directory tree of your project.
  3. Trees, which are directories and subdirectories.
  4. Blobs, which are files.

Each of these objects has its own sha1 hash ID, since Linus Torvalds designed Git like an content- addressable filesystem, i.e. files can be retrieved based on their content (sha1 IDs are generated from file content). The Pro Git book gives this example diagram:

Many Git commands can accept special identifiers for commits and (sub)directory trees:

  • "Commit-ish" are identifiers that ultimately lead to a commit object. For example,

    tag -> commit

  • "Tree-ish" are identifiers that ultimately lead to tree (i.e. directory) objects.

    tag -> commit -> project-root-directory

Because commit objects always point to a directory tree object (the root directory of your project), any identifier that is "commit-ish" is, by definition, also "tree-ish". In other words, any identifier that leads to a commit object can also be used to lead to a (sub)directory tree object.

But since directory tree objects never point to commits in Git's versioning system, not every identifier that points to a (sub)directory tree can also be used to point to a commit. In other words, the set of "commit-ish" identifiers is a strict subset of the set of "tree-ish" identifiers.

As explained in the documentation (thanks to Trebor for helping me find it):

<tree>

Indicates a tree object name.

<commit>

Indicates a commit object name.

<tree-ish>

Indicates a tree, commit or tag object name. A command that takes a <tree-ish> argument ultimately wants to operate on a <tree> object but automatically dereferences <commit> and <tag> objects that point at a <tree>.

<commit-ish>

Indicates a commit or tag object name. A command that takes a <commit-ish> argument ultimately wants to operate on a <commit> object but automatically dereferences <tag> objects that point at a <commit>.

The set of tree-ish identifiers that cannot be used as commit-ish are

  1. <rev>:<path>, which leads directly to directory trees, not commit objects. For example, HEAD:subdirectory.

  2. Sha1 identifiers of directory tree objects.

这篇关于在Git中树是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆