1. ホーム
  2. git

[解決済み] Gitにおけるtree-ishの意味とは?

2022-07-05 03:05:26

質問

をどのように使えばいいのか、とても困っています。 git archive .

git リポジトリに、フォルダ Foo , バー バズ をトップレベルにしています。 フォルダをエクスポートする必要があります。 Foo をSVN的な方法でエクスポートして、素早くテストデプロイできるようにしたいのです。

を使うことができることを知りました。 git-archive の中に SVN的なエクスポートのような方法で .

しかし、ここからが本題です。 以下は問題なく動作します。

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

であり、その結果 Foo , バー , バズ フォルダを 宛先 フォルダーに格納されます。

しかし、次のようにするとエラーになります。 と共に fatal not a valid object name :

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

ドキュメンテーション

のシノプシスを見ると git archive プログラムの概要を見ると、このプログラムは <tree-ish> [path] をパラメータとして受け取ることができます(あらすじを関連する部分に要約しています)。

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

もし master/foo tree-ish であるならば、何であるか?

どのように解決する?

簡単な答え (TL;DR)

"Tree-ish"は、任意の識別子(以下のように指定されたもの)を指す用語です。 Git のリビジョンに関する文書 で指定されている)、最終的に(サブ)ディレクトリにつながるあらゆる識別子を指します。 ツリー (Gitでは、ディレクトリのことを "ツリー" および "ツリーオブジェクト" と呼びます) に最終的につながります。

元の投稿者の場合 foo はディレクトリ を指定したい。 を指定します。Gitで(サブ)ディレクトリを指定する正しい方法は、次のようなものです。 ツリー的な構文 (項目番号15) です。 Git リビジョン ドキュメント ):

<rev>:<path> は、例えば HEAD:README , :README , master:./README

接尾辞 : の後にパスを指定すると、指定したパスにあるブロブまたはツリーを指定します。 コロンの前の部分によって名付けられたツリー状のオブジェクトを指定します。

つまり、言い換えれば master:foo が正しい構文であって master/foo .

その他ツリー的なもの(プラスコミット的なもの)

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

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

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

長い答え

最も低いレベルでは、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" 識別子のセットの厳密なサブセットです。

で説明されているように ドキュメント ( を見つけるのを手伝ってくれたTreborに感謝します。 をありがとうございました。 ):

<tree>

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

<commit>

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

<tree-ish>

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

<commit-ish>

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

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

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

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