DaleSchool

스테이징과 커밋

입문25분

학습 목표

  • git add로 변경 사항을 스테이징할 수 있다
  • git commit으로 의미 있는 커밋을 만들 수 있다
  • git diff와 git diff --staged로 변경 내역을 확인할 수 있다
  • git log로 커밋 히스토리를 확인할 수 있다

동작하는 코드

예제 1: 파일 추가부터 커밋까지

저장소를 초기화하고 첫 커밋을 만들어봅니다:

git init
echo "# 나의 프로젝트" > README.md
git status

출력 (파일이 Untracked):

Untracked files:
	README.md

스테이징:

git add README.md
git status

출력 (스테이징됨):

Changes to be committed:
	new file:   README.md

커밋:

git commit -m "feat: README 파일 추가"

출력:

[main (root-commit) a1b2c3d] feat: README 파일 추가
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

출력의 의미:

  • main: 현재 브랜치
  • a1b2c3d: 커밋 해시 (고유 ID)
  • 1 file changed, 1 insertion(+): 변경 통계

예제 2: git diff로 변경 내역 확인

파일을 수정하고 diff를 확인합니다:

echo "이 프로젝트는 Git 연습용입니다." >> README.md
git diff

출력:

diff --git a/README.md b/README.md
index abc1234..def5678 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
 # 나의 프로젝트
+이 프로젝트는 Git 연습용입니다.
  • -로 시작하는 줄: 삭제된 내용
  • +로 시작하는 줄: 추가된 내용
  • 공백으로 시작하는 줄: 변경 없음

예제 3: 스테이징 후 diff 확인

git add README.md
git diff --staged

git diff는 스테이징 전 변경 내역, git diff --staged는 스테이징된 변경 내역입니다.

커밋:

git commit -m "docs: 프로젝트 설명 추가"

직접 수정하기

선택적 스테이징

여러 파일 중 관련 있는 것만 골라서 커밋할 수 있습니다:

# 파일 3개 추가
echo "// 로그인" > login.js
echo "// 회원가입" > signup.js
echo "body { margin: 0; }" > style.css

git status

출력:

Untracked files:
	login.js
	signup.js
	style.css
# 로그인 관련만 스테이징
git add login.js

git status

출력:

Changes to be committed:
	new file:   login.js

Untracked files:
	signup.js
	style.css
git commit -m "feat: 로그인 기능 추가"

# 나머지도 커밋
git add signup.js style.css
git commit -m "feat: 회원가입 및 스타일 추가"

git log로 히스토리 확인

git log

출력 (상세):

commit e4f5g6h7i8j9k0l1m2n3o4p5q6r7s8t9u0v1w2x (HEAD -> main)
Author: 홍길동 <hong@example.com>
Date:   Mon Jan 15 10:35:00 2024 +0900

    feat: 회원가입 및 스타일 추가

commit a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t
Author: 홍길동 <hong@example.com>
Date:   Mon Jan 15 10:30:00 2024 +0900

    feat: 로그인 기능 추가
# 한 줄로 간결하게
git log --oneline

출력:

e4f5g6h feat: 회원가입 및 스타일 추가
a1b2c3d feat: 로그인 기능 추가
abc1234 docs: 프로젝트 설명 추가
a1b2c3d feat: README 파일 추가
# 변경 파일 목록도 함께
git log --oneline --name-status

출력:

e4f5g6h feat: 회원가입 및 스타일 추가
A       signup.js
A       style.css
a1b2c3d feat: 로그인 기능 추가
A       login.js

git commit --amend: 마지막 커밋 수정

커밋 직후 오타를 발견하거나 파일을 빠뜨렸을 때:

# 오타가 있는 커밋
git commit -m "feat: 로그인 기능 추기"   # '추가' 오타

# 메시지만 수정
git commit --amend -m "feat: 로그인 기능 추가"

# 파일을 추가하면서 수정
git add forgotten-file.txt
git commit --amend --no-edit   # 메시지 그대로 유지

주의: --amend는 이미 push한 커밋에는 쓰지 마세요. 커밋 해시가 바뀌어 협업에 문제가 생깁니다.

"왜?" — 스테이징 영역이 따로 있는 이유

직접 커밋하지 않고 스테이징 단계를 거치는 이유:

선택적 커밋이 가능합니다. 10개 파일을 수정했어도, 관련 있는 것만 묶어서 커밋할 수 있습니다.

# 파일 A, B, C 수정
git add login.js auth.js  # 로그인 관련만 스테이징
git commit -m "fix: 로그인 버그 수정"

git add profile.js        # 프로필 관련은 별도 커밋
git commit -m "feat: 프로필 편집 기능 추가"

이렇게 하면 히스토리가 의미 단위로 나뉘어 나중에 추적하기 쉬워집니다.

좋은 커밋 메시지 작성법

타입: 변경 내용 요약 (50자 이내)

자주 쓰는 타입:

  • feat — 새 기능 (feature)
  • fix — 버그 수정
  • docs — 문서 수정
  • refactor — 리팩토링 (기능 변경 없음)
  • chore — 빌드, 패키지 등 기타 작업

좋은 커밋 메시지 예시:

feat: 소셜 로그인(Google) 기능 추가
fix: 비밀번호 재설정 이메일 미발송 버그 수정
docs: API 문서에 인증 섹션 추가

나쁜 커밋 메시지 예시:

수정
업데이트
aaaaa
WIP
작업중

diff 흐름 정리

[작업 디렉토리] ← git diff → [스테이징 영역]
[스테이징 영역] ← git diff --staged → [저장소(마지막 커밋)]

흔한 실수

실수 1: git add . 의 함정

# 현재 디렉토리의 모든 변경을 스테이징
git add .

# 이렇게 하면 원치 않는 파일(임시 파일, 설정 파일 등)도 포함될 수 있음
# 반드시 git status로 먼저 확인!
git status
git add .

실수 2: 커밋 메시지 없이 커밋

git commit   # 메시지 없이 → 편집기가 열림
# 편집기 설정에 따라 vim이 열려 당황할 수 있음

처음에는 항상 -m으로 메시지를 인라인으로 작성하세요:

git commit -m "커밋 메시지"

실수 3: 스테이징 전에 diff 확인 안 하기

# 나쁜 흐름
git add .
git commit -m "업데이트"

# 좋은 흐름
git diff          # 변경 내역 확인
git add 파일명    # 필요한 것만 스테이징
git diff --staged # 스테이징된 내용 최종 확인
git commit -m "명확한 메시지"

심화 학습

git log의 다양한 옵션
# 그래프로 보기
git log --oneline --graph

# 특정 파일의 변경 히스토리
git log --oneline README.md

# 커밋 내용(diff) 포함
git log -p

# 특정 커밋만
git log -3   # 최근 3개만

# 날짜 범위
git log --after="2024-01-01" --before="2024-02-01"

# 특정 작성자
git log --author="홍길동"

# 커밋 메시지에 특정 단어 포함
git log --grep="feat"
스테이징 취소 (git restore)

스테이징된 파일을 취소하거나 변경 사항을 되돌릴 때:

# 스테이징 취소 (작업 디렉토리는 유지)
git restore --staged 파일명

# 전체 스테이징 취소
git restore --staged .

# 작업 디렉토리의 변경 취소 (수정 전으로 복원)
git restore 파일명   # 주의: 이 변경은 되돌릴 수 없음!
커밋 취소: git reset

아직 push하지 않은 커밋이면:

# 마지막 커밋 취소 (변경 사항은 스테이징 상태로)
git reset --soft HEAD~1

# 마지막 커밋 취소 (변경 사항은 작업 디렉토리로)
git reset HEAD~1   # 또는 git reset --mixed HEAD~1

# 마지막 커밋 취소 (변경 사항도 완전히 제거)
git reset --hard HEAD~1   # 주의: 복구 어려움!

push 후에는 되돌리기가 더 복잡해집니다. 레슨 11에서 다룹니다.

  1. 새 저장소를 만들고 README.md를 추가한 후 첫 커밋을 만드세요.
  2. README.md를 수정하고 git diff로 변경 내역을 확인하세요.
  3. git add README.mdgit diff --staged로 스테이징된 변경 내역을 확인하세요.
  4. 파일 3개를 만들고, 2개만 선택해서 첫 번째 커밋, 나머지 1개는 두 번째 커밋으로 나눠서 만드세요.
  5. git log --oneline으로 커밋 히스토리를 확인하세요.

Q1. git diffgit diff --staged의 차이는?

  • A) git diff는 모든 변경, git diff --staged는 스테이징된 것만
  • B) git diff는 스테이징 전 변경, git diff --staged는 스테이징된 변경
  • C) git diff는 파일 간 비교, git diff --staged는 커밋 간 비교
  • D) 두 명령어는 동일한 결과를 보여줌