DevFinance
테크·11 min read

Git 고급 명령어 실무 가이드 2026 — rebase, stash, cherry-pick 완전 정리

개발자가 실무에서 꼭 알아야 할 Git 고급 명령어를 정리했습니다. rebase vs merge, interactive rebase, stash, cherry-pick, bisect, reflog로 실수 복구까지 실전 예시와 함께 설명합니다.

Git — 단순 저장소를 넘어 협업 도구로

git add, commit, push만 알아도 개발을 시작할 수 있지만, 실무에서는 더 많은 상황을 만납니다. 충돌 해결, 커밋 정리, 실수 복구, 효율적인 브랜치 전략까지 — Git의 고급 기능을 알면 협업 속도가 달라집니다.


rebase — 깔끔한 히스토리의 핵심

rebase vs merge 차이

상황: main에 새 커밋이 생겼고, 내 feature 브랜치를 최신으로 업데이트하고 싶다.

merge 방식:
main:    A -- B -- C
                    \
feature: D -- E -- merge commit (F)

히스토리: 병합 커밋(F)이 생겨 히스토리가 복잡해짐

rebase 방식:
main:    A -- B -- C
                    \
feature:             D' -- E' (재작성된 커밋)

히스토리: 선형, 깔끔

기본 rebase 사용법

# feature 브랜치에서 main의 최신 변경사항을 가져올 때
git checkout feature/my-feature
git fetch origin
git rebase origin/main

# 충돌이 발생하면:
# 1. 충돌 파일 수정
# 2. git add <수정한 파일>
# 3. git rebase --continue
# 충돌 해결을 포기할 때:
git rebase --abort

rebase 주의사항

# 절대 하지 말 것: 공유 브랜치에 rebase 후 force push
git checkout main
git rebase feature/my-feature  # 위험!
git push --force               # 팀원 히스토리 파괴!

# 안전한 사용: 로컬 개인 브랜치에서만
git checkout feature/my-feature  # 내 브랜치
git rebase origin/main           # OK
git push --force-with-lease      # push한 적 없으면 안전

Interactive Rebase — 커밋 정리의 강자

PR 올리기 전 커밋을 정리할 때 필수입니다.

# 최근 3개 커밋 수정
git rebase -i HEAD~3

에디터에 표시되는 내용:

pick a1b2c3 feat: 로그인 API 연결
pick d4e5f6 wip: 임시 저장
pick g7h8i9 fix: 오타 수정

# 명령어:
# pick = 그대로 유지
# reword = 커밋 메시지 수정
# edit = 커밋 내용 수정
# squash = 이전 커밋에 합치기 (메시지 합침)
# fixup = 이전 커밋에 합치기 (메시지 버림)
# drop = 커밋 삭제

실전 시나리오

# 시나리오 1: 여러 WIP 커밋을 하나로 합치기
pick a1b2c3 feat: 로그인 API 연결
squash d4e5f6 wip: 임시 저장        # a1b2c3에 합침
fixup  g7h8i9 fix: 오타 수정        # 메시지 없이 합침

# → 결과: "feat: 로그인 API 연결" 하나의 깔끔한 커밋

# 시나리오 2: 커밋 메시지 일괄 수정
reword a1b2c3 feat: 로그인 API 연결   # 메시지 수정할 커밋
pick   d4e5f6 fix: 유효성 검사 추가

# 시나리오 3: 잘못된 커밋 삭제
pick a1b2c3 feat: 로그인 API 연결
drop d4e5f6 wip: 실수로 커밋한 민감 정보  # 삭제
pick g7h8i9 fix: 유효성 검사 추가

Stash — 임시 저장소

작업 중 급하게 다른 브랜치로 전환해야 할 때 사용합니다.

# 현재 변경사항 임시 저장
git stash

# 메시지와 함께 저장 (여러 stash 구분에 유용)
git stash push -m "로그인 폼 작업 중"

# stash 목록 확인
git stash list
# stash@{0}: On feature/login: 로그인 폼 작업 중
# stash@{1}: WIP on main: 이전 작업

# 최근 stash 복원 (스택에서 제거)
git stash pop

# 특정 stash 복원
git stash apply stash@{1}

# 특정 stash 삭제
git stash drop stash@{0}

# 전체 stash 삭제
git stash clear

# stash를 브랜치로 만들기 (안전한 복원)
git stash branch feature/saved-work stash@{0}

Stash 고급 옵션

# 추적되지 않은 파일도 포함 (-u)
git stash -u

# 무시된 파일까지 포함 (-a, 드물게 사용)
git stash -a

# stash 내용 확인
git stash show -p stash@{0}

# 특정 파일만 stash
git stash push -m "특정 파일만" -- src/components/Login.tsx

Cherry-pick — 커밋 선택 이식

# 단일 커밋 적용
git cherry-pick abc123

# 여러 커밋 적용
git cherry-pick abc123 def456

# 범위 적용 (a 제외, b까지)
git cherry-pick abc123..def456

# 커밋하지 않고 스테이징만
git cherry-pick --no-commit abc123

# 충돌 발생 시
git cherry-pick --continue
git cherry-pick --abort

실전 시나리오

# 시나리오 1: hotfix를 main과 develop 둘 다에 적용
git checkout main
git cherry-pick hotfix-commit-hash

git checkout develop
git cherry-pick hotfix-commit-hash

# 시나리오 2: 잘못된 브랜치에 커밋한 작업 이동
# main에 실수로 커밋 → feature 브랜치로 이동

# 1. feature 브랜치로 커밋 가져오기
git checkout feature/my-feature
git cherry-pick <commit-hash>

# 2. main에서 커밋 제거 (아직 push 안 한 경우)
git checkout main
git reset --hard HEAD~1

reflog — 히스토리 복구의 최후 수단

reflog는 Git이 내부적으로 유지하는 작업 로그입니다. 커밋 삭제, 브랜치 삭제, reset 후에도 복구가 가능합니다.

# 전체 reflog 보기
git reflog

# 결과 예시:
# abc1234 HEAD@{0}: reset: moving to HEAD~3
# def5678 HEAD@{1}: commit: feat: 중요한 기능 추가  ← 잃어버린 커밋
# ghi9012 HEAD@{2}: commit: fix: 버그 수정

# 잃어버린 커밋으로 이동
git checkout def5678

# 브랜치로 복구
git branch recovery/lost-feature def5678

# 현재 브랜치를 복구 지점으로 이동
git reset --hard def5678

주요 복구 시나리오

# 시나리오 1: git reset --hard로 날린 커밋 복구
git reset --hard HEAD~3  # 실수로 3개 커밋 제거
git reflog               # 이전 상태 해시 확인
git reset --hard <이전 해시>

# 시나리오 2: 삭제된 브랜치 복구
git branch -D feature/important  # 실수로 브랜치 삭제
git reflog                        # 마지막 커밋 해시 확인
git checkout -b feature/important <해시>

# 시나리오 3: merge 취소
git merge feature/something       # merge 후 문제 발견
git reflog                         # merge 전 상태 확인
git reset --hard ORIG_HEAD         # merge 전으로 되돌리기

git bisect — 버그 도입 커밋 이진 탐색

언제부터 버그가 생겼는지 모를 때, 이진 탐색으로 빠르게 원인 커밋을 찾습니다.

# bisect 시작
git bisect start

# 현재 상태: 버그 있음
git bisect bad

# 버그 없던 커밋 (예: 1주일 전)
git bisect good v1.0.0

# Git이 중간 커밋으로 이동 → 테스트 후 결과 입력
git bisect good  # 이 커밋은 정상
git bisect bad   # 이 커밋에서 버그 발생

# 반복... 몇 번 만에 원인 커밋 특정

# 종료
git bisect reset

# 자동화: 테스트 스크립트로 자동 bisect
git bisect start HEAD v1.0.0
git bisect run npm test -- --grep "특정 테스트"

브랜치 전략 — Git Flow vs Trunk-Based

Git Flow (전통적)

main         ──────────────────────────── (프로덕션)
develop    ──────────────────────────────  (통합)
feature/A   ──────┐
feature/B         └──────────────────────
release/1.0                   ──────────
hotfix/1.0.1                        ────
# Git Flow CLI 사용
git flow init

git flow feature start my-feature
git flow feature finish my-feature

git flow release start 1.0.0
git flow release finish 1.0.0

Trunk-Based Development (현대적)

main  ──────────────────────────── (항상 배포 가능)
feat   ──┘  ──┘  ──┘              (단명 브랜치, 1~2일)
# 단명 피처 브랜치 패턴
git checkout -b feat/login-button   # 이름 간결하게
# 작업
git push origin feat/login-button   # 당일 PR 생성
# 리뷰 후 squash merge → 브랜치 삭제

실전 Git 별칭 (alias) 설정

# ~/.gitconfig에 추가
git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.st "status -s"
git config --global alias.cm "commit -m"
git config --global alias.co "checkout"
git config --global alias.br "branch"
git config --global alias.undo "reset --soft HEAD~1"
git config --global alias.wip "commit -am 'wip'"
git config --global alias.unwip "reset HEAD~1"
# 사용 예시
git lg          # 그래프 형태 로그
git st          # 짧은 상태 확인
git undo        # 마지막 커밋 취소 (변경사항 유지)
git wip         # 임시 커밋
git unwip       # 임시 커밋 취소

자주 하는 실수와 해결

커밋 메시지를 잘못 작성했을 때

# 마지막 커밋 메시지 수정 (아직 push 안 한 경우)
git commit --amend -m "올바른 커밋 메시지"

# 에디터로 수정
git commit --amend

잘못된 파일을 커밋했을 때

# 파일을 커밋에서 제거하고 스테이징 해제
git reset HEAD~1 -- secret.env
git commit --amend --no-edit

# 또는: 파일만 제거하고 나머지 유지
git rm --cached secret.env
git commit --amend --no-edit

충돌(conflict) 해결 전략

# 현재 브랜치 것으로 전체 해결
git checkout --ours .

# 병합 대상 브랜치 것으로 전체 해결
git checkout --theirs .

# 수동 해결 후
git add <충돌 파일>
git rebase --continue  # 또는 merge --continue

Git 히스토리 작성 컨벤션

Conventional Commits

형식: <type>(<scope>): <description>

type:
  feat     - 새 기능
  fix      - 버그 수정
  docs     - 문서 수정
  style    - 포맷 변경 (기능 변경 없음)
  refactor - 리팩토링
  test     - 테스트 추가/수정
  chore    - 빌드, 설정 변경

예시:
feat(auth): 소셜 로그인 구글 연동 추가
fix(payment): 결제 금액 소수점 처리 버그 수정
docs(api): REST API 엔드포인트 문서 업데이트

관련 글: GitHub Actions CI/CD 설정법 · pnpm vs npm 비교 가이드 · Linux 서버 기초 가이드