Skip to main content

commit 생성시 .git 내부 변화


시나리오

  1. hello.txt 파일 생성
  2. git add hello.txt
  3. git commit -m "Add hello"

1. 작업 디렉토리 (Working Directory)

echo "Hello Git" > hello.txt
  • 파일 생성됨
  • 아직 Git은 이 파일을 추적하지 않음

2. git add hello.txt

git add hello.txt

내부 변화:

구성요소

변화 내용

.git/index

스테이징 영역에 파일 등록됨 (경로, 해시, 권한 등 저장)

.git/objects/

hello.txt

의 내용이

blob

객체로 저장됨 (SHA-1 해시 기반)

📦 예시 구조:

.git/
└── objects/
    └── 3a/
        └── 3efbed4aef... ← hello.txt의 blob 객체

3. git commit -m "Add hello"

내부 변화:

.git/objects/

객체

내용

tree

객체

커밋 당시의 디렉토리 구조 (hello.txt 포함)

commit

객체

커밋 메시지, 트리 포인터, 작성자 등 메타데이터 포함

.git/objects/
├── 3a/...(blob)
├── 47/... (tree)
└── a1/... (commit)

.git/refs/heads/main

  • 브랜치 포인터가 새 커밋 해시로 갱신됨
refs/heads/main → a1b2c3d4e5...

.git/HEAD

  • 여전히 ref: refs/heads/main 상태 → main 브랜치를 따라감

.git/logs/HEAD & logs/refs/heads/main

  • 커밋 전후 HEAD 포인터 변경 이력 추가됨 (reflog)
0000000 → a1b2c3d4 Commit: Add hello

전체 흐름 (커밋 1회 시)

📁 Working Directory       ← hello.txt 생성
    ↓ git add
📂 .git/index              ← 스테이징 정보 저장
    ↓ git commit
📦 .git/objects/
    ├── blob (파일 내용)
    ├── tree (디렉토리 구조)
    └── commit (메타데이터)

📄 .git/refs/heads/main    ← 브랜치 → 커밋 연결
    ↑
📌 .git/HEAD               ← 현재 브랜치 추적
🕓 .git/logs/              ← HEAD/브랜치 이력 추적

실제 파일 (커밋 후)

cat .git/HEAD
# ref: refs/heads/main

cat .git/refs/heads/main
# a1b2c3d4e5...

git ls-tree HEAD
# 100644 blob 3a3efbed...	hello.txt

git cat-file -p <커밋해시>
# tree 47fa...
# author ...
# message: Add hello

요약

단계

설명

git add

blob 객체 생성 + index 등록

git commit

tree + commit 객체 생성, 브랜치 포인터 이동

.git 내부

objects, refs, HEAD, logs 전부 갱신