1 Git 기본 작업 흐름
Git을 사용한 일상적인 작업은 다음 흐름을 반복한다.
1. git pull (원격의 최신 변경사항 가져오기)
↓
2. 파일 수정/추가 (코드 작업)
↓
3. git status (변경된 파일 확인)
↓
4. git diff (변경 내용 확인)
↓
5. git add (커밋할 파일 선택)
↓
6. git commit (로컬에 이력 저장)
↓
7. git push (원격에 업로드)
2 파일 상태 확인: git status
git status는 현재 작업 디렉토리의 상태를 보여주는 가장 자주 사용하는 명령어다.
출력 예시:
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
modified: src/app.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
src/utils.py
no changes added to commit (use "git add" to track)
파일의 4가지 상태:
| 상태 | 설명 | git status 표시 |
|---|---|---|
| Untracked | Git이 추적하지 않는 새 파일 | Untracked files |
| Modified | 추적 중인 파일이 수정됨 | Changes not staged for commit |
| Staged | 커밋 대기 중 (add 완료) | Changes to be committed |
| Unmodified | 변경 없음 (최신 상태) | 표시되지 않음 |
3 변경 내용 확인: git diff
파일이 어떻게 변경되었는지 확인한다.
# 스테이징 전 변경사항 확인 (Working Directory vs Staging Area)
git diff
# 스테이징된 변경사항 확인 (Staging Area vs 마지막 커밋)
git diff --staged
# 또는
git diff --cached
# 특정 파일의 변경사항만 확인
git diff src/app.py
# 두 커밋 사이의 차이 확인
git diff abc1234 def5678
# 두 브랜치 사이의 차이 확인
git diff main feature/login출력 예시:
diff --git a/src/app.py b/src/app.py
index 1234567..abcdefg 100644
--- a/src/app.py
+++ b/src/app.py
@@ -10,6 +10,8 @@ def main():
print("Hello")
+ print("World") # 추가된 줄 (+)
- print("Old line") # 삭제된 줄 (-)+(초록색): 추가된 줄-(빨간색): 삭제된 줄
4 파일 스테이징: git add
커밋할 파일을 선택하는 단계다. 모든 변경사항을 한꺼번에 커밋하지 않고, 관련된 변경사항만 묶어서 커밋할 수 있다.
# 특정 파일 스테이징
git add src/app.py
# 특정 디렉토리의 모든 변경사항 스테이징
git add src/
# 모든 변경사항 스테이징 (주의해서 사용)
git add .
# 변경된 파일만 스테이징 (새 파일 제외)
git add -u
# 스테이징 취소 (파일 내용은 유지)
git restore --staged src/app.py
# 또는 (구 버전)
git reset HEAD src/app.pygit add . 대신 git add <파일명>으로 관련 파일만 골라서 스테이징하면 커밋 이력이 깔끔해진다. 하나의 커밋에는 하나의 논리적 변경사항만 포함하는 것이 이상적이다.
5 커밋: git commit
스테이징된 변경사항을 로컬 저장소에 기록한다.
# 기본 커밋
git commit -m "Add user login feature"
# 출력 예시:
# [main a1b2c3d] Add user login feature
# 1 file changed, 28 insertions(+), 2 deletions(-)
# 여러 줄 커밋 메시지
git commit -m "feat: Add user login feature
- JWT 토큰 기반 인증 구현
- 로그인 API 엔드포인트 추가
- 비밀번호 해싱 적용"
# 출력 예시:
# [main b2c3d4e] feat: Add user login feature
# 3 files changed, 87 insertions(+), 5 deletions(-)
# add + commit 동시에 (추적 중인 파일만, 새 파일은 제외)
git commit -am "Fix typo in login page"커밋 성공 시 [브랜치명 해시] 메시지 형태로 출력된다. 2 files changed, 28 insertions(+), 2 deletions(-) 는 변경된 파일 수와 추가/삭제된 줄 수를 요약해준다.
5.1 커밋 메시지 컨벤션 (Conventional Commits)
좋은 커밋 메시지는 나중에 이력을 추적할 때 큰 도움이 된다.
<타입>: <제목>
[본문 (선택)]
| 타입 | 용도 | 예시 |
|---|---|---|
feat |
새 기능 추가 | feat: Add search functionality |
fix |
버그 수정 | fix: Resolve login timeout issue |
docs |
문서 변경 | docs: Update API documentation |
refactor |
리팩토링 | refactor: Simplify auth logic |
test |
테스트 추가/수정 | test: Add unit tests for auth |
chore |
빌드/설정 변경 | chore: Update dependencies |
style |
코드 스타일 변경 | style: Fix indentation |
커밋 메시지 작성 규칙:
- 현재형 사용: “Add feature” (O), “Added feature” (X)
- 명확하고 간결: “Update” (X), “Fix auth bug in login endpoint” (O)
- 제목은 50자 이내, 본문은 72자에서 줄바꿈
6 원격 저장소와 동기화: push, pull, fetch
6.1 git push
로컬 커밋을 원격 저장소에 업로드한다.
# 첫 푸시 (업스트림 설정)
git push -u origin main
# 출력 예시:
# Enumerating objects: 8, done.
# Counting objects: 100% (8/8), done.
# Delta compression using up to 8 threads
# Compressing objects: 100% (5/5), done.
# Writing objects: 100% (7/7), 1.23 KiB | 1.23 MiB/s, done.
# Total 7 (delta 1), reused 0 (delta 0)
# To https://github.com/username/my_project.git
# * [new branch] main -> main
# Branch 'main' set up to track remote branch 'main' from 'origin'.
# 이후 푸시 (-u 없이)
git push
# 출력 예시:
# Enumerating objects: 5, done.
# Counting objects: 100% (5/5), done.
# Writing objects: 100% (3/3), 412 bytes | 412.00 KiB/s, done.
# To https://github.com/username/my_project.git
# a1b2c3d..b2c3d4e main -> main
# 특정 브랜치 푸시
git push origin feature/login첫 푸시 시 Branch 'main' set up to track remote branch 'main' from 'origin'. 가 출력되면 이후 git push만 입력해도 origin/main 에 올라간다. 이후 푸시에서 마지막 줄 main -> main 은 “로컬 main → 원격 main으로 업로드 성공”을 의미한다.
6.2 git pull
원격 저장소의 변경사항을 로컬로 가져와 병합한다.
# 현재 브랜치의 원격 변경사항 가져오기 + 병합
git pull
# 출력 예시 (새 변경사항 있을 때):
# remote: Enumerating objects: 5, done.
# remote: Counting objects: 100% (5/5), done.
# Unpacking objects: 100% (3/3), done.
# From https://github.com/username/my_project
# a1b2c3d..c3d4e5f main -> origin/main
# Updating a1b2c3d..c3d4e5f
# Fast-forward
# src/app.py | 15 +++++++++++++--
# 1 file changed, 13 insertions(+), 2 deletions(-)
# 출력 예시 (이미 최신 상태):
# Already up to date.
# 특정 원격 브랜치에서 가져오기
git pull origin mainFast-forward 는 충돌 없이 단순히 새 커밋을 추가한 것을 의미한다. 변경된 파일 목록과 추가/삭제 줄 수가 함께 표시된다.
git pull은 내부적으로 git fetch + git merge를 수행한다. 차이점은 8편: Merge vs Rebase에서 자세히 다룬다.
6.3 git fetch
원격 저장소의 변경사항을 가져오되, 로컬 브랜치에 병합하지 않는다. 변경사항을 확인만 하고 싶을 때 유용하다.
# 모든 원격 브랜치의 최신 정보 가져오기
git fetch
# 출력 예시:
# remote: Enumerating objects: 5, done.
# remote: Counting objects: 100% (5/5), done.
# From https://github.com/username/my_project
# a1b2c3d..c3d4e5f main -> origin/main
# * [new branch] feature/payment -> origin/feature/payment
# 특정 원격 저장소의 정보만 가져오기
git fetch origin
# 가져온 후 로컬과 원격의 차이 확인
git diff main origin/mainfetch 는 원격 정보만 업데이트할 뿐 로컬 파일은 변경하지 않는다. [new branch] 항목은 원격에 새 브랜치가 생겼다는 뜻이다. 확인 후 병합할지 결정하고 싶을 때 pull 대신 fetch를 먼저 사용한다.
7 커밋 이력 확인: git log
# 전체 커밋 이력
git log
# 출력 예시:
# commit c3d4e5f6789012345678901234567890abcdef12 (HEAD -> main, origin/main)
# Author: Kwangmin Kim <kwangmin@example.com>
# Date: Mon Mar 11 09:15:32 2024 +0900
#
# feat: Add user login feature
#
# commit b2c3d4e5678901234567890123456789abcdef11
# Author: Kwangmin Kim <kwangmin@example.com>
# Date: Sun Mar 10 17:30:18 2024 +0900
#
# fix: Resolve database connection timeout
# ...
# (q를 눌러 종료)q 를 누르면 로그 화면에서 빠져나온다.
# 한 줄로 간결하게
git log --oneline
# 출력 예시:
# c3d4e5f (HEAD -> main, origin/main) feat: Add user login feature
# b2c3d4e fix: Resolve database connection timeout
# a1b2c3d docs: Update API documentation
# 9f8e7d6 refactor: Simplify auth logic
# 8e7d6c5 feat: Initial commit
# 최근 5개만
git log -5
# 그래프와 함께 (브랜치 시각화)
git log --oneline --graph --all --decorate
# 출력 예시:
# * c3d4e5f (HEAD -> main, origin/main) feat: Add user login feature
# * b2c3d4e fix: Resolve database connection timeout
# | * a9b8c7d (origin/feature/payment) feat: Add payment gateway
# |/
# * 9f8e7d6 refactor: Simplify auth logic
# 특정 파일의 변경 이력
git log -- src/app.py
# 출력 예시:
# c3d4e5f feat: Add user login feature
# 8e7d6c5 feat: Initial commit
# 특정 작성자의 커밋만
git log --author="홍길동"
# 날짜 범위로 필터링
git log --since="2024-01-01" --until="2024-03-31"
# 커밋 메시지에 특정 키워드가 포함된 것만
git log --grep="fix"
# 출력 예시:
# b2c3d4e fix: Resolve database connection timeout
# 7d6c5b4 fix: Handle null pointer in user modulegit log --oneline --graph --all --decorate 는 브랜치 구조를 시각화하는 가장 유용한 명령어다. * 는 커밋, | 와 / 는 브랜치 분기와 병합을 나타낸다. 더 자세한 그래프 활용은 6편: Git 그래프 시각화에서 다룬다.
8 .gitignore 기본 설정
버전 관리가 불필요한 파일을 Git이 무시하도록 설정한다. 프로젝트 루트에 .gitignore 파일을 생성한다.
# .gitignore 파일 예시
# Python
__pycache__/
*.py[cod]
*.egg-info/
.venv/
venv/
# IDE
.vscode/
.idea/
*.swp
# 환경변수 (중요: 절대 커밋하면 안 됨!)
.env
.env.local
# OS
.DS_Store
Thumbs.db
# 빌드 결과물
dist/
build/
node_modules/.env, 비밀번호, API 키 등 민감한 정보가 담긴 파일은 반드시 .gitignore에 추가해야 한다. 한번 커밋되면 이력에 남아서 완전히 제거하기 어렵다. 더 자세한 내용은 12편: .gitignore 심화에서 다룬다.
9 실전 워크플로우 예시
9.1 개인 프로젝트
9.2 팀 프로젝트
# 1. 최신 코드 가져오기
git pull origin develop
# 2. 기능 브랜치 생성 & 이동
git checkout -b feature/user-login
# 3. 코드 수정 & 커밋 (여러 번 반복)
git add .
git commit -m "feat: Add login form UI"
git add .
git commit -m "feat: Implement JWT authentication"
# 4. 원격에 푸시
git push -u origin feature/user-login
# 5. GitHub에서 Pull Request 생성 → 코드 리뷰 → 병합10 요약
| 명령어 | 역할 | 사용 시점 |
|---|---|---|
git status |
파일 상태 확인 | 수시로 |
git diff |
변경 내용 확인 | 커밋 전 |
git add |
커밋할 파일 선택 | 커밋 전 |
git commit |
변경 이력 기록 | 논리적 단위 완료 시 |
git push |
원격에 업로드 | 커밋 후 |
git pull |
원격 변경사항 가져오기 | 작업 시작 전 |
git fetch |
원격 정보만 가져오기 | 변경사항 확인 시 |
git log |
커밋 이력 조회 | 이력 추적 시 |
git clone |
저장소 복제 | 최초 1회 |
10.1 관련 포스트
- GitHub 로컬-원격 저장소 연결 문제 해결 — git init, remote add, 브랜치 불일치(main/master) 트러블슈팅