03-01 Git 내부 객체 모델
`.git` 안에서 실제로 무슨 일이 일어나는가 — blob/tree/commit 객체와 refs, packfile.
.git안에서 실제로 무슨 일이 일어나는가 — blob/tree/commit 객체와 refs, packfile.목표: Git을 “마법”이 아니라 단순한 내용 주소 저장소로 이해
🗄️ Git = 내용 주소 저장소
Git의 핵심은 키-값 저장소다. 내용을 넣으면 그 내용의 SHA-1 해시(키)를 돌려준다. 같은 내용은 항상 같은 해시 → 중복 자동 제거, 무결성 보장.
echo "hello" | git hash-object --stdin # 내용 → 해시
# ce013625030ba8dba906f756967f9e9ca394464a
🧱 4가지 객체 타입
graph TB
COMMIT["commit<br/>(스냅샷+메타)"] --> TREE["tree<br/>(디렉토리)"]
TREE --> BLOB1["blob<br/>(파일 내용)"]
TREE --> BLOB2["blob"]
TREE --> TREE2["tree<br/>(하위 디렉토리)"]
COMMIT --> PARENT["parent commit"]
TAG["tag<br/>(주석 태그)"] --> COMMIT
| 객체 | 저장 내용 |
|---|---|
| blob | 파일의 내용(이름·권한 없음) |
| tree | 디렉토리 — blob/tree 목록 + 이름 + 권한 |
| commit | tree 1개 + 부모 커밋 + 작성자/커미터/메시지 |
| tag | 주석 태그(커밋 가리킴 + 서명/메시지) |
[!tip] 스냅샷의 실체 “커밋 = 스냅샷”은 곧 커밋이 최상위 tree를 가리키고, tree가 blob들을 가리킨다는 뜻. 안 바뀐 파일은 같은 blob을 재사용해 공간을 아낀다.
🔬 직접 들여다보기 (plumbing 명령)
git cat-file -t <hash> # 객체 타입(blob/tree/commit)
git cat-file -p <hash> # 객체 내용 출력
git cat-file -p HEAD # 현재 커밋 객체
# 커밋이 가리키는 tree 탐색
git cat-file -p HEAD^{tree}
commit 객체 예시:
tree a1b2c3... ← 이 커밋의 스냅샷(디렉토리)
parent 9f3a1c... ← 부모 커밋
author Jongmin <..> 1717...
committer Jongmin <..> 1717...
feat: 로그인 추가
tree 객체 예시:
100644 blob e69de29... README.md
040000 tree 4d5e6f7... src
🔖 refs — 사람이 읽는 이름표
해시는 외우기 어렵다. ref는 해시를 가리키는 이름.
.git/refs/heads/main → 9f3a1c2... (브랜치)
.git/refs/tags/v1.0.0 → a1b2c3d... (태그)
.git/HEAD → ref: refs/heads/main (현재 위치)
git rev-parse HEAD # HEAD가 가리키는 실제 해시
git rev-parse main # 브랜치의 해시
cat .git/HEAD # HEAD 내용
- 브랜치 = 움직이는 ref(커밋하면 자동 전진)
- HEAD = 현재 브랜치를 가리키는 ref(detached HEAD면 커밋을 직접 가리킴)
📦 packfile — 압축 저장
객체가 많아지면 Git이 비슷한 객체를 델타 압축해 .git/objects/pack/에 모은다.
git gc # 정리·압축(garbage collection)
git count-objects -vH # 객체 수·크기 통계
git verify-pack -v ... # packfile 내용 검사
느슨한(loose) 객체 → packfile로 묶여 디스크·전송 효율↑.
🩺 무결성 검사
git fsck # 객체 무결성·연결 검사
git fsck --lost-found # 어디서도 참조 안 되는(dangling) 객체 찾기
dangling commit은 reflog·브랜치가 사라진 잃은 커밋일 수 있다 → 복구 단서.
📋 체크리스트
- Git이 내용 주소 저장소임을 이해
- blob/tree/commit/tag 역할
-
cat-file -p로 객체 탐색 - 커밋 → tree → blob 그래프 그리기
- refs와 HEAD의 의미
- detached HEAD 개념
- packfile·gc·fsck 용도
🔗 관련 노트
- 02-06-대화형-리베이스와-히스토리-정리 — 이전
- 03-02-bisect-worktree-submodule — 다음
- 01-01-Git-개념과-동작원리 — 스냅샷 개념
- 03-05-트러블슈팅과-재해-복구 — fsck로 복구
마지막 업데이트: 2026-06-02