
이 사진의 있는 objects 데이터의 파일 내용은 git cat-file -p 해시값을 했을 때 확인할 수 있는 내용이지 실제 .git/objects/해시값앞2자리/나머지38글자 파일에 저장되는 값이 아니다. objects 디렉터리 아래 파일에 저장되는 데이터는 원본 파일 내용과 헤더를 압축한 것이다.
Git 개체들이 저장되는 곳이다. 자세한 내용은 이전글을 읽고 오길 바란다. 다음 사진은 objects 디렉터리 내부의 예시이다.

index 파일은 staging area라고 생각해도 좋다.그리고 .git 디렉터리 아래에 있다.
git add될 때마다 add된 파일의 blob 개체를 index 파일에 추가한다.
index 파일에는 파일모드, objects 디렉터리에 있는 SHA-1 해시값, 파일명이 들어간다. 다음은 index 파일 내부의 예시이다.

-p 옵션을 주면 개체의 내용을 확인할 수 있고, -t 옵션을 주면 개체의 종류(blob, tree, commit)을 확인할 수 있다.
git cat-file -t 해시값 명령어를 했을 때 개체 종류를 알 수 있을까?git이 objects 디렉터리 아래에 개체를 저장할 때,
blob #{content.length}\0 이 형식으로 헤더를 만들고
헤더와 파일 내용을 합쳐서 압축을 해 저장한다.
그래서 압축된 내용으로부터 파일 타입을 알 수 있다.
위 결론에 도달하면서 내가 잘못 생각하고 있었던 부분을 알게 되었다. git cat-file -p 해시값 명령어를 사용하여 파일의 내용을 확인하면서 objects 디렉터리 아래에 저장되는 데이터는 파일 내용만 저장되는 줄 알았다. 하지만 헤더와 파일 내용을 압축한 것이 개체로 저장되는 것이다. 그리고 git cat-file -p 해시값 이 명령어는 그저 사람이 있을 수 있게 파일 내용을 출력해주는 명령어였던 것이다.
git add를 하게 되면 파일의 내용을 objects 디렉터리 아래에 개체로 저장을 하고 index를 업데이트한다.
이 때 index를 업데이트한다는 것은 워킹 트리에서 staging area에 파일을 추가할 때 실제 깃은 워킹 트리에 있는 내용을 그대로 두고 스테이지에 해당 파일이 추가된다는 것이다.
staging area에 해당하는 index 파일을 스냅샷을 떠 Tree 개체를 만든다. 이 Tree 개체를 내용을 포함하는 Commit 개체를 만든다. 이 두 Tree 개체와 Commit 개체가 objects 디렉터리 아래에 추가된다.
이 때 첫 커밋은 참조하는 부모 커밋이 없지만 두 번째 커밋부터는 부모 커밋을 참조한다.
$ git cat-file -p fdf4fc3
tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
parent 부모 커밋 개체 해시값
author Scott Chacon <schacon@gmail.com> 1243040974 -0700
committer Scott Chacon <schacon@gmail.com> 1243040974 -0700
first commit
그리고 커밋에 대한 정보가 logs 디렉터리 아래에 저장된다.
logs 디렉터리에 저장된 커밋 정보

git status는 아직 add되지 않은 파일과 add된 파일을 출력으로 나타내고, 커밋된 후에는 출력에서 사라진다.
add를 하면 index에는 추가는 됐는데 커밋은 안 된 상태이고,
index 파일과 최신 커밋을 비교해서 상태를 추적할 수 있다.
먼저 add되지 않은 상태는 index 파일과 파일 수정 개체 값이 다르고,
add된 상태는 index 파일과 최신 커밋에 포함된 Tree 개체의 내용과 불일치할 것이다.
