Skip to content
CP
Writing
16 분 읽기#code

Git 기본 사용법 — 평생 쓰는 명령 15개와 멘탈 모델

AI가 코드를 다 짜주는 시대에도 git은 직접 칠 줄 알아야 합니다. 처음 시작하는 사람이 알아야 할 명령 15개와 — 왜 그렇게 동작하는지에 대한 멘탈 모델.

AI가 코드를 다 짜주는 시대에도 — 결국 버전 관리는 직접 해야 합니다. Claude가 좋은 코드를 만들어줘도, 그걸 어디에 어떻게 저장하고, 망쳤을 때 어떻게 되돌리고, 다른 사람과 어떻게 합치는지는 — 당신의 몫입니다.

좋은 소식은 — git의 핵심은 명령 15개로 끝납니다. 나쁜 소식은 — 그 15개를 "그냥 외우는" 식으로 배우면 평생 무서워합니다. 한 번 충돌나면 멈춰버립니다.

이 글은 git을 외우는 게 아니라 이해해서 쓰는 법입니다. 멘탈 모델 하나 잡고, 그 위에 명령 15개를 얹습니다.

멘탈 모델 — 4개의 영역

git은 결국 4개의 영역에 파일이 어떻게 이동하는지의 게임입니다.

[작업 디렉토리] → [스테이지] → [로컬 저장소] → [원격 저장소]
  Working Dir      Staging       Repository       Remote
  (수정 중)       (찍어둠)      (내 컴퓨터)      (GitHub 등)
  • 작업 디렉토리(Working Directory) — 지금 에디터로 열어놓고 수정하는 파일들.
  • 스테이지(Staging Area / Index) — "이번에 커밋할 변경"이라고 따로 골라둔 것들. git의 특별한 점이 여기 있습니다.
  • 로컬 저장소(Local Repository) — 내 컴퓨터에 저장된 커밋 히스토리. .git/ 디렉토리 안에 다 들어 있습니다.
  • 원격 저장소(Remote Repository) — GitHub, GitLab 등 외부 저장소.

명령 대부분은 — 이 4개 사이에서 파일을 옮기는 동작입니다. add는 작업 디렉토리 → 스테이지. commit은 스테이지 → 로컬 저장소. push는 로컬 → 원격. 이 그림 하나만 머리에 있으면, 어떤 명령이든 "지금 뭘 하는지" 알 수 있습니다.

0. 처음 한 번만 — 글로벌 설정

git을 설치하고 가장 먼저 할 일. 이름과 이메일은 모든 커밋에 박힙니다.

git config --global user.name "Your Name"
git config --global user.email "you@example.com"
 
# 기본 브랜치 이름을 main으로 (옛날 git은 master)
git config --global init.defaultBranch main
 
# 줄바꿈 문제 (Mac/Linux)
git config --global core.autocrlf input
 
# 자주 쓰는 별칭 (선택)
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch

확인은:

git config --list

1. git init / git clone — 시작점 두 가지

저장소를 만드는 방법은 두 가지뿐입니다.

새로 시작하기 — 빈 폴더에서:

mkdir my-project
cd my-project
git init

.git/ 폴더가 생깁니다. 이게 git 저장소의 정체입니다. 이걸 지우면 — 그냥 평범한 폴더로 돌아갑니다.

남의 저장소 가져오기:

git clone https://github.com/user/repo.git
git clone https://github.com/user/repo.git my-folder-name  # 폴더명 바꿔서

clone은 단순히 다운로드가 아닙니다 — 원격 저장소 정보까지 같이 가져와서 연결까지 끝낸 상태입니다. 바로 push/pull이 됩니다.

2. git status — 가장 자주 치는 명령

git을 잘 쓰는 사람의 가장 큰 비결 — git status를 하루에 50번 칩니다.

git status

지금 상태를 한 화면으로 보여줍니다:

  • 어느 브랜치에 있는지
  • 어떤 파일이 수정됐는지
  • 스테이지에 뭐가 들어 있는지
  • 추적 안 되는 새 파일이 뭔지

모든 다음 행동은 status에서 시작합니다. 모르겠으면 status. 다른 단축키:

git status -s   # 짧게
git status -sb  # 짧게 + 브랜치 정보

3. git add — 스테이지에 올리기

git add file.txt           # 한 파일
git add src/               # 폴더 안의 모든 변경
git add .                  # 현재 폴더 아래 전부
git add -A                 # 저장소 전체
git add -p                 # 파일 안에서 부분만 선택해서 (강력함)

git add -p반드시 알아야 합니다. 한 파일에 여러 종류의 변경이 섞여 있을 때 — git이 변경 덩어리(hunk)를 하나씩 보여주면서 "이거 스테이지에 올릴래?"라고 물어봅니다. 의미 단위로 커밋을 나누는 마법.

4. git commit — 로컬 저장소에 기록

스테이지에 올라간 변경을 — 영구적으로 기록합니다.

git commit -m "feat: add login flow"

좋은 커밋 메시지의 첫 줄은 50자 이내, 명령형 동사로 시작. 영어든 한국어든 동일:

  • feat: 로그인 흐름 추가 (O)
  • 로그인 추가함 (그냥저냥)
  • 로그인 흐름을 추가했습니다 라는 변경이 들어갔습니다 (X)

자세한 설명이 필요하면:

git commit  # 에디터가 열림. 첫 줄 제목, 빈 줄, 본문.

자주 쓰는 변형:

git commit -am "..."   # add + commit 한 번에 (이미 추적 중인 파일만)
git commit --amend     # 마지막 커밋 메시지/내용 수정 (아직 push 안 했을 때만)

5. git log — 히스토리 보기

지금까지 쌓인 커밋을 봅니다.

git log                          # 전체
git log --oneline                # 한 줄씩
git log --oneline --graph        # 브랜치 그림까지
git log --oneline --graph --all  # 모든 브랜치 다
git log -p                       # 변경 내용까지
git log -5                       # 최근 5개
git log --author="kim"           # 특정 사람
git log --since="1 week ago"     # 특정 기간

내가 가장 자주 쓰는 조합:

git log --oneline --graph --all -20

이거 하나로 저장소의 최근 모양이 한눈에 보입니다.

6. git diff — 변경 내용 보기

뭐가 바뀌었는지 정확히 보고 싶을 때.

git diff              # 작업 디렉토리 vs 스테이지 (아직 add 안 한 변경)
git diff --staged     # 스테이지 vs 마지막 커밋 (add는 했지만 commit 안 한 변경)
git diff HEAD         # 작업 디렉토리 vs 마지막 커밋 (전부)
git diff main feature # 브랜치 간 차이
git diff abc123 def456 # 특정 커밋 간 차이

커밋 전엔 항상 git diff --staged로 한 번 봅니다. 의도하지 않은 변경(console.log, 디버그 코드)이 같이 올라가는 걸 막아줍니다.

7. .gitignore — 추적하지 않을 것들

저장소 루트에 .gitignore 파일을 만들고 — 추적하지 말 파일/폴더를 적습니다.

# 의존성
node_modules/
.venv/
__pycache__/
 
# 빌드 산출물
dist/
build/
.next/
 
# 환경 변수 (절대!)
.env
.env.local
.env.*.local
 
# OS
.DS_Store
Thumbs.db
 
# 에디터
.vscode/
.idea/
*.swp

언어별 .gitignore 템플릿은 github/gitignore에 다 있습니다. 그냥 복붙.

8. git branch / git switch — 브랜치

브랜치는 — 같은 저장소에서 평행 우주를 만드는 것입니다. 하나의 브랜치에서 작업하다가, 다른 브랜치로 옮기면 — 작업 디렉토리의 파일들이 그 브랜치의 마지막 모양으로 싹 바뀝니다.

git branch                    # 브랜치 목록
git branch feature/login      # 새 브랜치 만들기 (안 옮김)
git switch feature/login      # 브랜치 옮기기
git switch -c feature/login   # 만들고 바로 옮기기 (자주 씀)
git switch main               # main으로 돌아가기
git branch -d feature/login   # 브랜치 삭제 (이미 머지됨)
git branch -D feature/login   # 강제 삭제 (안 머지됐어도)

옛날에는 git checkout이 브랜치 이동과 파일 복원 둘 다 했는데 — 헷갈려서 git 2.23부터 둘로 나뉘었습니다:

  • git switch — 브랜치 이동
  • git restore — 파일 복원

이걸 쓰는 게 더 명확합니다.

작업 흐름의 기본형:

git switch main            # main에서 시작
git pull                   # 최신 상태로
git switch -c feature/x    # 새 브랜치 만들고 옮기기
# ... 작업 ...
git add . && git commit -m "feat: ..."
git push -u origin feature/x  # 원격에 첫 push

9. git merge — 합치기

브랜치를 다 만들었으면 — 어딘가에 합쳐야 합니다.

git switch main         # 받을 브랜치로 옮기고
git merge feature/login # feature/login의 변경을 main에 합침

**충돌(conflict)**이 나면 — git이 멈추고 알려줍니다. 같은 파일의 같은 줄을 두 브랜치가 다르게 고친 경우.

충돌 파일은 이렇게 표시됩니다:

<<<<<<< HEAD
const port = 3000;
=======
const port = 8080;
>>>>>>> feature/login

해결 방법:

  1. 에디터로 파일 열어서 어느 쪽이 맞는지 결정 (또는 둘 다 살리기)
  2. <<<, ===, >>> 마커 다 지우기
  3. git add <파일>
  4. git commit (메시지는 자동으로 머지 커밋용으로 채워짐)

중간에 포기하고 싶으면:

git merge --abort

원래 상태로 돌아갑니다.

10. git pull / git push — 원격과 동기화

원격 저장소와 변경을 주고받습니다.

git pull            # 원격 변경을 가져와서 내 브랜치에 머지
git push            # 내 변경을 원격으로 올림
git push -u origin feature/x  # 첫 push (브랜치 연결)
git fetch           # 원격 정보만 가져오고 머지는 안 함 (안전한 pull)

내가 추천하는 패턴은 — 항상 fetch 먼저, 보고 나서 pull:

git fetch
git log --oneline ..origin/main  # 원격에 어떤 새 커밋이 있는지 보기
git pull                          # 괜찮으면 머지

급하면 그냥 git pull 해도 됩니다. 다만 — push가 거부될 때(! [rejected])는 거의 항상 원격에 내가 모르는 새 커밋이 있다는 뜻. 먼저 pull 하고 다시 push.

11. git restore — 파일 되돌리기

실수했을 때 — 작업 디렉토리의 파일을 마지막 커밋 상태로 되돌리는 가장 안전한 방법.

git restore file.txt          # 작업 디렉토리의 변경을 버림
git restore --staged file.txt # 스테이지에서 내림 (add 취소)
git restore .                 # 모든 변경 다 버림 (위험!)

12. git reset — 커밋 되돌리기

이미 커밋한 걸 되돌리는 방법. 세 가지 모드가 있습니다.

git reset --soft HEAD~1   # 커밋만 취소, 변경은 스테이지에 남김
git reset HEAD~1          # 커밋도 취소, 스테이지도 비움, 변경은 작업 디렉토리에
git reset --hard HEAD~1   # 다 날림 (커밋, 스테이지, 작업 디렉토리)

HEAD~1은 "한 커밋 전". HEAD~3은 "세 커밋 전". 특정 커밋으로 가려면 해시:

git reset --hard abc123

13. git revert — 안전한 되돌리기

reset이 "역사를 다시 쓰는" 거라면 — revert는 "역사에 새 줄을 추가하는" 거라고 보면 됩니다. 특정 커밋의 변경을 반대로 적용한 새 커밋을 만듭니다.

git revert abc123

reset은 push된 커밋엔 못 씁니다. revert는 — 이미 공유된 커밋을 안전하게 되돌리는 유일한 방법입니다.

# 시나리오: 어제 푸시한 버그 커밋을 되돌려야 함
git revert HEAD              # 마지막 커밋의 반대 커밋을 만듦
git push                     # 안전하게 올림

14. git stash — 임시 보관

작업 중인데 다른 브랜치로 잠깐 가야 할 때 — 커밋하긴 애매하고, 버리긴 아깝고.

git stash              # 현재 변경을 임시 보관, 작업 디렉토리는 깨끗해짐
git stash list         # 보관된 것들 목록
git stash pop          # 가장 최근 stash를 꺼내서 적용 + 목록에서 삭제
git stash apply        # 꺼내서 적용만 (목록엔 남김)
git stash drop         # 목록에서 버림
git stash -u           # 추적 안 되는 파일까지 함께

자주 쓰는 시나리오:

# 작업 중인데 main에 핫픽스 해달라고 함
git stash
git switch main
# ... 핫픽스 ...
git switch feature/x
git stash pop

15. git reflog — 마지막 안전망

"아 망했어 — reset --hard 했는데 — 잃어버린 거 살릴 수 없나?"

살릴 수 있습니다. 거의 항상.

git reflog

git이 — HEAD가 움직인 모든 기록을 가지고 있습니다. commit, reset, checkout, merge — 다. 그래서 잃어버린 커밋 해시를 찾아서:

git reset --hard abc123  # 그 시점으로 돌아가기

또는 그 커밋만 살려서 새 브랜치로:

git branch recovered abc123

매일 쓰는 흐름 — 한 페이지로

이게 결국 하루의 거의 전부입니다:

# 아침 — 최신 상태로 시작
git switch main
git pull
 
# 새 작업 시작
git switch -c feature/something
 
# 한 사이클 (수십 번 반복)
# ... 코드 작성 ...
git status                    # 뭐가 바뀌었나
git diff                      # 어떻게 바뀌었나
git add -p                    # 의미 단위로 골라서
git diff --staged             # 올라간 거 다시 확인
git commit -m "feat: ..."
 
# 원격에 올리기
git push -u origin feature/something
 
# 다 끝나면
git switch main
git merge feature/something   # 또는 PR을 통해
git branch -d feature/something

흔한 함정 5가지

마지막으로 — 초보가 자주 빠지는 함정과 빠져나오는 법.

1. ".env 커밋했어요"

git rm --cached .env              # 추적에서 제거
echo ".env" >> .gitignore         # 무시 목록에 추가
git commit -m "chore: untrack .env"
# 그리고 노출된 모든 시크릿을 즉시 교체

2. "커밋 메시지 잘못 썼어요"

git commit --amend -m "올바른 메시지"  # push 전이면 OK

3. "푸시 거부됐어요 (rejected)"

거의 항상 — 원격에 새 커밋이 있다는 뜻.

git pull   # 머지하고
git push   # 다시

4. "브랜치를 잘못된 위치에서 시작했어요"

# main에서 시작했어야 하는데 feature/old에서 시작함
git switch feature/new
git rebase --onto main feature/old
# 어렵다면 그냥 변경 복사해서 새로 시작

5. "어제 한 작업이 다 사라졌어요"

git reflog       # 모든 움직임 기록을 봄
git reset --hard <잃어버린>

마무리 — git의 진짜 비밀

이 글에서 다룬 15개 명령은 — 직업적인 개발자도 평균적으로 일주일에 95%를 차지합니다. 나머지 5%는 — rebase, cherry-pick, bisect 같은 도구들. 그건 필요해질 때 배우면 됩니다.

git의 진짜 비밀은 — 두려워하지 않는 것입니다.

대부분의 git 사고는 — commit된 내용이면 reflog로 살릴 수 있고, push되지 않은 변경이면 로컬에서 끝나며, push된 변경이면 revert로 안전하게 되돌릴 수 있습니다. 진짜로 잃어버리는 경우 — git reset --hard로 commit되지 않은 변경을 날린 경우뿐입니다.

그래서 진짜 규칙은 단순합니다 — 자주 커밋하세요. 작업 30분 단위로. 메시지가 못 써도 괜찮습니다. 커밋만 되어 있으면 — git이 알아서 안전망이 됩니다.

다음 글에서는 — 팀 워크플로우(rebase, cherry-pick, PR 흐름)와 GitHub의 협업 패턴을 다루겠습니다.

관련 글