树形在 Git 中是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4044368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 09:22:25  来源:igfitidea点击:

What does tree-ish mean in Git?

gitgit-archive

提问by dkinzer

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

我对如何使用git archive.

I have a git repository with folder Foo, Barand Bazat the top level. I need to export folder Fooin a SVN-ish sort of way for quick test deployment.

我有一个 git 存储库,顶层有文件夹 FooBarBaz。我需要以类似于SVN 的方式导出文件夹Foo以进行快速测试部署。

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

我了解到我可以git-archive以一种SVN 式导出方式使用

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

但事情就是这样,以下工作正常:

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

it results in Foo, Bar, Bazfolders in the destinationfolder.

它会在目标文件夹中生成FooBarBaz文件夹。

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

然而,下面就会因错误使用fatal not a valid object name

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

The Documentation

文档

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

作为git archive程序的概要,我看到它可以将 a<tree-ish> [path]作为参数(概要汇总到相关部分):

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

Ifmaster/foois nottree-ish, then what is?

如果master/foo不是tree-ish,那么什么是?

回答by

The Short Answer (TL;DR)

简答 (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").

“Tree-ish”是一个术语,指的是最终导致(子)目录树(Git 将目录称为“树”和“树对象”)的任何标识符(如Git 修订文档中所指定)。

In the original poster's case, foois a directorythat 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):

在原始海报的情况下,foo他想要指定的目录。在 Git 中指定(子)目录的正确方法是使用这种“树形”语法(Git 修订文档中的第 15 项):

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

<rev>:<path>, 例如HEAD:README, :README,master:./README

后缀:后跟路径在由冒号之前的部分命名的树形对象中的给定路径上命名 blob 或树。

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

因此,换句话说,master:foo是正确的语法,而不是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 标识符列表(来自Git 修订文档感谢 LopSae 指出):

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

标识符 #1-14 都是“commit-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").

#15 在引用(子)目录时也可以用作 tree-ish,但它也可以用于标识特定文件。当它提到文件时,我不确定它是否仍然被认为是“树形”,或者行为更像是“blob-ish”(Git 将文件称为“blob”)。

The Long Answer

长答案

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

在最底层,Git 使用四个基本对象来跟踪源代码:

  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.
  1. 带注释的标签,指向提交。
  2. 提交,指向项目的根目录树。
  3. 树,即目录和子目录。
  4. Blob,它们是文件。

Each of these objects has its own sha1 hash ID, since Linus Torvalds designed Git like an content- addressablefilesystem, 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:

这些对象中的每一个都有自己的 sha1 哈希 ID,因为 Linus Torvalds 将 Git 设计为一个内容可寻址的文件系统,即可以根据其内容检索文件(sha1 ID 是从文件内容生成的)。Pro Git book 给出了这个示例图

Figure 9-3 from Pro Git book

图 9-3 来自 Pro Git 书籍

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

许多 Git 命令可以接受提交和(子)目录树的特殊标识符:

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

  • “Commit-ish”是最终导致提交对象的标识符。例如,

    tag -> commit

  • “Tree-ish”是最终导致树(即目录)对象的标识符。

    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.

由于提交对象始终指向目录树对象(项目的根目录),因此任何“commit-ish”标识符根据定义也是“tree-ish”。换句话说,任何指向提交对象的标识符也可以用来指向(子)目录树对象

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.

但由于目录树对象从不指向 Git 版本控制系统中的提交,因此并非每个指向(子)目录树的标识符也可用于指向提交。换句话说,“commit-ish”标识符集合是“tree-ish”标识符集合的严格子集。

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

文档所述感谢 Trebor 帮助我找到它):

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

<tree>

表示树对象名称。

<commit>

表示提交对象名称。

<tree-ish>

表示树、提交或标记对象名称。一个接受<tree-ish>参数的命令最终想要对一个<tree>对象进行操作,但会自动取消引用<commit><tag>指向 a 的对象<tree>

<commit-ish>

表示提交或标记对象名称。带有<commit-ish>参数的命令最终想要对一个<commit>对象进行操作,但会自动取消引用<tag>指向 a 的对象<commit>

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

不能用作 commit-ish的一组 tree-ish 标识符是

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

  2. Sha1 identifiers of directory treeobjects.

  1. <rev>:<path>,这直接导致目录树,而不是提交对象。例如,HEAD:subdirectory

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

回答by LopSae

A tree-ish is a way of naming a specific tree which can be one of the following:

tree-ish 是一种命名特定树的方法,它可以是以下之一:

  • References like:
    • HEAD
    • Tags
    • Branch names
    • Branch names with remotes, like origin/somebranch
  • Hash
  • Short hashes
  • 参考如:
    • 标签
    • 分行名称
    • 带有遥控器的分支名称,例如 origin/somebranch
  • 哈希
  • 短哈希

On top of that, any of the above can be appended with ^, ~. References can also use the @{}notation for some additional features:

最重要的是,上述任何一项都可以附加^, ~。参考文献还可以使用该@{}符号来表示一些附加功能:

  • HEAD^or HEAD^1will be resolved to the first parent of HEAD.
  • HEAD^2will resolve to the second parent
  • HEAD^3will resolve to the third parent and so on, which is more rare and product of merges with the octopus strategy.
  • HEAD~or HEAD~1will resolve to the first parent of head
  • HEAD~2will resolve to the first parent of the first parent of HEAD. This would be the same as HEAD^^
  • HEAD@{0}will resolve to the current HEAD
  • HEAD@{1}will resolve to the previous head. This can only be used by references since it makes use of the reference log. In the case of HEADevery commit, merge, checkout will change the value of HEAD and thus add it to the log. git reflog HEADwill display the reference log where you can see all the movements of HEAD and properly what @{1}and so on will resolve to.
  • HEAD^HEAD^1将解析为 HEAD 的第一个父级。
  • HEAD^2将解决第二个父母
  • HEAD^3将解析到第三个父级等,这是更罕见的,是与章鱼策略合并的产物 。
  • HEAD~HEAD~1将解析为 head 的第一个父级
  • HEAD~2将解析为 HEAD 的第一个父级的第一个父级。这将与HEAD^^
  • HEAD@{0}将解析为当前的 HEAD
  • HEAD@{1}将解决到以前的头。这只能由引用使用,因为它使用了引用日志。在HEAD每次提交、合并、签出的情况下,都会更改 HEAD 的值,从而将其添加到日志中。git reflog HEAD将显示参考日志,您可以在其中看到 HEAD 的所有移动以及正确的@{1}解析等等。

Most of the above can be further combined as long as it makes sense in your repository, for example: HEAD@{2}~3, somebranch^2~4, c00e66e~4^2, anotherbranch~^~^~^.

只要在您的存储库中有意义,以上大部分内容都可以进一步组合,例如:HEAD@{2}~3, somebranch^2~4, c00e66e~4^2, anotherbranch~^~^~^

So any of the described above, and its combinations, is what is meant in the documentation as a tree-ish, which is just a way to say what tree (or revision) is the one that should be used for most of git commands.

因此,上述任何一种及其组合在文档中都表示为树状,这只是说明大多数 git 命令应该使用哪种树(或修订版)的一种方式。

More info in Revision Selection in the Git book.

更多信息请参阅 Git 手册中的修订选择

回答by Sven Marnach

You probably want

你可能想要

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

The expression master/foodoes not make sense: masteris a branch name and foois a directory name, as I presume.

这个表达式master/foo没有意义:我认为master是一个分支名称和foo一个目录名称。

Edit: (Removed broken link. See comments.)

编辑:(删除断开的链接。请参阅评论。)

回答by Trebor Rude

For definitions of <tree-ish>and <commit-ish>see the git(1)man page. You'll have to search for the terms. In general <tree-ish>means a reference to a git tree object, but if you pass a type of object that references a tree (such as a commit or branch), git will automatically use the referenced tree.

有关定义<tree-ish><commit-ish>参见git(1)手册页。您必须搜索这些条款。一般<tree-ish>是指对 git 树对象的引用,但是如果传递了引用树的对象类型(例如提交或分支),git 将自动使用引用的树。

回答by stack1

I am a newbie to source control and git. This is what I know. A tree is the structure of files in a repository. Its similar to a directory in a file system.See - Which git tool generated this tree view?

我是源代码控制和 git 的新手。这是我所知道的。树是存储库中文件的结构。它类似于文件系统中的目录。请参阅 - 哪个 git 工具生成了此树视图?

Tree-ish means like a tree. It references a part or commit of a tree. You can reference a commit using any one of these: full or part of the SHA-1 hash of a commit, HEAD pointer, branch reference, tag reference. Another method uses any of the mentioned methods along with ancestors or parents of a commit. Ancestors example: enter image description here

Tree-ish 的意思是像一棵树。它引用树的一部分或提交。您可以使用以下任何一种来引用提交:提交的全部或部分 SHA-1 哈希、HEAD 指针、分支引用、标签引用。另一种方法使用任何提到的方法以及提交的祖先或父母。祖先例子: 在此处输入图片说明

回答by user2494386

From Git Glossarytree-ish is "A tree object or an object that can be recursively dereferenced to a tree object." commit, HEAD and tag are examples of tree-ish objects.

来自Git 词汇表tree-ish 是“一个树对象或一个可以递归取消引用到树对象的对象。” commit、HEAD 和 tag 是树形对象的示例。