72.1 커밋이 정확히 뭔가요?
앞에서 커밋은 "그 순간의 스냅샷"이라고 했죠. 조금만 더 정확히 볼게요. 커밋 하나에는 세 가지가 담겨요. 바뀐 내용, 누가 언제 했는지, 그리고 왜 했는지를 적은 메시지예요.
이미 찍어둔 커밋의 속을 자세히 보고 싶으면 git show를 써요.
$ git show --stat HEAD
commit 67c59b45f235367a147a99b957b60500d50ea12c
Author: kim <[email protected]>
Date: Sat Jul 11 05:54:06 2026 +0900
feat: add bye function
app.py | 3 +++
1 file changed, 3 insertions(+)
여기서 HEAD(헤드)는 "지금 내가 서 있는 가장 최근 커밋"을 가리키는 이름이에요. app.py에 3줄이 추가됐다는 것까지 한눈에 보이죠.
72.2 스테이징이라는 중간 단계는 왜 있죠?
git add랑 git commit, 왜 굳이 두 번 나눠서 해야 하나 싶죠? 여기서 스테이징(staging, 준비 영역에 올리기)이라는 개념이 나와요.
Git에는 공간이 세 개 있어요. 지금 파일을 고치는 작업 폴더, 커밋에 넣을 것만 골라 담는 스테이지, 그리고 실제 기록이 쌓이는 저장소예요. git add는 "이 변경을 다음 커밋에 넣을게"라며 스테이지에 올리는 거고, git commit은 스테이지에 담긴 것만 골라 스냅샷으로 찍는 거예요.
그래서 여러 파일을 고쳤어도 그중 일부만 골라 커밋할 수 있어요. 예를 들어 README.md와 app.py 둘 다 고쳤는데, README만 먼저 커밋하고 싶다고 해볼게요.
$ git add README.md
$ git status
On branch main
Changes to be committed:
new file: README.md
Changes not staged for commit:
modified: app.py
보이시죠? README.md는 Changes to be committed(커밋할 준비 완료)에, app.py는 Changes not staged(아직 안 올림)에 나뉘어 있어요. 딱 원하는 것만 골라 담은 거예요.
72.3 방금 뭘 바꿨는지 어떻게 확인해요?
커밋하기 전에 "내가 정확히 뭘 바꿨더라" 확인하고 싶을 때가 많죠. 그럴 땐 git diff예요.
$ git diff
diff --git a/app.py b/app.py
@@ -1,2 +1,5 @@
def hello():
print("hello")
+
+def bye():
+ print("bye")
앞에 +가 붙은 줄이 새로 추가된 부분이에요. 지운 줄이 있었다면 앞에 -가 붙고요. 이렇게 한 줄 단위로 뭐가 달라졌는지 딱 보여줘요.
단, git diff는 아직 스테이지에 안 올린 변경만 보여줘요. 이미 git add한 것까지 보려면 --staged를 붙여요. 방금 스테이지에 올린 README.md를 확인해볼게요.
$ git diff --staged
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# My App
new file mode는 새로 생긴 파일이라는 표시예요. 커밋 버튼을 누르기 전에 이렇게 diff로 한 번 훑어보는 습관을 들이면, 엉뚱한 걸 커밋하는 실수가 확 줄어요.
72.4 실수로 올린 파일, 어떻게 빼요?
git add를 했는데 "아 이건 이번 커밋에 넣으면 안 되는데" 싶을 때가 있어요. 그럼 스테이지에서 도로 내리면 돼요.
$ git restore --staged README.md
파일 내용은 그대로 두고 스테이지에서만 쏙 빠져요. 반대로, 고치던 내용 자체를 싹 되돌리고 싶을 때도 있죠. 오타를 잔뜩 냈다거나요.
상황: app.py를 잘못 고쳤어요. 커밋 전 상태로 되돌리고 싶어요.
$ git restore app.py
이러면 마지막 커밋 시점의 app.py로 돌아가요. 주의할 점은, 이렇게 되돌린 내용은 영영 사라진다는 거예요. 아직 커밋 안 한 변경은 Git도 못 살려주니, restore는 늘 신중하게 써야 해요.
72.5 커밋에 넣고 싶지 않은 파일은요?
비밀번호가 든 secret.txt나, 프로그램이 자동으로 만들어내는 로그 파일 같은 건 커밋에 올리면 안 되죠. 이런 건 .gitignore(깃 무시 목록) 파일에 적어두면 Git이 아예 못 본 척해줘요.
.gitignore 파일 내용:
secret.txt
*.log
여기서 *.log는 "이름이 .log로 끝나는 모든 파일"이라는 뜻이에요. 이렇게 해두면 status에도 안 뜨고, 실수로 add되지도 않아요.
$ git status -s
M app.py
?? .gitignore
?? README.md
목록에서 secret.txt랑 app.log가 아예 사라졌죠? -s는 상태를 짧게(short) 보여주는 옵션이에요. 앞의 물음표 두 개(??)는 아직 추적 안 하는 새 파일이라는 표시고요. 이제 남은 것들을 커밋해볼게요.
$ git add .
$ git commit -m "chore: add readme and gitignore"
[main 9f007de] chore: add readme and gitignore
3 files changed, 4 insertions(+), 1 deletion(-)
여기서 git add .은 바뀐 것 전부를 한 번에 스테이지에 올리는 명령이에요. 점 하나가 "현재 폴더 아래 전부"라는 뜻이죠. secret.txt는 .gitignore 덕분에 이 "전부"에도 안 끼어서, 커밋에 안 들어갔어요.
72.6 방금 커밋 메시지를 잘못 썼어요
방금 찍은 커밋의 메시지에 오타가 있거나 뭔가 빠뜨렸을 때, 새 커밋을 또 만들 필요 없어요. git commit --amend로 마지막 커밋을 바로 고쳐 쓰면 돼요.
$ git commit --amend -m "chore: add readme, gitignore, update hello"
메시지가 통째로 바뀐 새 커밋으로 교체돼요. 단, 이미 팀에 공유한 커밋을 amend하면 남들 기록과 어긋나 꼬일 수 있어요. 그러니 아직 내 컴퓨터에만 있는 커밋일 때만 쓰는 게 안전해요.
72.7 오늘 배운 걸 정리해볼게요
커밋은 스냅샷 + 작성자 + 메시지, 이 세 가지가 뭉친 저장 단위예요. git add로 스테이지에 골라 담고 git commit으로 찍어요. 바뀐 내용은 git diff로 보고, 잘못 올린 건 git restore --staged로 내리고, 아예 안 올릴 파일은 .gitignore에 적고, 방금 커밋 수정은 --amend예요.
좋은 커밋의 원칙은 딱 하나예요. "한 커밋에 한 가지 일"만 담고, 메시지에 왜 그렇게 했는지를 남기는 거죠. 로그인 기능과 오타 수정을 한 커밋에 뭉치면, 나중에 오타 부분만 되돌리고 싶을 때 골라내기가 어려워요. 작게 나눠 자주 찍는 습관이 결국 나를 편하게 해줘요. 그래야 나중에 log를 봤을 때 내가 나를 이해할 수 있고요.