git的半隐秘空树对象是可靠的,为什么没有一个象征性的名字呢?
Git有一个众所周知的,或者至少是那种众所周知的空树,其SHA1是:
4b825dc642cb6eb9a060e54bf8d69288fbee4904
(你可以在任何回购中看到这个,即使是新创建的,使用git cat-file -t
和git cat-file -p
)。
如果你努力工作,并且非常小心,你可以使用这个空树存储一个没有文件的目录(参见如何向git存储库添加一个空目录的答案 ),尽管这不是一个好主意。
作为示例钩子之一的git diff-tree
一个参数更有用。
我想知道的是,
- 这个可靠性如何 – 也就是说,未来版本的git没有git对象,编号为
4b825dc642cb6eb9a060e54bf8d69288fbee4904
? - 为什么没有空树的符号名(或者是否有?)。
(创建一个符号名称的一个快速和肮脏的方法是将SHA1放在.git/Nulltree
。不幸的是,你必须为每一个回购做这个,似乎更好的方法就是把这个神奇的数字放在脚本中,等等。对魔法数字有一个普遍的反感。)
这个线程提到:
如果你不记得空树sha1,你总是可以得到它:
git hash-object -t tree /dev/null
或者,正如Ciro Santilli 在评论中提出的那样 :
printf '' | git hash-object --stdin -t tree
所以我猜想用这个命令的结果定义一个变量作为你的空sha1树(而不是依赖“众所周知的值”)是比较安全的。
请注意,当作者希望第一次提交为空时,您将看到SHA1在某个GitHub 仓库中弹出(请参阅博客文章“ 我如何初始化我的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"
这将生成一个具有特定于您的repo,用户名,电子邮件,创建日期(这意味着提交本身的SHA1每次都会有所不同)的SHA1提交。
但是提交引用的树将是4b825dc642cb6eb9a060e54bf8d69288fbee4904
,即空树SHA1。
git log --pretty=raw commit 9ed4ff9ac204f20f826ddacc3f85ef7186d6cc14 tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 <==== author VonC <vonc@laposte.net> 1381232247 +0200 committer VonC <vonc@laposte.net> 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上使用Gnu On Windows命令)
正如下面的评论 ,使用git diff <commit> HEAD
,这将显示当前分支中的所有文件HEAD:
git diff --name-only 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD
我用两种不同的方法找到这个哈希来写一篇博文: http : //colinschimmelfing.com/blog/gits-empty-tree/
如果由于某种原因而改变,可以使用下面的两种方法来找到它。 不过, 我觉得在.bashrc别名中使用哈希值会很自信,我不认为它会很快改变。 至少它可能是git的主要版本。
两种方式是:
- 上面的答案:
git hash-object -t tree --stdin < /dev/null
- 简单地启动一个空的repo,然后在新的repo中运行
git write-tree
– 这个hash将会被git write-tree输出。