객체 탐색기
git은 복잡하다는 평판이 있어요. 그 평판의 거의 전부는 모델을 한 번도 본 적이 없다는 데서 와요. 네 가지 객체, 그리고 포인터가 전부인데 말이죠. 커밋을 클릭해 그 트리로 내려가고, 내 파일이 사실은 트리가 이름을 붙여 준 블롭이라는 것을 확인하고 나면, 포슬린 명령들은 더 이상 마법이 아니게 돼요.
⌘K → 객체 탐색기. 이 화면은 단 1바이트도 바꿀 수 없어요 — 뒤에서
일어나는 호출은 전부 읽기예요.

네 가지 객체
| 객체 | 무엇인가 | 무엇을 아는가 |
|---|---|---|
| blob | 파일의 내용 | 아무것도 몰라요. 이름도, 경로도, 히스토리도 |
| tree | 디렉터리 목록 | 이름, 모드, 그리고 자식 blob이나 tree 각각의 sha |
| commit | 스냅샷 하나 | 자기 트리, 부모들, 작성자, 커미터, 메시지 |
| tag | 주석 달린 태그 | 가리키는 객체, 태그를 단 사람, 메시지 |
대부분의 사람이 놀라는 건 첫 번째 줄이에요. 블롭에는 이름이 없어요. 히스토리 어디에 있든 내용이 같은 두 파일은 같은 블롭이고, 한 번만 저장돼요. 이름은 그것을 가리키는 트리에 있어요 — git이 파일이 아니라 내용을 추적하는 이유, 그리고 이름 변경이 기록되는 게 아니라 탐지되는 이유가 바로 이거예요.
ref — refs/heads/main, refs/tags/v1.0, HEAD — 는 sha 하나가 들어 있는
파일일 뿐이에요. "브랜치는 싸다"는 말의 전부가 이것이에요.
걸어 다니기
왼쪽 열은 저장소의 모든 ref를, git이 묶는 방식 그대로 묶어서 나열해요. 하나를 클릭하면 그것이 이름 붙인 객체로 이동해요.
거기서부터는 전부 링크예요:
- commit 은 자기
tree와 각parent를 보여줘요 — 스냅샷으로 건너가거나, 히스토리를 한 커밋씩 거슬러 올라갈 수 있어요. - tree 는 항목들을 모드, 타입, sha, 크기와 함께 나열해요. 이름을 클릭하면 그 자식이 열려요.
- blob 은 텍스트를 보여주고(큰 것은 앞부분만), 이진 파일이면 그렇다고 분명히 말해요.
- 주석 달린 태그 는 무엇을 가리키는지 보여줘요 — 클릭하면 그 커밋으로 넘어가요.
뒤로 는 지나온 길을 되짚어요.
리비전 입력하기
입력란은 git rev-parse 가 받아들이는 것이면 무엇이든 받아요. 이 도구가 단순한
탐색기이길 그만두고 배우는 수단이 되는 지점이 여기예요:
| 이렇게 입력하면 | 이런 것이 나와요 |
|---|---|
HEAD |
현재 커밋 |
HEAD~3 |
세 커밋 이전 |
HEAD^{tree} |
그 커밋의 트리를 벗겨 낸 것 |
HEAD:src/app.ts |
그 경로의 블롭을 곧바로 |
v1.0^{} |
태그 객체가 아니라, 주석 달린 태그가 가리키는 것 |
a1b2c3d |
sha로 지정한 아무 객체 — 축약형도 통해요 |
트리 목록의 모드 숫자는 알아 둘 만해요. 100644 는 파일, 100755 는 실행
파일, 040000 은 하위 트리, 120000 은 심볼릭 링크, 160000 은 서브모듈
gitlink예요 — 마지막 그것이 서브모듈이 저장하는 것의 전부고요.
알아둘 만한 한계
- 일부러 읽기 전용이에요. 여기에는 쓸 수 있는 도구가 없어요. 객체를 손으로
만드는 건
git hash-object연습이고, 터미널에서 할 일이에요. - 큰 블롭은 잘려요 — 처음 200 KB까지만요. 그게 무엇인지 보기에는 충분하고, 창을 멎게 하기에는 모자란 양이죠.
- 크기는
git cat-file -s가 보고하는 객체의 내용 크기이지, 팩으로 묶인 뒤 디스크에서 드는 비용이 아니에요. 그건 유지 보수를 보세요. - 도달 불가 객체도 여전히 객체예요.
git fsck의 dangling 보고에서 sha를 복사해 붙여 넣으면 열려요. 잃어버린 커밋에 무엇이 들어 있었는지, 복구할지 결정하기 전에 확인하는 가장 빠른 방법인 경우가 많아요.