Git 실전 트러블슈팅 및 문제 해결 가이드

Git을 사용하다 보면 실수로 잘못된 커밋을 만들거나, 브랜치를 엉뚱한 곳으로 이동시키거나, 리베이스 중 충돌이 발생하는 등 다양한 예외 상황에 직면하게 됩니다. 이 가이드는 개발자들이 자주 겪는 Git 관련 실수와 문제들을 해결하기 위한 실전 트러블슈팅 명령어와 워크플로를 정리한 것입니다.

1. 커밋 수정 및 되돌리기

방금 생성한 커밋의 내용을 확인하고 싶을 때

git commit -a를 사용했지만 어떤 파일이 포함되었는지 확실하지 않다면, 현재 HEAD의 최신 커밋 상세 내역을 확인합니다.

(main)$ git show --stat
# 또는 패치 내용까지 확인하려면
(main)$ git log -1 -p

커밋 메시지 오타 수정하기

커밋을 푸시하기 전에 메시지 오타를 발견했다면 --amend 옵션을 사용합니다.

(feature/oauth)$ git commit --amend -m "feat: implement google oauth login flow"

이미 원격 저장소에 푸시한 경우라면 git push --force-with-lease를 사용해야 하지만, 팀원들과 공유된 브랜치라면 새로운 커밋을 추가하는 방식을 권장합니다.

특정 파일만 커밋에서 제외하기

커밋에 포함하지 말아야 할 파일(예: 환경 변수 파일, 빌드 결과물)이 실수로 포함되었을 때:

(feature/db)$ git reset HEAD^ .env
(feature/db)$ git commit --amend -C HEAD

로컬 커밋 히스토리 초기화 및 되돌리기

아직 원격에 푸시하지 않은 최근 N개의 커밋을 취소하고 작업물은 유지하고 싶다면:

(fix/bug-102)$ git reset --soft HEAD~3

작업물까지 완전히 폐기하고 싶다면 --hard 옵션을 사용합니다. (주의: 되돌릴 수 없음)

2. 스테이징 및 작업 영역 관리

파일의 일부 변경 사항만 스테이징하기

하나의 파일에 여러 기능의 수정 사항이 섞여 있을 때, 대화형 모드를 이용해 특정 헝크(hunk)만 선택적으로 스테이징할 수 있습니다.

(main)$ git add -p src/payment/service.py

프롬프트에서 y는 스테이징, n은 건너뛰기, s는 현재 헝크를 더 작게 분할할 때 사용합니다.

스테이징된 내용과 작업 영역 내용 서로 뒤바꾸기

현재 스테이징된 내용은 작업 영역으로 내리고, 작업 영역의 변경 사항은 스테이징으로 올리고 싶을 때:

(dev)$ git stash push --keep-index
(dev)$ git reset --hard
(dev)$ git stash pop

3. 브랜치 조작 및 복구

잘못된 브랜치에서 작업한 내용 새 브랜치로 옮기기

main 브랜치에서 커밋을 해버렸을 때, 기존 main을 초기화하고 새 브랜치로 작업을 이동시킵니다.

(main)$ git branch feature/search-api
(main)$ git reset --hard origin/main
(main)$ git checkout feature/search-api

실수로 삭제한 로컬 브랜치 복구하기

브랜치를 잘못 삭제했을 때는 reflog를 통해 삭제 직전의 커밋 해시를 찾아 복구합니다.

(main)$ git reflog
# 삭제된 브랜치의 마지막 커밋 해시 확인 (예: a1b2c3d)
(main)$ git checkout -b restored-branch a1b2c3d

원격에서 삭제된 브랜치 로컬에서 정리하기

PR이 병합되어 원격에서는 삭제된 브랜치들을 로컬에서 한 번에 정리하려면:

(main)$ git fetch --prune

4. 리베이스 및 병합 충돌 해결

진행 중인 리베이스 또는 병합 취소하기

충돌 해결이 너무 복잡해지거나 실수로 잘못된 대상과 리베이스를 시작했다면, 안전하게 이전 상태로 롤백합니다.

(feature/cart)$ git rebase --abort
# 병합 중이었다면
(feature/cart)$ git merge --abort

여러 커밋을 하나로 압축(Squash)하기

PR을 올리기 전, 자잘한 커밋들을 하나의 의미 있는 커밋으로 합칠 때 대화형 리베이스를 사용합니다.

(feature/ui)$ git rebase -i HEAD~4

에디터가 열리면 첫 번째 커밋은 pick으로 두고, 나머지 커밋들을 squash (또는 s)로 변경합니다. 이후 새로운 커밋 메시지를 작성하면 됩니다.

병합 충돌 시각적으로 해결하기

터미널에서 텍스트로 충돌을 해결하기 어려울 때, 설정된 머지 툴을 활용합니다.

(main)$ git mergetool --tool=vscode

5. 기타 유용한 설정 및 명령어

대소문자만 다른 파일명 변경하기

Git은 기본적으로 파일명의 대소문자 변경을 감지하지 못합니다. -f 옵션을 강제로 사용해야 합니다.

(main)$ git mv -f userprofile.js UserProfile.js

Git 추적에서 파일 제외하기 (로컬 파일은 유지)

이미 추적 중인 파일을 .gitignore에 추가한 후, Git의 추적 목록에서만 제거하고 로컬 파일은 남겨둡니다.

(main)$ git rm --cached config/database.yml
(main)$ git commit -m "chore: stop tracking database config file"

자주 사용하는 명령어 별칭(Alias) 설정하기

반복적으로 입력하는 긴 명령어는 전역 설정에 별칭으로 등록해 생산성을 높일 수 있습니다.

$ git config --global alias.st "status -sb"
$ git config --global alias.co "checkout"
$ git config --global alias.br "branch"
$ git config --global alias.last "log -1 HEAD --stat"

태그: Git Troubleshooting version-control git-rebase git-merge

7월 10일 02:40에 게시됨