git的半秘密空树对象是可靠的,为什么没有它的象征性名称? [英] Is git's semi-secret empty tree object reliable, and why is there not a symbolic name for it?

查看:86
本文介绍了git的半秘密空树对象是可靠的,为什么没有它的象征性名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  4b825dc642cb6eb9a060e54bf8d69288fbee4904 

(你可以在任何回购中看到这个,甚至是一个新创建的回购, git cat-file -t git cat-file -p )。



如果您努力工作并且非常小心,则可以使用此空树来存储没有文件的目录(请参阅命令)






As 评论在下面,使用 git diff< commit> HEAD ,这会显示当前分支中的所有文件HEAD:

  git diff --name-only 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD 






注意:在 <$ c $中正式定义空树值c> cache.h

  #define EMPTY_TREE_SHA1_HEX \ 
4b825dc642cb6eb9a060e54bf8d69288fbee4904

现在是(Git 2.16,Q1 2018)结构不再与(仅)SHA1绑定,如提交eb0ccfd 所示:


切换空树和blob查找以使用散列抽象



切换使用 empty_tree_oid empty_blob_oid 使用
use中的 current_hash 抽象表示当前的散列算法。


请参阅为什么Git不使用更现代化的SHA?


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).

If you work hard and are very careful you can sort of use this empty tree to store a directory that has no files (see answer to How do I add an empty directory to a git repository), although it's not really a great idea.

It's more useful as one argument to git diff-tree, which one of the sample hooks does.

What I'm wondering is,

  1. how reliable is this—i.e., will some future version of git not have a git object numbered 4b825dc642cb6eb9a060e54bf8d69288fbee4904?
  2. Why is there no symbolic name for the empty tree (or is there one?).

(A quick and dirty way to create a symbolic name is to put the SHA1 in, e.g., .git/Nulltree. Unfortunately you have to do this for every repo. Seems better to just put the magic number in scripts, etc. I just have a general aversion to magic numbers.)

解决方案

This thread mentions:

If you don't remember the empty tree sha1, you can always derive it with:

git hash-object -t tree /dev/null

Or, as Ciro Santilli proposes in the comments:

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

So I guess it is safer to define a variable with the result of that command as your empty sha1 tree (instead of relying of a "well known value").


Note, you will see that SHA1 pop up on some GitHub repo when the author wants its first commit to be empty (see blog post "How I initialize my Git repositories"):

$ 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'

Will give you:

(See the tree SHA1?)

You can even rebase your existing history on top of that empty commit (see "git: how to insert a commit as the first, shifting all the others?")

In both cases, you don't rely on the exact SHA1 value of that empty tree.
You simply follow a best practice, initializing your repo with a first empty commit.


To do that:

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"

That will generate a commit with a SHA1 specific to your repo, username, email, date of creation (meaning the SHA1 of the commit itself will be different every time).
But the tree referenced by that commit will be 4b825dc642cb6eb9a060e54bf8d69288fbee4904, the empty tree 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

To show just the tree of a commit (display the commit tree SHA1):

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

If that commit, referencing an empty tree, is indeed your first commit, you can show that empty tree SHA1 with:

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

(and that even works on Windows, with Gnu On Windows commands)


As commented below, using git diff <commit> HEAD, this will show all your file in the current branch HEAD:

git diff --name-only 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD


Note: that empty tree value is formally defined in cache.h.

#define EMPTY_TREE_SHA1_HEX \
    "4b825dc642cb6eb9a060e54bf8d69288fbee4904"

It is now (Git 2.16, Q1 2018), use in a structure which is no longer tied to (only) SHA1, as seen in commit eb0ccfd:

Switch empty tree and blob lookups to use hash abstraction

Switch the uses of empty_tree_oid and empty_blob_oid to use the current_hash abstraction that represents the current hash algorithm in use.

See more at "Why doesn't Git use more modern SHA?"

这篇关于git的半秘密空树对象是可靠的,为什么没有它的象征性名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆