Refs, HEAD, 그리고 index 파일
Object 는 내용. Ref 는 이름. Commit 이 main 이나 v2.4.0 같은 사람 읽을 수 있는 이름 갖는 이유는 .git/ 아래 refs/ 계층: hash 하나씩 든 작은 파일들 + 옛 entry 의 packed-refs. Git 이 네가 어디 있는지 아는 이유는 HEAD — ref 가리키는 (또는 detached 면 직접 commit 가리키는) 특수 pointer. 이 셋 — ref, HEAD, index — 이 object database 와 일상 명령 사이 다리.
Ref 가 sub-tree 셋에 살아. refs/heads/<name> 이 local branch. refs/remotes/<remote>/<branch> 가 remote-tracking branch — 마지막 fetch 시 remote 가 가졌던 것의 네 시점 read-only 그림자. refs/tags/<name> 이 tag (lightweight tag 는 직접 hash, annotated tag 는 tag object 가리킴). git for-each-ref 가 한 query 로 모두 walk, housekeeping 에 유용.
HEAD 가 Git 이 모든 연산에서 수정하는 유일한 pointer. 파일 내용은 보통 ref: refs/heads/main — branch 에 대한 symbolic ref. Commit 하면 Git 이 commit object 업데이트, branch ref 를 새 commit 으로 업데이트, HEAD 는 같은 branch 가리키는 채로 (이제 새 tip 에). Branch switch 하면 HEAD 의 symbolic-ref 내용 바뀜. 특정 commit checkout 하면 HEAD 가 직접 hash 됨 — 그게 detached HEAD.
Index 가 세 번째 구조. .git/index 에 저장된 binary 파일, 다음 commit 의 tree 가 어떻게 생길지 묘사 — Git 이 추적하는 모든 path, mode, blob hash, timestamp, 진행 중 merge 의 stage 정보. git ls-files --stage 가 읽어. git diff 가 working tree 와 index 비교, git diff --staged 가 index 와 HEAD tree 비교. Index 가 존재하는 이유는 git add — 없으면 모든 commit 이 all-or-nothing 이어야 함.