공공부하자개발 · 영어 학습 노트
협업·배포
Git버전 관리와 협업0/8 완료
  • 01저장소와 커밋
  • 02브랜치와 병합
  • 03되돌리기
  • 04원격 저장소
  • 05히스토리 정리
  • 06태그와 버전
  • 07협업 규칙
  • 08문제 해결
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › Git › 08 / 8

문제 해결

섹션 7진행 0 / 8
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

2. 핵심 원리

2.1 증상으로 명령 찾기

증상 원인 명령
브랜치 이름이 안 보이고 HEAD detached 커밋 해시로 checkout git switch -c <새브랜치>
커밋을 엉뚱한 브랜치에 했음 브랜치 전환을 깜빡함 git cherry-pick, git reset
비밀번호·키를 push 까지 함 민감 파일을 실수로 add 키 폐기 + filter-repo
clone·push 가 느리고 저장소가 큼 큰 파일이 히스토리에 남음 count-objects, rev-list, filter-repo
어느 커밋부터 버그가 생겼는지 모름 커밋이 많고 재현이 느림 git bisect run
이 줄을 누가 왜 바꿨는지 모름 변경 이력 확인 안 함 git blame, git log -S
merge·rebase 도중 꼬임 충돌 해결 중 잘못 조작 git merge --abort, git rebase --abort
Unable to create '.git/index.lock' 이전 git 프로세스가 남음 프로세스 확인 후 lock 삭제
한글 파일명이 8진수로 깨져 보임 core.quotepath 기본값 git config core.quotepath false
한 줄만 고쳤는데 파일 전체가 바뀐 것처럼 보임 줄 끝(CRLF/LF) 차이 git diff -w

2.2 detached HEAD 란과 빠져나오기

git checkout <해시> 처럼 브랜치 이름이 아닌 지점으로 이동하면 HEAD 가 브랜치 대신 커밋을 직접 가리킵니다. 이 상태를 detached HEAD 라 합니다. 여기서 만든 커밋은 어떤 브랜치에도 속하지 않아, 다른 브랜치로 이동하면 그 커밋을 가리키는 이름이 사라지고 결국 gc 대상이 됩니다.

구해내는 방법은 git switch -c <새브랜치> 하나뿐입니다. 지금 HEAD 가 가리키는 커밋에 새 브랜치 이름을 붙여 즉시 안전하게 만듭니다.

2.3 잘못된 브랜치에 커밋했을 때 옮기기

두 가지 방법이 있습니다. 상황에 따라 고릅니다.

방법 언제 쓰는가
git cherry-pick 옮길 브랜치가 이미 있고 그 사이에 다른 커밋도 있음
git branch + git reset --hard 옮길 브랜치가 아직 없고 지금 위치를 그대로 살리면 됨

옮길 브랜치가 없다면 git branch feature <해시> 로 지금 위치에 브랜치를 만든 뒤 git reset --hard HEAD~N 으로 잘못된 브랜치에서 커밋을 지우는 쪽이 더 짧습니다. 이미 갈라진 브랜치로 옮길 때는 cherry-pick 이 필요합니다.

2.4 비밀번호·키 파일을 커밋해 push 까지 했을 때

git revert 는 최신 상태에서 파일 내용을 없앨 뿐, 과거 커밋 안의 값은 히스토리에 그대로 남습니다. clone 이나 fetch 로 과거 커밋을 받으면 여전히 드러나므로 되돌리기로는 부족합니다.

대응 순서는 다음과 같습니다.

  1. 키를 즉시 폐기하고 새로 발급합니다. 히스토리 정리보다 항상 먼저입니다.
  2. 히스토리에서 완전히 제거하려면 git filter-repo --path <파일> --invert-paths 를 씁니다. 더 간단한 대안 도구로 BFG(bfg --delete-files <파일>)도 있습니다.
  3. 원격 팀원에게 미리 알린 뒤 force push 하고, 모두 새로 clone 하게 합니다.

2.5 큰 파일로 저장소가 무거워졌을 때

git count-objects -vH 로 저장소 전체 크기를 먼저 확인합니다. 큰 원인을 찾으려면 git rev-list --objects --all 과 git cat-file --batch-check 를 묶어 blob 을 크기순으로 훑습니다(4.1 에서 실제 실행).

큰 blob 을 찾았으면 2.4 와 같은 git filter-repo 로 히스토리에서 제거합니다.

재발 방지는 .gitignore 로 빌드 산출물을 미리 막고, pre-commit 훅으로 파일 크기를 검사합니다(레슨 07 참고). 원래 큰 바이너리가 필요하면 Git LFS 를 씁니다.

2.6 git bisect: 버그가 생긴 커밋 찾기

커밋이 많고 눈으로 하나씩 확인하기 힘들 때 이분 탐색으로 첫 번째 "나쁜" 커밋을 찾습니다.

명령 동작
git bisect start 탐색 시작
git bisect bad [커밋] 이 커밋(기본 HEAD)은 버그 있음
git bisect good <커밋> 이 커밋은 버그 없음(정상)
git bisect run <스크립트> 스크립트 종료 코드로 자동 판정(0=good, 1=bad)
git bisect reset 탐색 종료, 원래 브랜치로 복귀

run 에 넘기는 스크립트는 현재 checkout 된 파일을 검사해 정상이면 0, 버그면 1(또는 다른 0이 아닌 값)을 반환하면 됩니다. git 이 good·bad 사이를 자동으로 checkout 하며 반복합니다.

2.7 git blame: 누가 언제 바꿨는가

git blame <파일> 은 파일의 각 줄을 마지막으로 바꾼 커밋을 보여줍니다. 자주 쓰는 옵션은 다음과 같습니다.

옵션 동작
-L 10,20 10~20 번째 줄만
-w 공백만 바뀐 줄은 이전 커밋 그대로 표시
--since=2026-01-01 그 날짜 이후 변경만 추적

blame 은 "누가·언제" 는 바로 보여주지만 "왜" 는 알려주지 않습니다. 이유는 그 커밋의 메시지나 연결된 PR 을 함께 봐야 합니다.

2.8 log -S / -G / --follow / -- 경로: 변경 추적

명령 동작
git log -S"문자열" 그 문자열의 등장 횟수가 바뀐 커밋(pickaxe)
git log -G"정규식" 정규식과 매치되는 줄이 추가·삭제된 커밋
git log --follow -- <파일> 이름이 바뀌어도 그 전 이력까지 추적
git log -- <경로> 특정 파일·폴더의 커밋만

-S 는 문자열이 나타나거나 사라진 커밋을, -G 는 그 문자열을 포함한 줄이 바뀐 커밋을 찾습니다. 문자열이 그대로인데 다른 부분만 바뀐 줄도 -G 는 잡아낼 수 있습니다. 지금 저장소 전체에서 검색할 때는 git grep -n "문자열"(과거 커밋은 -- <커밋> 추가)을 씁니다.

2.9 merge·rebase 중 꼬였을 때: --abort 와 status 힌트

충돌이 나면 git status 가 지금 무엇을 해야 하는지 힌트를 함께 보여줍니다. 해결이 막막하면 무리하지 말고 git merge --abort·git rebase --abort·git cherry-pick --abort 로 시작 전 상태로 되돌립니다.

2.10 자주 보는 오류 메시지와 진단 명령

Unable to create '.git/index.lock': File exists 는 이전 git 프로세스가 비정상 종료했거나 다른 터미널에서 아직 실행 중이라는 뜻입니다. 다른 프로세스가 정말 없는지 확인한 뒤에만 lock 파일을 지웁니다.

한글 파일명이 "\355\225..." 처럼 깨져 보이면 git config core.quotepath false 를 설정합니다. 한 줄만 고쳤는데 파일 전체가 바뀐 것처럼 보이면 CRLF·LF 줄 끝 차이이므로 git diff -w 로 실제 변경만 확인합니다.

저장소 차원의 근본 해결은 .gitattributes 이며 레슨 07 에서 다뤘습니다.

git fsck 는 깨진 오브젝트나 매달린 커밋을 검사하고, git gc 는 느슨한 오브젝트를 정리해 압축합니다. 둘 다 충돌 해결 도구가 아니라 저장소 정합성 점검 도구입니다. 그리고 무엇을 되돌리든, 실수를 알아챈 첫 행동은 항상 git reflog 확인입니다.

핵심 원리
  • 2.1 증상으로 명령 찾기
  • 2.2 detached HEAD 란과 빠져나오기
  • 2.3 잘못된 브랜치에 커밋했을 때 옮기기
  • 2.4 비밀번호·키 파일을 커밋해 push 까지 했을 때
  • 2.5 큰 파일로 저장소가 무거워졌을 때
  • 2.6 git bisect: 버그가 생긴 커밋 찾기
  • 2.7 git blame: 누가 언제 바꿨는가
  • 2.8 log -S / -G / --follow / -- 경로: 변경 추적
  • 2.9 merge·rebase 중 꼬였을 때: --abort 와 status 힌트
  • 2.10 자주 보는 오류 메시지와 진단 명령
이전 섹션1 왜 배우는가2 / 7다음 섹션3 코드 예제