🗂️
Git은 내부적으로 어떻게 동작하나?
Blob, Tree, Commit — Git의 3가지 객체
Git이 '차분(diff)을 저장한다'는 건 흔한 오해다.
실제로는 각 커밋마다 파일 전체의 스냅샷을 저장한다. 다만 같은 내용의 파일은 같은 해시를 가지므로 중복 저장되지 않는다.
3가지 객체
Blob: 파일 내용. 파일명이 아니라 내용의 SHA-1 해시로 식별된다. 같은 내용은 어디에 있든 하나의 blob이다.
Tree: 디렉토리. 파일명 → blob 해시 매핑, 그리고 서브디렉토리 → tree 해시 매핑을 담는다.
Commit: 최상위 tree 해시 + 부모 커밋 해시 + 작성자 + 메시지. 이게 전부다.
브랜치는 포인터일 뿐
.git/refs/heads/main은 그냥 커밋 해시 한 줄이 적힌 텍스트 파일이다. 브랜치를 만드는 건 파일 한 개 만드는 것과 같다. Git 브랜치가 가볍다고 말하는 이유다.
HEAD는 '현재 어느 브랜치에 있는지'를 가리키는 또 다른 포인터다.
동작 흐름
1
`git add` → 파일 내용으로 blob 생성 (.git/objects/)
2
`git commit` → 현재 인덱스로 tree 생성, tree + 부모 + 메시지로 commit 생성
3
브랜치 포인터(.git/refs/heads/xxx)를 새 커밋 해시로 업데이트
4
`git log`은 HEAD → commit → parent → parent... 체인을 거슬러 올라간다
5
`git cat-file -p <hash>`로 아무 객체나 직접 열어볼 수 있다
사용 사례
Git 명령이 왜 그렇게 동작하는지 이해하기
손상된 저장소 복구 (reflog, fsck)
커스텀 도구 작성 (libgit2, rugged)