본문 바로가기
C.W.K.
Stream
Lesson 01 of 04 · published

Object: blob, tree, commit, tag

~22 min · objects, internals

Level 0추적 전 새싹
0 XP0/47 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

네 가지 object와 content-addressable store

Git이 아는 모든 것은 .git/objects/에 blob, tree, commit, tag 네 object 가운데 하나로 저장되고 내용의 SHA-1 hash로 주소를 얻어. repo 안에서 이 넷을 구분할 수 있으면 높은 수준의 Git 명령도 마법처럼 보이지 않아. 결국 네 모양을 만들고 연결하고 가리키는 일이거든.

Blob은 파일 하나의 raw byte만 저장해. 파일 이름도 permission도 없이 내용만 있어. 같은 내용을 가진 파일 둘은 같은 blob hash를 얻어 한 번만 저장돼. Tree는 directory listing을 저장해. 이름과 mode, 파일을 담은 blob 또는 하위 directory를 담은 tree의 hash가 있어. Tree가 blob에 이름과 구조를 부여하는 셈이야.

Commit은 root tree hash, parent commit hash, author와 committer 및 timestamp, message를 묶은 작은 object야. parent를 따라가면 이력을 거슬러 올라가고 tree를 열면 그 시점의 프로젝트 snapshot으로 들어가. Tag는 metadata가 있는 이름표 object로 annotated tag에 쓰여. Lightweight tag는 tag object가 아니라 ref일 뿐이야.

이 store는 내용으로 주소를 정해. echo "hello" | git hash-object --stdin은 hash를 계산하고 git cat-file -p <hash>는 object를 다시 읽어. Hash의 첫 두 글자는 .git/objects/ 아래 directory 이름, 나머지 38글자는 파일 이름이 돼서 .git/objects/3a/4f5d6e... 같은 모양이 나와. repo가 커지면 Git은 많은 object를 pack file로 압축하지만 mental model은 그대로야. hash → object → content야.

Code

Repo 의 object 타입 투어·bash
# 최신 commit:
HASH=$(git rev-parse HEAD)

# Commit object 읽기:
git cat-file -p $HASH
# 출력에 tree, parent, author, committer, 메시지 표시.

# Commit 이 가리키는 root tree 읽기:
TREE=$(git cat-file -p $HASH | head -1 | awk '{print $2}')
git cat-file -p $TREE
# 각 줄: <mode> <type> <hash>\t<name>

# Tree 에서 blob hash 골라 읽기:
git cat-file -p <blob-hash>

# Hash 의 타입은?
git cat-file -t $HASH        # commit
git cat-file -t $TREE        # tree
Object 수동 계산 + 저장·bash
# 저장 없이 hash 계산:
echo "hello world" | git hash-object --stdin

# Blob 으로 .git/objects/ 에 계산 + 저장:
echo "hello world" | git hash-object --stdin -w

# Hash 로 다시 읽기:
git cat-file -p <hash>

# HEAD tree 의 모든 unique blob hash list:
git ls-tree -r HEAD | awk '{print $3, $4}'

External links

Exercise

작은 repo에서 git rev-parse HEAD로 commit hash를 얻고 git cat-file -p를 commit, 그 commit의 tree, tree의 blob 하나에 차례로 실행해 chain을 직접 걸어봐. git ls-tree -r HEAD | wc -l로 현재 snapshot의 blob 수를 세고, 전에 잘못 이해했을 수 있는 Git 저장 방식에 관해 확인한 사실 둘을 적어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.