developer tip

git의 semi-secret 빈 트리 객체는 신뢰할 수 있으며 왜 상징적 인 이름이 없습니까?

optionbox 2020. 8. 10. 07:56
반응형

git의 semi-secret 빈 트리 객체는 신뢰할 수 있으며 왜 상징적 인 이름이 없습니까?


Git에는 SHA1이 다음과 같은 잘 알려진 또는 적어도 잘 알려진 빈 트리가 있습니다.

4b825dc642cb6eb9a060e54bf8d69288fbee4904

(당신은 어떤 REPO에서도 새로 만든 하나를이 볼 수 git cat-file -tgit cat-file -p).

열심히 일하고 매우 조심한다면이 빈 트리를 사용하여 파일이없는 디렉터리를 저장할 수 있습니다 ( git 저장소에 빈 디렉터리를 추가하는 방법에 대한 답변 참조 ). 실제로 좋은 생각은 아닙니다.

git diff-tree샘플 후크 중 하나가하는에 대한 하나의 인수로 더 유용합니다 .

제가 궁금한 것은

  1. 이것이 얼마나 신뢰할 수 4b825dc642cb6eb9a060e54bf8d69288fbee4904있는가? 즉, 어떤 미래 버전의 git에 git 객체에 번호가 매겨지지 않을 것인가?
  2. 빈 나무에 대한 상징적 이름이없는 이유는 무엇입니까?

(상징적 이름을 만드는 빠르고 더러운 방법은 예를 들어 SHA1을 넣는 것 .git/Nulltree입니다. 불행히도 모든 저장소에 대해이 작업을 수행해야합니다. 스크립트 등에 매직 넘버를 넣는 것이 더 나은 것 같습니다. 저는 일반적인 혐오감을 가지고 있습니다. 매직 넘버에.)


이 스레드 는 다음을 언급합니다.

빈 트리 sha1을 기억하지 못하는 경우 언제든지 다음과 같이 파생 할 수 있습니다.

git hash-object -t tree /dev/null

또는 Ciro Santilli 가 의견에서 제안한 대로 :

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

또는 여기 에서 볼 수 있듯이 Colin Schimmelfing에서 :

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

따라서 해당 명령의 결과로 변수를 빈 sha1 트리 ( "잘 알려진 값"에 의존하는 대신)로 정의하는 것이 더 안전하다고 생각합니다.


작성자가 첫 번째 커밋을 비우기를 원할 때 일부 GitHub 저장소에 SHA1 팝업이 표시됩니다 (블로그 게시물 " 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'

당신에게 줄 것입니다 :

빈 트리 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 <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

참고 : 빈 트리 값은 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?"


I wrote up a blog post with two different ways of finding the hash: http://colinschimmelfing.com/blog/gits-empty-tree/

If it were to ever change for some reason, you could use the two ways below to find it. However, I would feel pretty confident using the hash in .bashrc aliases, etc., and I don't think it will change anytime soon. At the very least it would probably be a major release of git.

The two ways are:

  1. The answer above: git hash-object -t tree --stdin < /dev/null
  2. Simply initing an empty repo and then running git write-tree in that new repo - the hash will be output by git write-tree.

Here is the answer on how to create empty tree commit even in the case when the repository is not already empty. https://stackoverflow.com/a/14623458/9361507

But I prefer "empty" to be tag, but not a branch. Simple way is:

git tag empty $(git hash-object -t tree /dev/null)

Because tag can point to tree-ish directly, without commit. Now to get all the files in the working tree:

git diff --name-only empty

Or the same with stat:

git diff --stat empty

diff로 모든 파일 :

git diff empty

모든 파일에서 공백을 확인하십시오.

git diff --check empty

참고 URL : https://stackoverflow.com/questions/9765453/is-gits-semi-secret-empty-tree-object-reliable-and-why-is-there-not-a-symbolic

반응형