핵심 정리
blob 파일 내용
tree 디렉터리 스냅샷과 파일 이름
commit tree + 부모 commit + 작성자 + 메시지
tag 특정 object에 붙는 이름표
ref object hash를 사람이 쓰기 쉬운 이름으로 가리킴구조 이해
Git은 파일 이름보다 content-addressable object를 먼저 저장한다
Git 내부 모델은 파일 경로를 먼저 저장하는 단순 폴더 복사본이 아니다. 파일 내용은 blob object로 저장되고, 그 내용의 hash가 식별자가 된다. 같은 내용은 같은 object로 참조될 수 있으므로 Git은 "파일 이름"보다 "내용과 그 내용의 주소"를 중심으로 동작한다.
git cat-file -t HEAD
git cat-file -p HEAD
git cat-file -p HEAD^{tree}tree object가 파일 이름과 디렉터리 구조를 연결한다
blob은 파일 내용만 알고 파일 이름을 모른다. 파일 이름, 실행 bit, 하위 디렉터리 구조는 tree object가 담는다. commit은 특정 tree를 가리키므로, 한 commit은 프로젝트 전체 스냅샷을 간접적으로 가리킨다. 이 구조 때문에 Git은 commit 하나만 있어도 해당 시점의 전체 파일 구조를 복원할 수 있다.
commit은 변경분이 아니라 스냅샷을 가리키는 기록이다
Git commit은 "이전 commit과의 diff" 자체를 저장하는 단위로 이해하기 쉽지만, 내부적으로는 특정 tree와 부모 commit, 작성자, 메시지를 담는 object다. diff는 두 commit이 가리키는 tree를 비교해 계산된다. 그래서 git diff A B는 저장된 patch를 읽는 것이 아니라 두 스냅샷의 차이를 계산하는 흐름이다.
ref가 hash 위에 사람이 쓰는 이름을 얹는다
branch, tag, HEAD는 object hash를 직접 외우지 않기 위한 ref 계층이다. main branch는 어떤 commit hash를 가리키는 이름이고, HEAD는 현재 작업 기준을 가리킨다. object model과 ref model을 분리해서 이해하면 reset, checkout, detached HEAD 상황을 더 안전하게 판단할 수 있다.
체크포인트
| 확인할 것 | 명령 |
|---|---|
| object 타입 | git cat-file -t <hash> |
| object 내용 | git cat-file -p <hash> |
| commit의 tree 보기 | git cat-file -p HEAD^{tree} |
| branch가 가리키는 commit | git rev-parse main |
| 현재 HEAD | git rev-parse HEAD |
공식 참고: Pro Git: Git Objects, Git Glossary
주의할 점
Git을 파일 복사본 모음처럼만 이해하면 reset, rebase, checkout의 결과를 예측하기 어렵습니다. commit은 tree 스냅샷을 가리키고, branch는 commit을 가리키는 ref라는 점을 분리해서 봐야 히스토리 조작이 안전해집니다.
실패 예시
- branch가 파일 묶음 자체라고 생각하고 reset을 실행함
- 결과: branch ref가 다른 commit으로 이동한 것을 작업 파일 삭제처럼 오해함
- 대응: object, commit, ref, working tree를 나눠서 상태를 확인한다참고 링크
2 sources