Git中的commit-ish和tree-ish是什么? [英] What are commit-ish and tree-ish in Git?

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

问题描述

问题



Git中的commit-ish和tree-ish的具体示例是什么?



堆栈溢出问题tree-ish在git中的含义是什么? 特别针对
树进行处理,但我想更多地了解 背景

文档中的用法



Git文档对commit-ish和
tree-ish做了几处引用。例如,如果您正在检查 Git源代码

  $ git grep --files-with-matches --extended-regexpcommit( - )* 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
词汇表内容.txt
howto / revert-branch-rebase.txt
revisions.txt

  $ git grep --files-with-matches --extended-regexptree( - )* 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



定义



Git文档定义了什么commit-ish和tree-ish是

< blockquote>

 <树> 

表示树形对象名称。

 <提交> 

表示一个提交对象名称。

 <树肥胖型> 

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

 < commit-ish> 

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



文档不够清晰



即使上述文档定义了什么commit-ish和tree-ish是什么,
我仍​​然觉得它太模糊和不清楚。


什么是commit-ish和tree-ish的具体例子,以及它们是如何彼此不同的? 解决方案

简短答案(TL; DR)



下面是一个完整的commit-ish和tree-ish标识符列表(来自 Git
修订文档
):


  ----------------------------------- --- -------------------------------- 
| Commit-ish / Tree-ish |示例
--------------------------------------------- -------------------------
| 1.< sha1> | dae86e1950b1277e545cee180551750029cfe735
| 2.< describeOutput> | v1.7.4.2-679-g3bee7fb
| 3.< refname> |主,头/主,参考/头/主
| 4.< refname> @ {< date>} | master @ {yesterday},HEAD @ {5分钟前}
| 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> |主〜3
| 11.< rev> ^ {< type>} | v0.99.8 ^ {commit}
| 12.< rev> ^ {} | v0.99.8 ^ {}
| 13.< rev> ^ {/< text> | | HEAD ^ {/修复讨厌的bug}
| 14.:/< text> | :/修复讨厌的bug
----------------------------------------- -----------------------------
|树只是| |示例
--------------------------------------------- -------------------------
| 15.< rev>:<路径> | HEAD:README.txt,master:子目录/
---------------------------------- ------------------------------------
|树十岁上下? |示例
--------------------------------------------- -------------------------
| 16.:< n>:<路径> | :0:README,:README
--------------------------------------- -------------------------------



标识符#1-14都是commit-ish,因为它们全都导致提交,但
因为提交也指向目录树,它们最终都会导致
(sub)目录树对象,因此也可以用作tree-ish。

#15也可以用作tree-ish到(子)目录,但
也可以用来识别特定的文件。当它涉及到文件时,我不是
,如果它仍然被认为是树状,或者更像是blob-ish(Git
将文件称为blob)。


长答案



Git中的提交和目录树



在最低级别,Git使用四个基本的
对象跟踪源代码:


  1. 带注释的标签,它指向提交。

  2. 提交,指向项目的根目录树。

  3. 树,即目录和子目录。
  4. >
  5. Blob,它们是文件。

这些对象中的每一个都有自己的sha1哈希ID,因为Linus Torvalds将 content-addressable 文件系统设计为
Git,即文件可以被检索为
关于他们的内容(sha1 ID是从文件内容生成的)。 Pro Git
书提供了这个示例图





Commit-ish vs Tree-ish



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


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

    标签 - >提交


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

    标签 - >提交 - >项目根目录




因为commit对象总是指向一个目录树对象你的项目的根目录
),任何标识符commit-ish,由
定义,也是tree-ish。换句话说,任何导致
提交对象的标识符都可以用来指向(子)目录树对象 。



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

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


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


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



The Question

What are specific examples of commit-ish and tree-ish in Git?

The Stack Overflow question "What does tree-ish mean in git?" deals with tree-ish specifically, but I want to understand more about both.

Background

Usages in Documentation

The Git documentation makes several references to "commit-ish" and "tree-ish". For example, if you're examining the Git source code:

$ 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

and

$ 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

Definitions

The Git documentation defines what "commit-ish" and "tree-ish" are:

<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 Documentation isn't Clear Enough

Even though the documentation above defines what "commit-ish" and "tree-ish" are, I still find it to be too vague and unclear.

What are specific examples of "commit-ish" and "tree-ish", and how are they different from each other?

解决方案

The Short Answer (TL;DR)

Here's a complete list of commit-ish and tree-ish identifiers (from the Git revisions documentation):

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

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

Commits and Directory Trees in Git

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:

Commit-ish vs Tree-ish

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.

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中的commit-ish和tree-ish是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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