학습 목표
이 장을 마치면 다음을 할 수 있습니다:
- ✅ Git의 3가지 영역(Working Directory, Staging Area, Repository)을 이해할 수 있습니다
- ✅ 파일을 스테이징하고 커밋을 만들 수 있습니다
- ✅ 효과적인 커밋 메시지를 작성할 수 있습니다
- ✅ 커밋 히스토리를 조회하고 관리할 수 있습니다
지난 편 복습
기초편 #6에서는 .gitignore와 라이선스를 배웠습니다:
- .gitignore 파일의 역할과 작성법
- 언어/프레임워크별 무시 패턴
- 오픈소스 라이선스 종류 (MIT, GPL, Apache 등)
- 프로젝트에 적절한 라이선스 선택
1. 첫 커밋 만들기
1.1 Git의 3가지 영역
Git은 파일을 3가지 영역에서 관리합니다:
graph LR
A[Working Directory<br/>작업 디렉토리] -->|git add| B[Staging Area<br/>스테이징 영역]
B -->|git commit| C[Repository<br/>저장소]
C -->|git checkout| A
style A fill:#f9f
style B fill:#9cf
style C fill:#9f9
1. Working Directory (작업 디렉토리)
- 실제 파일이 있는 곳
- 파일을 편집하고 작업하는 공간
.git 폴더를 제외한 모든 파일/폴더
1
2
3
4
5
| my-project/
├── .git/ # Git 저장소 (보이지 않음)
├── index.html # Working Directory
├── style.css # Working Directory
└── script.js # Working Directory
|
2. Staging Area (스테이징 영역)
- 커밋 대기 영역 (Index라고도 함)
- 다음 커밋에 포함될 파일들
git add 명령으로 파일을 이동
1
2
| # Staging Area는 눈에 보이지 않지만
# .git/index 파일에 저장됨
|
왜 Staging Area가 필요한가?
1
2
3
4
5
6
7
8
9
10
11
12
13
| 시나리오: 3개 파일을 수정했지만 2개만 커밋하고 싶을 때
1. 모든 파일 수정 (Working Directory)
- feature.js (기능 A 완성)
- feature.js (기능 B 작업 중)
- style.css (기능 A 스타일)
2. 완성된 것만 선택 (Staging Area)
git add feature.js style.css
(기능 B는 제외)
3. 커밋 생성 (Repository)
git commit -m "Add feature A"
|
3. Repository (저장소)
- 커밋들이 저장되는 곳
.git/ 폴더 안에 있음 - 프로젝트의 전체 히스토리
1
2
3
4
5
| .git/
├── objects/ # 모든 커밋, 파일 저장
├── refs/ # 브랜치, 태그 정보
├── HEAD # 현재 브랜치 참조
└── config # 저장소 설정
|
1.2 파일 상태 이해하기
Git의 파일은 4가지 상태를 가집니다:
graph LR
A[Untracked<br/>추적 안 됨] -->|git add| B[Staged<br/>스테이징됨]
B -->|git commit| C[Unmodified<br/>수정 안 됨]
C -->|파일 수정| D[Modified<br/>수정됨]
D -->|git add| B
C -->|git rm| A
style A fill:#f99
style B fill:#9cf
style C fill:#9f9
style D fill:#ff9
파일 상태 설명
1. Untracked (추적 안 됨)
1
2
3
4
5
6
7
| # 새 파일 생성
touch newfile.txt
# 상태 확인
git status
# Untracked files:
# newfile.txt
|
2. Staged (스테이징됨)
- 다음 커밋에 포함될 파일
git add로 추가됨
1
2
3
4
5
| git add newfile.txt
git status
# Changes to be committed:
# new file: newfile.txt
|
3. Unmodified (수정 안 됨)
1
2
3
4
5
| git commit -m "Add newfile.txt"
# 이제 Unmodified 상태
git status
# nothing to commit, working tree clean
|
4. Modified (수정됨)
1
2
3
4
5
6
| # 파일 수정
echo "content" >> newfile.txt
git status
# Changes not staged for commit:
# modified: newfile.txt
|
1.3 첫 커밋 만들기
Step 1: 저장소 초기화
새 프로젝트 시작
1
2
3
4
5
6
7
8
9
| # 프로젝트 폴더 생성
mkdir my-first-repo
cd my-first-repo
# Git 저장소 초기화
git init
# 출력:
# Initialized empty Git repository in /path/to/my-first-repo/.git/
|
기존 GitHub 저장소 클론
1
2
| git clone https://github.com/username/my-repo.git
cd my-repo
|
Step 2: 파일 생성
1
2
3
4
5
| # README 파일 생성
echo "# My First Project" > README.md
# 소스 파일 생성
echo "console.log('Hello, Git!');" > app.js
|
Step 3: 상태 확인
1
2
3
4
5
6
7
8
9
10
11
| git status
# 출력:
# On branch main
#
# No commits yet
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# README.md
# app.js
|
출력 해석:
On branch main: main 브랜치에 있음 No commits yet: 아직 커밋 없음 Untracked files: 새 파일들 (아직 추적 안 됨)
Step 4: 스테이징 (git add)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 특정 파일만 스테이징
git add README.md
# 여러 파일 스테이징
git add README.md app.js
# 모든 파일 스테이징
git add .
# 특정 확장자만
git add *.js
# 폴더 전체
git add src/
|
스테이징 확인:
1
2
3
4
5
6
7
| git status
# 출력:
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
# new file: README.md
# new file: app.js
|
Step 5: 커밋 만들기
1
2
3
4
5
6
7
8
| # 커밋 메시지와 함께 커밋
git commit -m "Initial commit: Add README and app.js"
# 출력:
# [main (root-commit) a1b2c3d] Initial commit: Add README and app.js
# 2 files changed, 2 insertions(+)
# create mode 100644 README.md
# create mode 100644 app.js
|
출력 해석:
[main (root-commit) a1b2c3d]: main 브랜치의 첫 번째 커밋, 커밋 해시는 a1b2c3d 2 files changed: 2개 파일 변경 2 insertions(+): 2줄 추가 create mode 100644: 일반 파일로 생성
Step 6: 커밋 확인
1
2
3
4
5
6
7
8
9
10
11
| git status
# On branch main
# nothing to commit, working tree clean
# → 모든 변경사항이 커밋됨
git log
# commit a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
# Author: Your Name <your.email@example.com>
# Date: Mon Jan 15 10:30:00 2024 +0900
#
# Initial commit: Add README and app.js
|
1.4 커밋 메시지 작성법
좋은 커밋 메시지의 특징
1
2
3
4
5
6
| 짧은 요약 (50자 이내)
상세 설명 (선택사항, 72자로 줄바꿈)
- 왜 이 변경이 필요한가?
- 어떻게 문제를 해결하는가?
- 어떤 부작용이 있을 수 있는가?
|
커밋 메시지 형식
기본 형식:
1
2
3
4
5
6
7
8
9
| # 짧은 메시지만
git commit -m "Fix typo in README"
# 제목 + 본문
git commit -m "Add user authentication" -m "Implement JWT-based authentication with refresh tokens. Includes login, logout, and token refresh endpoints."
# 에디터로 작성
git commit
# → 기본 에디터(vim, nano 등)가 열림
|
Conventional Commits (권장):
1
2
3
4
5
| <type>(<scope>): <subject>
<body>
<footer>
|
Types:
feat: 새로운 기능 fix: 버그 수정 docs: 문서 변경 style: 코드 포맷팅 (기능 변경 없음) refactor: 코드 리팩토링 test: 테스트 추가/수정 chore: 빌드, 설정 변경
예시:
1
2
3
4
5
6
7
8
9
| git commit -m "feat: Add user login functionality"
git commit -m "fix: Resolve memory leak in data processing"
git commit -m "docs: Update installation guide"
git commit -m "refactor(auth): Simplify token validation logic"
git commit -m "test: Add unit tests for user service"
|
DO ✅
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 1. 명확하고 구체적으로
✅ git commit -m "Fix login button alignment on mobile"
❌ git commit -m "Fix bug"
# 2. 동사 원형으로 시작
✅ git commit -m "Add error handling for API calls"
❌ git commit -m "Added error handling"
# 3. 50자 이내 (제목)
✅ git commit -m "Refactor database connection pooling"
❌ git commit -m "Refactor the database connection pooling system to improve performance and reduce memory usage"
# 4. 관련 변경사항은 하나의 커밋으로
✅ git commit -m "feat: Add user registration with email validation"
❌ git commit -m "Add user registration and fix CSS and update README"
|
DON’T ❌
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 1. 너무 모호한 메시지
❌ git commit -m "Update"
❌ git commit -m "Fix"
❌ git commit -m "Changes"
# 2. 여러 기능을 한 커밋에
❌ git commit -m "Add login, fix CSS, update docs, refactor API"
# 3. WIP (Work In Progress) 커밋 남기기
❌ git commit -m "WIP"
❌ git commit -m "asdf"
❌ git commit -m "test"
# 4. 과거형 사용
❌ git commit -m "Added new feature"
✅ git commit -m "Add new feature"
|
이모지 사용 (선택)
1
2
3
4
5
6
7
| git commit -m "✨ feat: Add dark mode support"
git commit -m "🐛 fix: Resolve crash on startup"
git commit -m "📝 docs: Update API documentation"
git commit -m "♻️ refactor: Simplify auth logic"
git commit -m "🎨 style: Format code with Prettier"
git commit -m "🚀 perf: Optimize image loading"
git commit -m "✅ test: Add integration tests"
|
자주 사용하는 이모지:
- ✨
:sparkles: 새 기능 - 🐛
:bug: 버그 수정 - 📝
:memo: 문서 - ♻️
:recycle: 리팩토링 - 🎨
:art: 코드 포맷 - 🚀
:rocket: 성능 개선 - ✅
:white_check_mark: 테스트 - 🔒
:lock: 보안 - 🔥
:fire: 코드 제거
1.5 커밋 수정하기
마지막 커밋 메시지 수정
1
2
| # 커밋 메시지만 수정 (파일 변경 없음)
git commit --amend -m "New commit message"
|
마지막 커밋에 파일 추가
1
2
3
4
5
| # 파일 수정 후
git add forgotten-file.txt
# 이전 커밋에 추가 (새 커밋 생성하지 않음)
git commit --amend --no-edit
|
⚠️ 주의: --amend는 커밋 히스토리를 변경하므로, 이미 push한 커밋에는 사용하지 마세요!
스테이징 취소
1
2
3
4
5
6
7
8
| # 특정 파일 스테이징 취소
git reset HEAD file.txt
# 또는 (Git 2.23+)
git restore --staged file.txt
# 모든 파일 스테이징 취소
git reset HEAD .
|
파일 변경사항 취소
1
2
3
4
5
6
7
8
| # 특정 파일의 변경사항 취소 (되돌릴 수 없음!)
git checkout -- file.txt
# 또는 (Git 2.23+)
git restore file.txt
# 모든 변경사항 취소
git checkout -- .
|
⚠️ 경고: 변경사항 취소는 되돌릴 수 없습니다! 신중하게 사용하세요.
2. 커밋 히스토리 관리
2.1 로그 조회하기
기본 로그
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| git log
# 출력:
# commit a1b2c3d (HEAD -> main)
# Author: Your Name <email@example.com>
# Date: Mon Jan 15 10:30:00 2024 +0900
#
# feat: Add user authentication
#
# commit e4f5g6h
# Author: Your Name <email@example.com>
# Date: Sun Jan 14 15:20:00 2024 +0900
#
# Initial commit
|
간결한 로그
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 한 줄로 표시
git log --oneline
# 출력:
# a1b2c3d (HEAD -> main) feat: Add user authentication
# e4f5g6h Initial commit
# 최근 3개만
git log --oneline -3
# 그래프 형태로
git log --oneline --graph --all
# 출력:
# * a1b2c3d (HEAD -> main) feat: Add user authentication
# * e4f5g6h Initial commit
|
상세 로그
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # 변경 파일 통계
git log --stat
# 실제 변경 내용 (diff)
git log -p
# 특정 파일의 히스토리
git log README.md
# 특정 작성자의 커밋
git log --author="Your Name"
# 날짜 범위
git log --since="2024-01-01" --until="2024-01-31"
# 키워드 검색
git log --grep="authentication"
|
2.2 특정 커밋 보기
1
2
3
4
5
6
7
8
| # 특정 커밋의 상세 정보
git show a1b2c3d
# 특정 커밋의 변경 파일 목록
git show --name-only a1b2c3d
# 특정 커밋의 통계
git show --stat a1b2c3d
|
2.3 커밋 비교하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 두 커밋 비교
git diff e4f5g6h a1b2c3d
# Working Directory vs Staging Area
git diff
# Staging Area vs Repository (마지막 커밋)
git diff --staged
# 특정 파일만 비교
git diff file.txt
# 브랜치 간 비교
git diff main feature-branch
|
2.4 실전 워크플로우
일반적인 작업 흐름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| # 1. 작업 시작 전 상태 확인
git status
# 2. 파일 수정
# (코드 편집...)
# 3. 변경사항 확인
git diff
# 4. 스테이징
git add .
# 5. 스테이징된 내용 확인
git diff --staged
# 6. 커밋
git commit -m "feat: Add new feature"
# 7. 로그 확인
git log --oneline -5
# 8. GitHub에 푸시 (다음 편에서 배울 내용)
git push origin main
|
실수 복구 시나리오
시나리오 1: 잘못된 파일을 스테이징
1
2
3
4
5
6
| git add wrong-file.txt
git status
# → wrong-file.txt가 스테이징됨
# 해결:
git reset HEAD wrong-file.txt
|
시나리오 2: 커밋 메시지 오타
1
2
3
4
| git commit -m "Addnew feature" # 오타!
# 해결:
git commit --amend -m "Add new feature"
|
시나리오 3: 파일을 커밋에서 빠뜨림
1
2
3
4
5
6
| git commit -m "Add authentication"
# → 아, auth-helper.js를 깜빡했다!
# 해결:
git add auth-helper.js
git commit --amend --no-edit
|
자주 묻는 질문 (FAQ)
Q1. Staging Area를 건너뛰고 바로 커밋할 수 있나요?
A: 네! -a 옵션을 사용하면 됩니다:
1
2
3
4
| # Modified 파일을 스테이징 없이 바로 커밋
git commit -a -m "Quick fix"
# 단, Untracked 파일은 제외됨!
|
Q2. 커밋 해시(a1b2c3d)는 무엇인가요?
A: 커밋의 고유 식별자입니다. SHA-1 해시(40자)로 생성되며, 보통 앞 7자만 사용합니다.
1
2
3
4
5
| # 전체 해시
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
# 짧은 해시 (보통 사용)
a1b2c3d
|
Q3. 커밋을 완전히 삭제할 수 있나요?
A: 네, 하지만 주의가 필요합니다:
1
2
3
4
5
6
7
| # 마지막 커밋 삭제 (변경사항은 유지)
git reset --soft HEAD~1
# 마지막 커밋 삭제 (변경사항도 삭제, 위험!)
git reset --hard HEAD~1
# ⚠️ push한 커밋은 절대 삭제하지 마세요!
|
Q4. 빈 커밋을 만들 수 있나요?
A: 네! 파일 변경 없이 메시지만 남기고 싶을 때:
1
| git commit --allow-empty -m "Trigger CI/CD pipeline"
|
실습 과제
과제 1: 첫 커밋 만들기
- 새 프로젝트 폴더 생성 및
git init - README.md 파일 생성
git status로 상태 확인 git add로 스테이징 git commit으로 커밋 git log로 확인
과제 2: 여러 커밋 만들기
- index.html 파일 생성 및 커밋
- style.css 파일 생성 및 커밋
- script.js 파일 생성 및 커밋
git log --oneline --graph로 히스토리 확인
과제 3: 커밋 수정 연습
- 파일 수정 후 커밋
- 커밋 메시지에 오타 발견
git commit --amend로 수정 - 추가 파일을 같은 커밋에 포함
과제 4: Conventional Commits 연습
다음 시나리오에 맞는 커밋 메시지 작성:
- 새로운 로그인 기능 추가
- 로그인 버튼 CSS 버그 수정
- README 파일 업데이트
- 코드 리팩토링 (기능 변경 없음)
- 단위 테스트 추가
마무리
축하합니다! Git의 핵심인 커밋을 이해하고 만들 수 있게 되었습니다.
핵심 요약:
- ✅ 3가지 영역: Working Directory → Staging Area → Repository
- ✅ git add: 스테이징 (커밋 준비)
- ✅ git commit: 스냅샷 생성
- ✅ git log: 히스토리 조회
- ✅ 좋은 커밋 메시지: 명확하고 구체적으로
다음 편에서는 git add와 commit을 더 깊이 알아보고, 다양한 옵션과 패턴을 배워보겠습니다!
📚 GitHub 마스터하기 시리즈
🌱 기초편 (입문자)
- GitHub 소개와 계정 만들기
- 프로필 꾸미기와 포트폴리오
- 보안 설정과 인증
- Repository 이해하기
- README 작성법
- .gitignore와 라이선스
- 첫 커밋과 관리 👉 현재 글
- git add와 commit
- git push와 pull
- 실전 워크플로우
- Branch 기본
- Merge와 Rebase
- 브랜치 전략
- Fork와 Clone
- Pull Request
💼 실전편 (중급자)
- Issues 활용법
- Projects와 칸반보드
- 코드 리뷰 실전
- Discussions 활용
- 팀 협업 전략
- GitHub Pages 블로그
🚀 고급편 (전문가)
- GitHub Actions 입문
- Actions 고급 활용
- Webhooks와 API
- GitHub Apps 개발
- 보안 기능 활용
- Packages 레지스트리
- Codespaces 클라우드 개발
- GitHub CLI 마스터
- Insights와 Analytics
🏆 심화편 (전문가+)
- Submodules와 Subtree
- Git Internals 이해
- 브랜칭과 릴리스 전략
- GraphQL API 활용
- GitHub Copilot 마스터