1. 실습 개요
이번 실습에서는 Git 저장소를 직접 생성하고, 파일을 추가한 뒤 두 번의 commit을 수행하면서 .git 내부, 특히 .git/objects 디렉터리에 어떤 object가 생성되는지 관찰하였다.
또한 Git object 파일을 Python의 zlib.decompress()로 직접 열어 보고, commit / tree / blob object가 각각 어떤 정보를 담고 있는지도 확인하였다.
2. 진행한 작업
이번 실습은 PowerShell 환경에서 진행하였다.
실습 순서는 다음과 같다.
2-1. 저장소 생성 및 파일 추가
git init
echo "ossca" > a.txt
git add a.txt
git commit -m "첫번째 커밋"
2-2. 파일 수정 후 두 번째 커밋
"ossca study" | Out-File -Encoding utf8 a.txt
git add a.txt
git commit -m "두번째 커밋"
2-3. 생성된 object 확인
Get-ChildItem .git\\objects-Recurse-File
2-4. object 압축 해제 확인
예를 들어 두 번째 commit object는 아래와 같이 확인하였다.
python -c "import zlib; OBJECT_PATH=r'.git\\objects\\7b\\8819c6d32d120877db51b459cd3894e3c057fe'; data=zlib.decompress(open(OBJECT_PATH,'rb').read()); print(data); print(); print(data.decode(errors='replace'))"
tree object는 Git 명령으로 더 쉽게 확인할 수 있었다.
git cat-file -p f261758d74fb919ad6b381d6f7be894d4b6c034c
출력 결과:
100644 blob f853bacec969b422f71054a8b1810b9bb8f7ba29 a.txt
이를 통해 두 번째 tree가 a.txt와 두 번째 blob object를 가리키고 있음을 확인하였다.
3. object 관계 정리
이번 실습에서 생성된 object들은 다음과 같은 관계를 가진다.
첫 번째 상태
a.txt 내용 -> blob 9e0176...
↓
tree 2cdbd2...
↓
commit c137bd... ("첫번째 커밋")
두 번째 상태
a.txt 내용 -> blob f853ba...
↓
tree f26175...
↓
commit 7b8819... ("두번째 커밋")
↑
parent = c137bd...
- 파일 내용을 blob으로 저장하고
- 파일 목록과 blob 연결을 tree로 묶은 뒤
- 이를 가리키는 commit object를 생성하며
- 이전 commit과는 parent로 연결
4. 생성된 object 표 정리
해시 타입 의미
| 9e0176bd24d00fdb5b837f3a7bdd4db7611efd25 | blob | 첫 번째 a.txt 내용 (ossca) |
| 2cdbd2c5688b466cc9287982a9fc0ef26c3898b6 | tree | 첫 번째 시점의 디렉터리 스냅샷 |
| c137bde3269577c083c813cf30a9afdcd5504c6b | commit | 첫 번째 커밋 |
| f853bacec969b422f71054a8b1810b9bb8f7ba29 | blob | 수정된 a.txt 내용 (ossca study) |
| f261758d74fb919ad6b381d6f7be894d4b6c034c | tree | 두 번째 시점의 디렉터리 스냅샷 |
| 7b8819c6d32d120877db51b459cd3894e3c057fe | commit | 두 번째 커밋 |
총 6개의 object가 생성되었고, 구성은 다음과 같다.
- blob 2개
- tree 2개
- commit 2개
5. 느낀 점
이번 실습을 통해 Git의 commit이 단순한 파일 저장이나 메시지 기록이 아니라는 점을 확인할 수 있었다. object 파일을 직접 열어본 결과, Git은 파일 내용을 blob으로 저장하고, 이를 tree로 묶은 뒤, commit object가 해당 tree와 부모 commit을 가리키는 방식으로 동작하고 있었다. 특히 두 번째 commit에서 parent 항목이 나타나는 것을 보고, Git의 버전 관리가 단순한 덮어쓰기가 아니라 이전 상태와 연결된 구조라는 점이 인상적이었다.
겉으로는 간단한 명령어 몇 줄에 불과하지만, 내부적으로는 체계적인 객체 구조를 기반으로 버전 관리가 이루어진다는 점을 이해할 수 있었다. 이번 실습을 통해 앞으로 Git을 사용할 때 commit의 의미를 더 정확히 인식하면서 활용할 수 있을 것 같다.
'CS STUDY' 카테고리의 다른 글
| Valkey 커스텀 명령어 응답 가공하기: echo2_ prefix 붙이기 (0) | 2026.05.24 |
|---|---|
| Redis/Valkey는 Command를 어떻게 실행할까? - Valkey 커스텀 명령어를 만들어보자 (0) | 2026.05.21 |
| Redis, Valkey는 왜 빠를까? - 자료구조, 메모리 최적화, RESP 프로토콜 실습 (0) | 2026.05.10 |
| io_uring 개념과 epoll과의 비교 + 실제 코드 테스트 (0) | 2025.11.08 |