1. ホーム
  2. git

[解決済み] Gitのcommit-ishとtree-ishとは何ですか?

2022-06-24 07:32:49

質問

質問

Gitにおけるコミット的なもの、ツリー的なものの具体的な例を教えてください。

スタックオーバーフローの質問 "tree-ishはgitで何を意味するのでしょうか? は は具体的にtree-ishを扱っていますが、私はもっと理解したいのです。 .

背景

ドキュメンテーションでの使用

Git のドキュメント では、何度か "commit-ish"と ツリー的なもの("tree-ish")。例えば、もしあなたが 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

$ 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

定義

Git のドキュメント コミット的なもの」と「ツリー的なもの」が何であるかを定義しています。 :

<tree>

ツリーオブジェクトの名称を示す。

<commit>

コミットオブジェクト名を示す。

<tree-ish>

ツリー、コミット、タグのオブジェクト名を示す。を取るコマンドは <tree-ish> 引数を取るコマンドは、最終的に <tree> オブジェクトを操作したいのに、自動的に を参照しません。 <commit><tag> を指しているオブジェクトは <tree> .

<commit-ish>

コミットやタグのオブジェクト名を示す。を取るコマンドは <commit-ish> 引数を取るコマンドは、最終的に <commit> オブジェクトを操作したいのに、自動的に を参照しません。 <tag> オブジェクトを指す <commit> .

ドキュメントが十分に明確でない

上記のドキュメントでは、コミット的なものとツリー的なものが定義されていますが、私はまだ曖昧ではっきりしません。 私はまだそれがあまりにも曖昧で不明確であると感じています。

コミット的なもの」と「ツリー的なもの」の具体的な例と、それぞれの違いを教えてください。 それぞれどのように違うのでしょうか?

どのように解決するのですか?

簡単な答え (TL;DR)

コミット的、ツリー的な識別子の完全なリストはこちらです ( 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
----------------------------------------------------------------------

識別子#1-14はすべてコミットにつながるので、quot;commit-ish"です。 コミットはディレクトリツリーも指すので、最終的にこれらはすべて(サブ)ディレクトリツリーオブジェクトにつながります。 (サブ) ディレクトリ ツリー オブジェクトにつながるため、quot;tree-ish" として使用することができます。

#15 は、(サブ) ディレクトリを参照するときにもツリーとして使用できますが、特定のファイルを識別するためにも使用できます。 は、特定のファイルを識別するために使用することもできます。ファイルを参照するとき、私は ファイルを参照するとき、それがまだ "tree-ish" と見なされるのか、それとももっと "blob-ish" のように振る舞うのか、よくわかりません(Git はファイルを "blob-ish" として参照します)。 はファイルを"blob"として参照します)。

長い答え

Git におけるコミットとディレクトリツリー

最下層では、Gitは4つの基本的な オブジェクトを使用します。

  1. コミットを指し示す注釈付きタグ。
  2. プロジェクトのルートディレクトリツリーを指すコミット。
  3. ディレクトリとサブディレクトリであるツリー。
  4. ファイルであるブロブ。

Linus TorvaldsがGitのように設計したため、これらのオブジェクトはそれぞれ独自のsha1ハッシュIDを持っています。 のようにGitを設計しているからです。 コンテンツアドレス指定可能な ファイルシステムのように設計されています。 に基づいてファイルを取り出すことができます(sha1 IDはファイルの内容から生成されます)。The Pro Git の本では この例の図 :

コミット的なものとツリー的なもの

多くの Git コマンドは、コミットや(サブ)ディレクトリツリーに対して特別な識別子を指定することができます。 ツリーに対して特別な識別子を使うことができます。

  • "Commit-ish"は、最終的にコミットオブジェクトにつながる識別子を指します。例えば

    tag -> commit

  • "Tree-ish"は、最終的にツリー(すなわちディレクトリ)オブジェクトにつながる識別子です。

    tag -> commit -> project-root-directory

コミットオブジェクトは常にディレクトリツリーオブジェクト(プロジェクトのルートディレクトリ)を指すので ディレクトリを指すので、quot;commit-ish" である任意の識別子は、定義上 である識別子は、定義上、"tree-ish" でもあります。言い換えれば につながる任意の識別子は コミットオブジェクトにつながる識別子は、(サブ)ディレクトリツリーオブジェクトにつながるために使用することもできます。 .

しかし、Gitのバージョン管理システムでは、ディレクトリツリーオブジェクトがコミットを指すことはありません。 ではディレクトリツリー・オブジェクトはコミットを指すことはないので、(サブ)ディレクトリツリーを指すすべての識別子がコミットを指すために使えるわけではありません。 コミットを指すために使われるわけではありません。言い換えれば コミットっぽい識別子のセット は、"tree-ish" 識別子のセットの厳密なサブセットです。

ツリー的な識別子のセットで はコミット的なものとして使用できません。

  1. <rev>:<path> となり 直接 をコミットするのではなく、ディレクトリツリー オブジェクトではありません。例えば HEAD:subdirectory .

  2. のSha1識別子。 ディレクトリツリー オブジェクトを作成します。