포스트

[이제와서 시작하는 GitHub 마스터하기 - 기초편 #7] 첫 커밋과 관리: Git의 핵심 이해하기

[이제와서 시작하는 GitHub 마스터하기 - 기초편 #7] 첫 커밋과 관리: Git의 핵심 이해하기

학습 목표

이 장을 마치면 다음을 할 수 있습니다:

  • ✅ 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 (추적 안 됨)

  • Git이 아직 모르는 파일
  • 새로 만든 파일
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: 첫 커밋 만들기

  1. 새 프로젝트 폴더 생성 및 git init
  2. README.md 파일 생성
  3. git status로 상태 확인
  4. git add로 스테이징
  5. git commit으로 커밋
  6. git log로 확인

과제 2: 여러 커밋 만들기

  1. index.html 파일 생성 및 커밋
  2. style.css 파일 생성 및 커밋
  3. script.js 파일 생성 및 커밋
  4. git log --oneline --graph로 히스토리 확인

과제 3: 커밋 수정 연습

  1. 파일 수정 후 커밋
  2. 커밋 메시지에 오타 발견
  3. git commit --amend로 수정
  4. 추가 파일을 같은 커밋에 포함

과제 4: Conventional Commits 연습

다음 시나리오에 맞는 커밋 메시지 작성:

  1. 새로운 로그인 기능 추가
  2. 로그인 버튼 CSS 버그 수정
  3. README 파일 업데이트
  4. 코드 리팩토링 (기능 변경 없음)
  5. 단위 테스트 추가

마무리

축하합니다! Git의 핵심인 커밋을 이해하고 만들 수 있게 되었습니다.

핵심 요약:

  • 3가지 영역: Working Directory → Staging Area → Repository
  • git add: 스테이징 (커밋 준비)
  • git commit: 스냅샷 생성
  • git log: 히스토리 조회
  • 좋은 커밋 메시지: 명확하고 구체적으로

다음 편에서는 git add와 commit을 더 깊이 알아보고, 다양한 옵션과 패턴을 배워보겠습니다!

📚 GitHub 마스터하기 시리즈

🌱 기초편 (입문자)

  1. GitHub 소개와 계정 만들기
  2. 프로필 꾸미기와 포트폴리오
  3. 보안 설정과 인증
  4. Repository 이해하기
  5. README 작성법
  6. .gitignore와 라이선스
  7. 첫 커밋과 관리 👉 현재 글
  8. git add와 commit
  9. git push와 pull
  10. 실전 워크플로우
  11. Branch 기본
  12. Merge와 Rebase
  13. 브랜치 전략
  14. Fork와 Clone
  15. Pull Request

💼 실전편 (중급자)

  1. Issues 활용법
  2. Projects와 칸반보드
  3. 코드 리뷰 실전
  4. Discussions 활용
  5. 팀 협업 전략
  6. GitHub Pages 블로그

🚀 고급편 (전문가)

  1. GitHub Actions 입문
  2. Actions 고급 활용
  3. Webhooks와 API
  4. GitHub Apps 개발
  5. 보안 기능 활용
  6. Packages 레지스트리
  7. Codespaces 클라우드 개발
  8. GitHub CLI 마스터
  9. Insights와 Analytics

🏆 심화편 (전문가+)

  1. Submodules와 Subtree
  2. Git Internals 이해
  3. 브랜칭과 릴리스 전략
  4. GraphQL API 활용
  5. GitHub Copilot 마스터
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.