Is git's semi-secret empty tree object reliable, and why is there not a symbolic name for it? Ask Question

Is git's semi-secret empty tree object reliable, and why is there not a symbolic name for it? Ask Question

Git has a well-known, or at least sort-of-well-known, empty tree whose SHA1 is:

4b825dc642cb6eb9a060e54bf8d69288fbee4904

(you can see this in any repo, even a newly created one, with git cat-file -t and git cat-file -p). [Edit made in 2020: the SHA-256 empty tree hash ID is:

6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321

as VonC mentions in his answer私の質問はどうやら8年ほど早かったようです。

一生懸命に、そして注意深く作業すれば、この空のツリーを、ファイルのないディレクトリを保存するために使うことができます(gitリポジトリに空のディレクトリを追加する方法の回答)、それはあまり良いアイデアではありませんが。

git diff-treeこれは、サンプル フックの 1 つが行うへの 1 つの引数として使用するとより便利です。

私が疑問に思っているのは、

  1. これはどの程度信頼できるのでしょうか。つまり、git の将来のバージョンでは、git オブジェクトに番号が付かなくなるのでしょうか4b825dc642cb6eb9a060e54bf8d69288fbee4904
  2. 空のツリーにシンボリックな名前がないのはなぜですか (あるいはあるのでしょうか)。

(シンボリック名を作成する簡単な方法は、たとえば SHA1 を入力することです.git/Nulltree。残念ながら、すべてのリポジトリに対してこれを行う必要があります。スクリプトなどにマジックナンバーを入力する方がよいようです。私はマジックナンバーが大嫌いなのです。)

ベストアンサー1

このスレッド言及:

空のツリー sha1 を覚えていない場合は、次のようにしていつでも導出できます。

git hash-object -t tree /dev/null

あるいは、チロ・サンティリ提案するコメント欄:

printf '' | git hash-object --stdin -t tree

あるいは、ここで見られる、 からコリン・シメルフィング:

git hash-object -t tree --stdin < /dev/null

したがって、そのコマンドの結果を持つ変数を空の sha1 ツリーとして定義する方が安全だと思います (「既知の値」に頼るのではなく)。

注: Git 2.25.1 (2020年2月)では、コミット 9c8a294:

empty_tree=$(git mktree </dev/null)

# Windows (Command Prompt):
git mktree <NUL

# Windows (PowerShell):
$null | git mktree

そしてこう付け加えた。

歴史的なメモとして、現在知られている関数はrepo_read_object_file()346245a1bb(「空のツリーオブジェクトをハードコードする」、2008-02-13、Git v1.5.5-rc0 --マージ)、そして現在知られている関数はoid_object_info()c4d9986f5f(「sha1_object_info:cached_objectストアも調べる」、2011-02-07、Git v1.7.4.1)。


注記: GitHub リポジトリによっては、最初のコミットを空にしたい場合に SHA1 がポップアップ表示されることがあります (ブログ投稿「Gitリポジトリを初期化する方法"):

$ GIT_AUTHOR_DATE="Thu, 01 Jan 1970 00:00:00 +0000" GIT_COMMITTER_DATE="Thu, 01 Jan 1970 00:00:00 +0000" git commit --allow-empty -m 'Initial commit'

以下を提供します:

空のツリー SHA1

(ツリー SHA1 を参照してください)

既存の履歴をその空のコミットの上にリベースすることもできます(「git: 最初のコミットを挿入し、他のすべてのコミットをシフトするにはどうすればよいでしょうか?

どちらの場合も、空のツリーの正確なSHA1値に頼る必要はありません
ベストプラクティスとして、最初の空のコミットでリポジトリを初期化する


それを行うには:

git init my_new_repo
cd my_new_repo
git config user.name username
git config user.email email@com

git commit --allow-empty -m "initial empty commit"

これにより、リポジトリ、ユーザー名、メール、作成日に応じたSHA1を持つコミットが生成されます(コミット自体のSHA1は毎回異なります)。
ただし、そのコミットで参照されるツリーは4b825dc642cb6eb9a060e54bf8d69288fbee4904、空のツリー SHA1。

git log --pretty=raw

commit 9ed4ff9ac204f20f826ddacc3f85ef7186d6cc14
tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904      <====
author VonC <[email protected]> 1381232247 +0200
committer VonC <[email protected]> 1381232247 +0200

    initial empty commit

コミットのツリーだけを表示するには(コミット ツリー SHA1 を表示):

git show --pretty=format:%T 9ed4ff9ac204f20f826ddacc3f85ef7186d6cc14
4b825dc642cb6eb9a060e54bf8d69288fbee4904

空のツリーを参照するそのコミットが本当にあなたの初めコミットすると、次のようにして空のツリー SHA1 を表示できます。

git log --pretty=format:%h --reverse | head -1 | xargs git show --pretty=format:%T
4b825dc642cb6eb9a060e54bf8d69288fbee4904

(Windowsでも動作しますが、Windows 上の Gnuコマンド)


として下記にコメント、使用git diff <commit> HEADすると、現在のブランチ HEAD 内のすべてのファイルが表示されます。

git diff --name-only 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD

注: 空のツリー値は、cache.h

#define EMPTY_TREE_SHA1_HEX \
    "4b825dc642cb6eb9a060e54bf8d69288fbee4904"

Git 2.16 (2018年第1四半期)以降、これはSHA1に縛られなくなった構造で使用されています。コミット eb0ccfd:

空のツリーとブロブの検索をハッシュ抽象化に切り替える

と の使用を切り替えてempty_tree_oid、現在使用中のハッシュ アルゴリズムを表す抽象化empty_blob_oidを使用します。current_hash

詳細は「Git はなぜもっと新しい SHA を使用しないのでしょうか?「:それはSHA-2Git 2.19 (2018年第3四半期) 以降


Git 2.25(2020年第1四半期)では、テストはSHA-2 移行、空のツリーが関係しています。

見るコミット fa26d5eコミット cf02be8コミット 38ee26bコミット 37ab8ebコミット 0370b35コミット 0253e12コミット 45e2ef2コミット 79b0edcコミット 840624fコミット 32a6707コミット 440bf91コミット 0b408caコミット 2eabd38(2019年10月28日)コミット 1bcef51コミット ecde49b(2019年10月5日)ブライアン・M・カールソン ( bk2204)(合併者
ジュニオ・C・ハマノ -- gitster--コミット 28014c1、2019年11月10日)

t/oid-info: 空のツリーと空のBLOB値を追加する

署名者: ブライアン・M・カールソン

テストスイートは、最終的には SHA-1 以外のアルゴリズムを使用して実行する方法を学びます。そのための準備として、test_oid空の BLOB と空のツリー値を検索して使用できるようにする方法を関数ファミリに教えます。

それでt/oid-info/hash-info以下が含まれるようになりました:

rawsz sha1:20
rawsz sha256:32

hexsz sha1:40
hexsz sha256:64

zero sha1:0000000000000000000000000000000000000000
zero sha256:0000000000000000000000000000000000000000000000000000000000000000

algo sha1:sha1
algo sha256:sha256

empty_blob sha1:e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
empty_blob sha256:473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813

empty_tree sha1:4b825dc642cb6eb9a060e54bf8d69288fbee4904
empty_tree sha256:6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321

SHA2 " 6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321" は新しい SHA1 " 4b825dc642cb6eb9a060e54bf8d69288fbee4904" の空のツリーです。

おすすめ記事