
https://git-scm.com/book/ko/v2/Git%EC%9D%98-%EB%82%B4%EB%B6%80-Git-%EA%B0%9C%EC%B2%B4
Git이 개체를 어떻게 저장할까?
Git이 개체를 만드는 과정을 코틀린으로 표현해보았다.
Git은 개체의 타입을 Blob으로 만들면서 이를 시작으로 헤더를 만듦
val content = "개체를 어떻게 만들까?"
=> "개체를 어떻게 만들까?"
그 다음 공백 문자 하나, 내용의 크기, 마지막에 널 문자를 추가
val header = "blob ${content.length}\u0000"
=> "blob 12\u0000"
Git은 헤더와 원래 내용을 합쳐서 SHA-1 체크섬을 계산
이때 import java.security.MessageDigest로 라이브러리를 이용해 해시화를 진행
val store = header + content
val hash = MessageDigest.getInstance("SHA-1").digest(store.toByteArray())
val hashString = hash.joinToString("") {
String.format("%02x", it)
}
println(hashString)
println(hashString.length)
결과로 40자의 체크섬이 생성됨
275b0346177e468471e5b782e6d6f189302b5df8
40
위의 코드는 echo -n "개체를 어떻게 만들까??" | git hash-object --stdin와 같은 역할을 하는 것
그러나 비교해보면 정확히 같은 결과는 아님
맨 위의 참고 링크에서는 Ruby를 사용하여 비교해보는데, 같은 결과가 나옴
⇒ 정확한 차이는 잘 모르겠음
어쨌든 이렇게 체크섬을 생성한 후 이제 Git은 zlib으로 내용을 압축함
그 후 zlib으로 압축한 내용을 개체로 저장하는 것
SHA-1값의 맨 앞 두 글자를 가져와 .git/objects 디렉토리 안에 하위 디렉토리로 만들고, 나머지 38자를 그 디렉토리 안에 있는 파일 이름으로 사용
이 파일의 내용으로 zlib으로 압축한 내용을 저장함
이 과정이 Blob 개체를 만드는 과정
만약 Tree 개체나 Commit 개체를 만드려고 한다면 헤더를 만들 때 blob으로 시작하는 것이 아닌 tree나 commit으로 시작하면 됨