git은 파일 해시를 어떻게 계산합니까?
(에 의해 반환되는 트리 객체에 저장된 SHA1 해시 git ls-tree
()에 의해 반환되는 파일 내용의 SHA1 해시 일치하지 않습니다 sha1sum
)
$ git cat-file blob 4716ca912495c805b94a88ef6dc3fb4aff46bf3c | sha1sum
de20247992af0f949ae8df4fa9a37e4a03d7063e -
git은 파일 해시를 어떻게 계산합니까? 해시를 계산하기 전에 내용을 압축합니까?
힘내는 개체 앞에 "blob", 길이 (사람이 읽을 수있는 정수), NUL 문자
$ echo -e 'blob 14\0Hello, World!' | shasum 8ab686eafeb1f44702738c8b0f24f2567c36da6d
출처 : http://alblue.bandlem.com/2011/08/git-tip-of-week-objects.html
나는 답변을 확장 @Leif Gruenwoldt
하고 참조 에있는 내용을 자세히 설명 하고 있습니다.@Leif Gruenwoldt
스스로 해..
- 1 단계. 저장소에 빈 텍스트 문서 (이름은 중요하지 않음)를 작성하십시오.
- 2 단계. 문서 준비 및 커밋
- 3 단계. Blob의 해시를 실행하여 식별
git ls-tree HEAD
- 단계 4. Blob의 해시 찾기
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
- 5 단계. 놀라움을 피하고 아래 내용을 읽으십시오
GIT는 커밋 해시를 계산하는 방법
Commit Hash (SHA1) = SHA1("blob " + <size_of_file> + "\0" + <contents_of_file>)
텍스트 blob⎵
는 상수 접두사이며 \0
상수이며 NULL
문자입니다. <size_of_file>
및 <contents_of_file>
파일에 따라 달라집니다.
참조 : git commit 객체의 파일 형식은 무엇입니까?
그리고 모든 사람들입니다!
하지만 기다려! , 당신은이 통지 않았다 <filename>
해시 계산에 사용되는 매개 변수가 아니다? 내용이 생성 된 날짜와 시간 및 이름과 동일하지 않은 경우 두 파일의 해시가 동일 할 수 있습니다. 이것이 Git이 다른 버전 제어 시스템보다 이동 및 이름 바꾸기를 처리하는 이유 중 하나입니다.
스스로해라 (Ext)
- 6 단계.
filename
같은 디렉토리에 다른 빈 파일을 만듭니다.- 7 단계. 두 파일의 해시를 비교하십시오.
노트 :
링크는 tree
객체가 해시되는 방법을 언급하지 않습니다 . 나는 알고리즘과 매개 변수를 확신하지 못하지만 내 관찰에서 아마도 포함 된 모든 blobs
및 trees
( 해시 해시)를 기반으로 해시를 계산합니다.
git hash-object
테스트 방법을 확인하는 빠른 방법입니다.
s='abc'
printf "$s" | git hash-object --stdin
printf "blob $(printf "$s" | wc -c)\0$s" | sha1sum
산출:
f2ba8f84ab5c1bce84a7b441cb1959cfc7093b7f
f2ba8f84ab5c1bce84a7b441cb1959cfc7093b7f -
sha1sum
GNU Coreutils는 어디에 있습니다.
그런 다음 각 객체 유형의 형식을 이해합니다. 우리는 이미 사소한 것을 다루었 blob
습니다.
- commit : git commit 객체의 파일 형식은 무엇입니까?
- tree : 자식 트리 객체의 내부 형식은 무엇입니까?
- tag : Git Tag Object SHA1은 어떻게 생성됩니까?
Based on Leif Gruenwoldt answer, here is a shell function substitute to git hash-object
:
git-hash-object () { # substitute when the `git` command is not available
local type=blob
[ "$1" = "-t" ] && shift && type=$1 && shift
# depending on eol/autocrlf settings, you may want to substitute CRLFs by LFs
# by using `perl -pe 's/\r$//g'` instead of `cat` in the next 2 commands
local size=$(cat $1 | wc -c | sed 's/ .*$//')
( echo -en "$type $size\0"; cat "$1" ) | sha1sum | sed 's/ .*$//'
}
Test:
$ echo 'Hello, World!' > test.txt
$ git hash-object test.txt
8ab686eafeb1f44702738c8b0f24f2567c36da6d
$ git-hash-object test.txt
8ab686eafeb1f44702738c8b0f24f2567c36da6d
I needed this for some unit tests in Python 3 so thought I'd leave it here.
def git_blob_hash(data):
if isinstance(data, str):
data = data.encode()
data = b'blob ' + str(len(data)).encode() + b'\0' + data
h = hashlib.sha1()
h.update(data)
return h.hexdigest()
I stick to \n
line endings everywhere but in some circumstances Git might also be changing your line endings before calculating this hash so you may need a .replace('\r\n', '\n')
in there too.
참고URL : https://stackoverflow.com/questions/7225313/how-does-git-compute-file-hashes
'programing tip' 카테고리의 다른 글
NSCache를 사용하는 방법 (0) | 2020.07.14 |
---|---|
저장 프로 시저에 대한 명명 규칙은 무엇입니까? (0) | 2020.07.14 |
초기 커밋을 참조하는 방법? (0) | 2020.07.14 |
numpy를 가져온 후 멀티 프로세싱에서 단일 코어 만 사용하는 이유는 무엇입니까? (0) | 2020.07.14 |
일반 위임 매개 변수로 제공 될 때 람다 식을 캐스트해야하는 이유 (0) | 2020.07.14 |