Quick Flow
Git은 파일의 diff를 차례로 저장하기보다 content-addressed object와 그 object를 가리키는 ref로 snapshot history를 만듭니다. object ID 길이와 algorithm은 repository format에 따라 달라지므로 hash를 고정 문자열 길이로 가정하지 않습니다.
blob: file content
<- tree: name, mode, blob/subtree 연결
<- commit: root tree, parent commit(s), metadata
<- branch / tag ref
HEAD -> current branch ref -> current commit| 대상 | 담는 것 | 확인 명령 |
|---|---|---|
| blob | 경로 없는 file content | git cat-file -p <blob> |
| tree | name·mode·object ID | git ls-tree <tree> |
| commit | root tree·parent·author·message | git cat-file -p HEAD |
| annotated tag | target object와 tag metadata | git cat-file -t/-p <tag> |
| ref | 사람이 읽는 object name | git rev-parse <ref> |
object와 경로의 역할
blob은 content만 저장하며 filename이나 directory를 모릅니다. tree가 filename, mode, blob/subtree object를 묶고, commit이 root tree와 parent commit을 가리킵니다. 그래서 commit 하나는 해당 시점 프로젝트의 전체 tree를 가리키며, git diff A B는 저장된 patch를 읽는 것이 아니라 두 tree를 비교합니다.
같은 content는 같은 repository format 안에서 같은 object ID로 참조될 수 있지만, file path는 attributes filter 적용 여부에 영향을 줄 수 있습니다. object ID는 content-addressing의 key이지 사람이 외워야 하는 영구 business ID나 보안 서명이 아닙니다. SHA-1과 SHA-256 object format을 모두 지원하므로 현재 storage format은 git rev-parse --show-object-format=storage로 확인합니다.
ref와 HEAD의 차이
local branch는 tip commit을 가리키는 movable ref이고, annotated tag는 tag object를 통해 target object를 가리킬 수 있습니다. HEAD는 보통 현재 branch를 가리키는 symbolic ref이며, detached HEAD에서는 commit을 직접 가리킵니다. reset, rebase, merge를 실행하기 전에 어떤 ref가 이동하고 worktree/index가 어떻게 달라지는지를 별도로 봐야 하는 이유입니다.
object가 있어도 ref에서 더 이상 도달하지 않으면 reflog와 garbage collection 정책에 따라 나중에 찾기 어려워질 수 있습니다. 실험 commit을 보존하려면 branch/tag를 붙이고, remote에도 남겨야 한다면 그 ref를 push합니다.
직접 확인하기
git cat-file -t HEAD, git cat-file -p HEAD, git ls-tree HEAD, git symbolic-ref --short HEAD, git rev-parse HEAD를 순서대로 실행해 object와 ref를 분리해 봅니다. production repository에서 hash-object -w로 임의 object를 쓰거나 내부 파일을 직접 편집하는 것은 학습 목적 외에는 피합니다.
branch는 파일 묶음이 아니라 commit을 가리키는 ref입니다. ref 이동과 object 삭제, index·worktree 변경을 같은 일로 생각하면 reset·rebase·detached HEAD의 결과를 잘못 예측하게 됩니다.
참고 링크
3 sources