04. 커밋(Commit) — 변경 이력 기록하기
git add로 변경을 스테이지에 담고,git commit으로 기록한다- 커밋 메시지를 잘 작성하는 법을 안다
- HEAD, 커밋 ID(해시)가 무엇인지 이해한다
git log로 이력을 조회하고,git diff로 변경 내용을 비교한다
4.1 커밋(Commit)이란?
커밋은 "이 순간의 변경 사항을 저장소에 영구히 기록하는 것"입니다. 앞 장의 비유로는 장바구니(스테이지)에 담은 것을 결제(저장)하는 행위입니다.
커밋 하나에는 다음이 함께 기록됩니다.
- 변경된 파일들의 스냅샷 (그 순간의 전체 사진)
- 누가 커밋했는가 (앞에서 설정한 user.name/email)
- 언제 커밋했는가 (날짜·시간)
- 왜/무엇을 바꿨는가 (커밋 메시지)
- 고유 ID (커밋 해시)
이 커밋들이 사슬처럼 연결되어 프로젝트의 전체 역사를 이룹니다.
gitGraph
commit id: "초기버전"
commit id: "기능추가"
commit id: "버그수정"
commit id: "문서작성"
위 그래프에서 가장 오른쪽 커밋이 HEAD(현재 위치)가 가리키는 최신 커밋입니다. 커밋들이 사슬처럼 연결되어 프로젝트의 전체 역사를 이룹니다.
4.2 새 파일은 어떻게 감지될까?
3장에서 만든 readme.txt는 Untracked(추적 안 됨) 상태였습니다. Git은 새 파일이 생기면 자동으로 추적하지 않습니다. 개발자가 명시적으로 "이 파일을 관리해"라고 알려줘야 합니다. 그 명령이 바로 git add입니다.
git status # 현재 상태 확인
Untracked files:
readme.txt
4.3 스테이지에 담기 — git add
# 특정 파일 하나 담기 git add readme.txt # 여러 파일 담기 git add file1.txt file2.txt # 현재 폴더의 모든 변경 사항 담기 (가장 많이 씀) git add . # 수정/삭제된 추적 파일 전부 담기 (새 파일 제외) git add -u
git add 후 상태를 확인해봅시다.
git status
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: readme.txt
이제 readme.txt가 "Changes to be committed"(커밋 대기) 상태, 즉 장바구니에 담겼습니다.
소스트리에서 스테이지에 담기
소스트리에서는 Unstaged files 영역에서 파일을 선택하고 "Stage Selected" 버튼(또는 파일 옆 체크박스)을 누르면 됩니다. git add와 정확히 같은 동작입니다. 위쪽 Staged files 영역으로 파일이 올라갑니다.
4.4 스테이지에서 빼기 — git restore --staged
장바구니에 잘못 담았다면 다시 뺄 수 있습니다.
# 신버전 (권장) git restore --staged readme.txt # 구버전 (여전히 동작) git reset HEAD readme.txt
git status를 치면 친절하게 "빼는 방법"을 알려줍니다. 안내 문구를 잘 읽는 습관을 들이세요.소스트리에서는 Staged 영역의 파일을 선택하고 "Unstage"를 누르면 됩니다.
restore --staged는 스테이지에서만 내리고 파일 내용은 그대로 둡니다. 파일 내용 자체를 되돌리는 git restore 파일명(staged 옵션 없음)과 혼동하지 마세요.4.5 HEAD란 무엇인가?
HEAD는 "지금 내가 어디에 있는지" 가리키는 포인터입니다. 보통은 가장 최근 커밋을 가리킵니다.
flowchart RL
C3["커밋3"] --> C2["커밋2"] --> C1["커밋1"]
HEAD(["🔖 HEAD"]) -.-> C3
classDef head fill:#fde68a,stroke:#d97706,color:#92400e
classDef commit fill:#dcfce7,stroke:#16a34a,color:#166534
class HEAD head
class C1,C2,C3 commit
"나는 지금 커밋3 위에 있다" — HEAD가 최신 커밋을 가리킵니다.
첫 커밋을 하기 전에는 HEAD가 가리킬 커밋이 없습니다. 그래서 git status에 "No commits yet"이 떴던 것입니다. 첫 커밋을 하면 HEAD가 그 커밋을 가리키기 시작합니다.
HEAD는 브랜치 장에서 매우 중요해지니, 지금은 "현재 위치를 가리키는 화살표" 정도로 기억하세요.
4.6 커밋하기 — git commit
이제 장바구니(스테이지)에 담긴 것을 기록(결제)합시다.
방법 A — -m 옵션으로 메시지 한 줄 작성 (가장 많이 씀)
git commit -m "Add readme file"
[main (root-commit) a1b2c3d] Add readme file 1 file changed, 1 insertion(+) create mode 100644 readme.txt
a1b2c3d가 이 커밋의 ID(해시) 앞부분입니다. 첫 커밋이라 root-commit이라고 표시됩니다.
방법 B — 에디터로 메시지 작성
git commit
-m을 생략하면 설정한 에디터(vi 또는 VS Code)가 열립니다. 여러 줄의 상세한 메시지를 쓸 때 좋습니다.
vi 에디터 탈출법 (입문자 필수!)
실수로 vi가 열렸을 때 당황하지 마세요.
1.i를 눌러 입력 모드 진입 → 메시지 작성
2.Esc키
3.:wq입력 후 Enter (저장 후 종료)
그냥 나가려면:q!
방법 C — add와 commit 동시에 (-a 옵션)
이미 추적 중인 파일의 수정은 add를 건너뛰고 바로 커밋할 수 있습니다.
git commit -a -m "Update readme" # 또는 git commit -am "Update readme"
-a는 이미 추적 중인 파일에만 적용됩니다. 새 파일(Untracked)은 반드시 git add를 먼저 해야 합니다.소스트리에서 커밋
소스트리 하단에 커밋 메시지 입력란이 있습니다. Staged 파일이 있는 상태에서 메시지를 쓰고 "Commit" 버튼을 누르면 됩니다.
4.7 좋은 커밋 메시지 작성법
커밋 메시지는 미래의 나와 동료에게 보내는 편지입니다. "수정함", "ㅁㄴㅇㄹ" 같은 메시지는 나중에 큰 후회를 부릅니다.
권장 형식
제목: 50자 이내, 무엇을 했는지 명령형으로 본문: (필요시) 한 줄 띄우고, 왜 이렇게 바꿨는지 설명. 72자마다 줄바꿈 권장.
좋은 예 vs 나쁜 예
| 나쁜 예 ❌ | 좋은 예 ✅ |
|---|---|
수정 | Fix login button not responding on mobile |
ㅎㅎ | Add user email validation |
최종본 | Update API endpoint to v2 |
버그픽스2 | Fix crash when cart is empty |
빈 커밋 메시지는 불가
메시지 없이 커밋하려 하면 Git이 커밋을 거부합니다(에디터에서 빈 채로 저장 시 abort). 메시지는 필수입니다. (단, --allow-empty-message 같은 옵션으로 강제할 수는 있으나 권장하지 않습니다.)
마지막 커밋 메시지 수정 — --amend
방금 한 커밋의 메시지를 잘못 썼다면:
git commit --amend -m "올바른 메시지"
--amend는 커밋을 새로 만드는 것입니다(해시가 바뀜). 이미 push(공유)한 커밋에는 사용하지 마세요. 협업 중 혼란을 일으킵니다.4.8 커밋 이력 보기 — git log
git log
commit a1b2c3d4e5f6... (HEAD -> main)
Author: Hong Gildong <hong@example.com>
Date: Mon Jun 23 14:30:00 2026 +0900
Add readme file
유용한 log 옵션
# 한 줄로 간결하게 (가장 많이 씀) git log --oneline # 최근 3개만 git log -3 # 그래프로 브랜치 흐름 보기 git log --oneline --graph --all # 각 커밋의 변경 내용까지 git log -p # 통계(몇 줄 추가/삭제)와 함께 git log --stat # 특정 작성자만 git log --author="Gildong"
--oneline 출력 예시:
a1b2c3d (HEAD -> main) Add readme file 9f8e7d6 Initial commit
소스트리에서 로그 확인
소스트리의 좌측 메뉴 "History" 또는 "Log"를 누르면 커밋들이 시간순 그래프로 나타납니다. 각 커밋을 클릭하면 작성자, 날짜, 메시지, 변경 파일이 한눈에 보입니다. CLI의 git log --graph를 시각화한 것입니다.
4.9 커밋 ID(해시)란?
각 커밋에는 40자리 16진수의 고유 ID가 붙습니다. 이것이 커밋의 "주민등록번호"입니다.
a1b2c3d4e5f6789012345678901234567890abcd
- 이 ID는 커밋 내용·작성자·시간·부모 커밋 등을 모두 합쳐 계산되므로 세상에 단 하나뿐입니다.
- 보통 앞 7자리(
a1b2c3d)만 써도 충분히 구별됩니다. - 특정 커밋으로 이동하거나 비교할 때 이 ID를 사용합니다.
# 특정 커밋의 상세 정보 보기 git show a1b2c3d
4.10 변경 내용 비교하기 — git diff
git diff는 "무엇이, 어떻게 바뀌었는지"를 줄 단위로 보여줍니다.
# 워킹 디렉터리 vs 스테이지 (아직 add 안 한 변경) git diff # 스테이지 vs 마지막 커밋 (add는 했지만 commit 안 한 변경) git diff --staged # (--cached 도 동일) # 두 커밋 사이의 차이 git diff a1b2c3d 9f8e7d6
diff 출력 읽는 법:
diff --git a/readme.txt b/readme.txt --- a/readme.txt ← 변경 전 (a) +++ b/readme.txt ← 변경 후 (b) @@ -1 +1,2 @@ Hello Git ← 변경 없는 줄 (공백으로 시작) +New line added ← 추가된 줄 (+) -Old line removed ← 삭제된 줄 (-)
+초록색 = 추가된 줄-빨간색 = 삭제된 줄
소스트리에서는 파일을 클릭하기만 하면 오른쪽 패널에 이 diff가 색깔로 예쁘게 표시됩니다. CLI보다 보기 편해서 변경 검토에 자주 활용됩니다.
4.11 작업 내용 되돌리기 (맛보기)
커밋하기 전, 워킹 디렉터리의 수정을 버리고 마지막 커밋 상태로 되돌리고 싶다면:
# 신버전 (권장) git restore readme.txt # 구버전 git checkout -- readme.txt
4.12 전체 흐름 복습 — 한 사이클
# 1. 파일 수정 echo "version control is fun" >> readme.txt # 2. 상태 확인 git status # 3. 무엇이 바뀌었는지 확인 git diff # 4. 장바구니에 담기 git add readme.txt # 5. 담긴 것 확인 git diff --staged # 6. 기록하기 git commit -m "Add a sentence to readme" # 7. 이력 확인 git log --oneline
이 7단계가 Git 일상 작업의 기본 리듬입니다. 수십 번 반복하면 손에 익습니다.
4.13 이 장에서 배운 것 (요약)
git add(담기) →git commit(기록)이 기본 흐름- 커밋에는 스냅샷·작성자·시간·메시지·고유 해시가 담긴다
- HEAD는 현재 위치(보통 최신 커밋)를 가리키는 포인터
- 커밋 메시지는 명령형·구체적으로 (
Fix login bug) --amend로 마지막 커밋 수정 (단, push한 건 금지)git log로 이력 조회,git diff로 변경 비교git commit -am은 추적 중인 파일의 add+commit 단축
✍️ 확인 문제
- 새로 만든 파일을
git commit -am으로 한 번에 커밋할 수 있나요? 왜인가요? git diff와git diff --staged의 차이는?- HEAD는 보통 무엇을 가리키나요?
다음 장에서는 내 커밋을 인터넷(GitHub)에 올리고 동료와 공유하는 원격 저장소를 배웁니다. → 05_원격저장소.md