[解決済み] git の半秘密の空のツリーオブジェクトは信頼できますか?なぜシンボル名がないのですか?
質問
Gitには、よく知られた、あるいは少なくともある種のよく知られた、SHA1が空のツリーがあります。
4b825dc642cb6eb9a060e54bf8d69288fbee4904
(これはどのレポでも、新しく作ったレポでも
git cat-file -t
と
git cat-file -p
). [
2020年に行われた編集
: SHA-256空木ハッシュIDは。
6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321
として VonCが回答で触れている . 私の質問は約8年早かったようです。????]
もしあなたが一生懸命に、そして非常に注意深く作業するならば、この空のツリーを、ファイルのないディレクトリを保存するために使うことができます(参照 空のディレクトリを git リポジトリに追加するにはどうすればよいですか? を参照)、あまり良いアイデアではありませんが。
の一つの引数としてより有用です。
git diff-tree
の1つの引数として、より有用です。
私が疑問に思っているのは
-
これはどの程度信頼できるのでしょうか。つまり、将来のバージョンの git には git オブジェクト番号がないのでしょうか。
4b825dc642cb6eb9a060e54bf8d69288fbee4904
? - なぜ空のツリーにはシンボル名がないのでしょうか(あるのでしょうか)。
(シンボル名を作成する手っ取り早い方法は、SHA1を入れることです、例,
.git/Nulltree
. 残念ながら、あなたはすべてのレポについてこれをしなければなりません。 スクリプトなどにマジックナンバーを入れる方がよさそうです。 私はマジックナンバーに一般的な嫌悪感を抱いているだけです)。
どのように解決するのですか?
このスレッド が言及しています。
空木のsha1を覚えていない場合は、常にで導出することができます。
git hash-object -t tree /dev/null
または、次のように チロ・サンティリ プロポーズ コメントで :
printf '' | git hash-object --stdin -t tree
または、次のように ここに見られる から Colin Schimmelfing :
git hash-object -t tree --stdin < /dev/null
というわけで、(よく知られた値に頼るのではなく)そのコマンドの結果を空のsha1ツリーとして変数に定義するのが安全だと思います。
注:Git 2.25.1 (Feb. 2020)では、Git 2.25.1 で提案された コミット 9c8a294 :
empty_tree=$(git mktree </dev/null)
# Windows:
git mktree <NUL
と追加します。
歴史的なメモとして、現在では
repo_read_object_file()
で空のツリーを教えていました。 346245a1bb ("hard-code the empty tree object", 2008-02-13, Git v1.5.5-rc0 --) で教えてもらいました。 マージ として知られている関数です)。oid_object_info()
で空のツリーを教えていました。 c4d9986f5f ("sha1_object_info
調べるcached_object
store too", 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を見てください)
その空のコミットの上に、既存の履歴をリベースすることもできます(" 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 :
<ブロッククオート空のツリーと blob の検索をハッシュの抽象化を使用するように切り替え
の使用方法を変更
empty_tree_oid
と
empty_blob_oid
を使用することで
current_hash
抽象化され、現在使用されているハッシュアルゴリズムが表示されます。
を使用します。
詳しくは"でご覧ください。 なぜGitはもっと現代的なSHAを使わないのですか? ": そうです。 SHA-2 , Git 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月05日)によって
ブライアン・M・カールソン (
bk2204
)
.
(によって統合されました。
ジュニオ・C・ハマノ--。
gitster
--
で
コミット 28014c1
, 2019年11月10日)
t/oid-info
: 空のツリーと空のブロブ値を追加署名: Brian M. Carlson
テストスイートはいずれ、SHA-1以外のアルゴリズムを使って実行する方法を学習します。この準備のために
test_oid
関数のファミリーに、空のブロブと空のツリーの値を調べる方法を教えて、それらが使えるようにします。
では
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
"空のツリーです。
関連
-
[解決済み] あなたのブランチは 'origin/master' より 3 コミット進んでいます。
-
[解決済み】ローカルに変更があるにもかかわらず、git pushが「すべて最新」と言う
-
[解決済み] git rebase fatal: 必要なリビジョンは1つです。
-
git push reports an error ! [リモート拒否] master -> master (受信前のフックが拒否されました)
-
[解決済み] 複数のコミットをチェリーピックする方法
-
[解決済み] ブラウンアウトの一環として、パスワード認証が一時的に無効になっています。代わりに個人用アクセストークンを使用してください[重複]。
-
[解決済み] fatal: bad revision "とはどういう意味ですか?
-
[解決済み] GitのFETCH_HEADとはどういう意味ですか?
-
[解決済み] git リモートリポジトリには、ローカルブランチにマージされていないコミットが含まれています。
-
[解決済み】Git: ベアリポジトリのActive Branchを変更する正しい方法?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】GitHubのメッセージの意味: メールのプライバシー制限のためプッシュが拒否されました。
-
[解決済み] [email protected] へのいくつかの参考文献のプッシュに失敗しました。
-
[解決済み] .gitignore と "以下の追跡されていない作業ツリーファイルはチェックアウトによって上書きされるでしょう"
-
[解決済み] git initを2回実行すると、リポジトリが初期化されますか?それとも既存のリポジトリを再初期化しますか?
-
[解決済み] git リモートリポジトリには、ローカルブランチにマージされていないコミットが含まれています。
-
[解決済み] git リポジトリの行数をカウントする
-
[解決済み] Gitで最初の2つのコミットをつぶす?重複
-
[解決済み】Git リポジトリに空のディレクトリを追加するには?
-
[解決済み】Gitでルートコミットの前にコミットを挿入する?
-
[解決済み] 新しい(そして空の!)「ルート」ブランチを作成する方法は?