Git 기본 워크플로우

add, commit, push, pull, status, diff 완전 정복

Git의 핵심 명령어(init, add, commit, push, pull, clone, status, diff, log)를 실제 작업 흐름에 맞춰 단계별로 설명한다. .gitignore 기본 설정과 커밋 메시지 작성법도 함께 다룬다.

Engineering
Git
DevOps
저자

Kwangmin Kim

공개

2023년 05월 02일

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는 현재 작업 디렉토리의 상태를 보여주는 가장 자주 사용하는 명령어다.

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 변경 없음 (최신 상태) 표시되지 않음
# 간결한 상태 확인
git status -s
# 출력 예시:
#  M src/app.py      (수정됨, 미스테이징)
# A  src/utils.py    (새 파일, 스테이징됨)
# ?? config.txt      (추적되지 않는 파일)

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.py
좋은 습관: 선택적 스테이징

git 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 main

Fast-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/main

fetch 는 원격 정보만 업데이트할 뿐 로컬 파일은 변경하지 않는다. [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 module

git 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 개인 프로젝트

# 1. 저장소 클론 (최초 1회)
git clone https://github.com/username/my_project.git
cd my_project

# 2. 작업 시작 전 최신 상태 동기화
git pull

# 3. 코드 수정 후 상태 확인
git status
git diff

# 4. 스테이징 & 커밋
git add src/app.py src/utils.py
git commit -m "feat: Add data export feature"

# 5. 원격에 업로드
git push

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 관련 포스트

Subscribe

Enjoy this blog? Get notified of new posts by email: