git的半隐秘空树对象是可靠的,为什么没有一个象征性的名字呢?

Git有一个众所周知的,或者至少是那种众所周知的空树,其SHA1是:

4b825dc642cb6eb9a060e54bf8d69288fbee4904 

(你可以在任何回购中看到这个,即使是新创建的,使用git cat-file -tgit cat-file -p )。

如果你努力工作,并且非常小心,你可以使用这个空树存储一个没有文件的目录(参见如何向git存储库添加一个空目录的答案 ),尽管这不是一个好主意。

作为示例钩子之一的git diff-tree一个参数更有用。

我想知道的是,

  1. 这个可靠性如何 – 也就是说,未来版本的git没有git对象,编号为4b825dc642cb6eb9a060e54bf8d69288fbee4904
  2. 为什么没有空树的符号名(或者是否有?)。

(创建一个符号名称的一个快速和肮脏的方法是将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

(见树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的主要版本。

两种方式是:

  1. 上面的答案: git hash-object -t tree --stdin < /dev/null
  2. 简单地启动一个空的repo,然后在新的repo中运行git write-tree – 这个hash将会被git write-tree输出。