손상된 Git 저장소 복구: 완벽한 문제 해결 가이드
백업, git fsck, 인덱스 복구, reflog 복구, 안전한 재클론을 통해 Git 저장소 손상을 진단하고 복구합니다.
손상된 Git 저장소 복구: 완벽한 문제 해결 가이드
Git 저장소는 일반적으로 견고하지만, 하드웨어 오류, 갑작스러운 시스템 충돌, 디스크 오류, 또는 중요한 Git 작업(객체 패킹이나 히스토리 재작성 등) 중 전원 손실과 같은 외부 요인으로 인해 데이터 손상이 발생할 수 있습니다. 손상된 저장소는 혼란스러운 오류, 커밋 불가능, 또는 누락된 객체 보고서로 나타날 수 있습니다.
이 가이드는 손상 유형을 진단하고, 적절한 복구 기술을 적용하며, 손실된 데이터를 안전하게 복구하는 체계적인 단계별 접근 방식을 제공합니다. 저장소 손상은 영구적인 데이터 손실로 이어질 수 있으므로, 침습적인 복구를 시도하기 전에 항상 안전 백업을 생성하는 모범 사례를 따르십시오.
1. 안전 우선: 손상된 저장소 백업
특히 .git 디렉토리 내 파일 시스템 조작을 포함하는 복구 명령을 시작하기 전에 완전한 백업을 생성해야 합니다. 이렇게 하면 복구 프로세스가 추가 문제를 일으킬 경우 현재 손상된 상태로 되돌릴 수 있습니다.
# 저장소 디렉토리 밖으로 이동
cd ..
# 전체 디렉토리의 압축 백업 생성
tar -czvf myrepo_corrupted_backup.tar.gz myrepo
# 또는 전체 저장소 디렉토리 복사
cp -R myrepo myrepo_backup_$(date +%Y%m%d)
2. git fsck로 손상 진단
Git 저장소의 무결성을 확인하는 주요 도구는 git fsck(파일 시스템 검사)입니다. 이 명령은 객체 데이터베이스와 참조를 스캔하여 불일치, 누락된 객체 또는 끊어진 링크를 찾습니다.
포괄적인 검사를 위해 다음 명령을 실행하세요:
# 상세 출력으로 무결성 검사 실행
git fsck --full --unreachable --strict
git fsck 출력 해석
| 오류 메시지 | 의미 | 심각도 | 주요 해결책 |
|---|---|---|---|
error: object XXXXX is missing |
필수 blob, 트리 또는 커밋 객체가 완전히 누락됨. | 높음 | 원격/백업에서 복구. |
dangling commit XXXXX |
커밋이 존재하지만 어떤 브랜치, 태그 또는 reflog에서 참조되지 않음. | 낮음/중간 | git reflog를 통한 복구. |
dangling blob XXXXX |
데이터가 존재하지만 어떤 커밋이나 트리와 연결되지 않음. | 낮음 | 일반적으로 무시하거나 정리 가능. |
error: HEAD points to an unborn branch |
.git/HEAD 파일이 손상되었거나 존재하지 않는 브랜치를 가리킴. |
중간 | .git/HEAD 수동 수정 또는 git reset. |
3. Git 인덱스(.git/index) 복구
인덱스 파일은 Git이 작업 디렉토리와 마지막 커밋 사이의 변경 사항을 추적하는 데 사용하는 스테이징 영역 캐시입니다. 인덱스 손상은 시스템 충돌이나 실패한 병합 후 가장 흔한 문제 중 하나입니다.
Git 작업이 인덱스가 유효하지 않거나, 일관성이 없거나, 읽을 수 없다는 오류와 함께 실패하면 인덱스를 다시 빌드해야 합니다.
방법 1: Git이 인덱스를 다시 읽도록 강제
인덱스 복구를 시도하는 가장 안전한 방법은 하드 리셋을 수행하는 것입니다. 이렇게 하면 Git이 최신 커밋을 기반으로 인덱스와 작업 디렉토리를 조정하도록 강제합니다.
git reset --hard HEAD
방법 2: 인덱스 수동 삭제 및 재생성
git reset이 실패하면 손상된 인덱스 파일을 삭제할 수 있습니다. Git은 git status 또는 git add와 같은 명령이 필요할 때 다음 번에 자동으로 인덱스를 다시 생성합니다.
경고: 인덱스를 삭제하면 스테이징 영역이 지워집니다. git add를 사용하여 스테이징한 모든 변경 사항이 손실됩니다.
# 손상된 인덱스 파일 삭제
rm .git/index
# Git이 HEAD에서 인덱스를 다시 빌드하도록 강제
git reset
# 기능 확인을 위해 상태 확인
git status
4. 깨진 객체 및 누락된 객체 처리
깨진 Git 객체(blob, 트리 또는 커밋)와 관련된 손상은 특히 객체가 실제로 누락된 경우 수정하기 가장 어려운 경우가 많습니다. 그러나 때로는 손상이 잘못 패키징된 객체나 복구 가능한 고아 객체로 인해 발생합니다.
4.1. 저장소 재패키징
Git은 객체를 느슨한 파일로 저장하거나 팩 파일로 통합하여 저장합니다. 때로는 재패키징 작업을 실행하면 사소한 무결성 문제를 해결하고 성능을 향상시킬 수 있습니다.
# 모든 느슨한 객체 재패키징, 무결성 확인, 오래된 팩 파일 정리
git repack -a -d
# 개선 확인을 위해 fsck 재실행
git fsck --full
4.2. Reflog를 통한 고아 커밋 복구
dangling commit은 유효하지만 알려진 참조(브랜치, 태그)로 도달할 수 없는 커밋 객체입니다. 이는 강제 리셋이나 히스토리 재작성 후에 자주 발생합니다. reflog는 로컬 HEAD 및 참조의 히스토리를 추적하며, 종종 복구의 열쇠를 쥐고 있습니다.
Reflog 보기:
git reflog손실을 초래한 작업 앞의 SHA-1 해시를 찾으세요(예:
HEAD@{5}: reset: moving to origin/main).커밋 재참조:
올바른 SHA-1(예:
a1b2c3d4)을 식별하면 해당 커밋을 가리키는 새 브랜치를 만들거나 현재 브랜치를 리셋할 수 있습니다.# 예: 새 복구 브랜치 생성 git branch recovered-work a1b2c3d4 # 또는 현재 브랜치를 고아 커밋으로 리셋 # (주의해서 사용) git reset --hard a1b2c3d4
4.3. 실제 누락된 객체 처리
git fsck가 error: object XXXXX is missing을 보고하면 특정 커밋 히스토리에 필요한 데이터가 더 이상 로컬 객체 데이터베이스(.git/objects)에 없다는 의미입니다.
원격이 있는 경우: 유일한 신뢰할 수 있는 해결책은 원격 저장소에서 누락된 객체를 가져오는 것입니다.
git fetch origin # 그런 다음 링크를 복구하거나 영향을 받은 브랜치를 리셋원격이 없는 경우(로컬 손상): 저장소가 전적으로 로컬이고 객체가 누락된 경우, 외부 백업이 없으면 해당 객체가 참조하는 데이터는 영구적으로 손실됩니다.
5. 손상된 참조(Refs) 수정
참조(refs)는 .git/refs/ 디렉토리에 있는 파일(예: 브랜치, 태그, 원격 추적 브랜치)로, 가리키는 커밋의 SHA-1 해시를 포함합니다. 이러한 파일이 손상된 경우(예: 0바이트 또는 잘못된 해시 포함), Git은 브랜치의 상태를 확인할 수 없습니다.
5.1. 위치 확인 및 수동 복구
손상된 참조 식별: 오류 메시지는 일반적으로 어떤 참조가 깨졌는지 지정합니다(예:
error: bad ref for branch 'feature/X').refs 디렉토리로 이동:
cd .git/refs/heads/ # 또는 .git/refs/remotes/origin/파일 검사: 텍스트 편집기나
cat을 사용하여 파일을 봅니다. 정확히 40개의 16진수 문자(SHA-1 해시)가 포함되어야 합니다.수정:
- 해시를 알고 있는 경우(예:
git reflog에서), 올바른 40자 SHA-1을 파일에 수동으로 붙여넣습니다. - 참조가 명백히 깨진 경우(예: 0바이트, 쓰레기 데이터), 파일을 삭제합니다. 그런 다음 필요한 경우 브랜치/참조를 다시 생성해야 합니다(예:
git checkout -b <브랜치-이름> <알려진-좋은-커밋>).
- 해시를 알고 있는 경우(예:
최후의 수단: 손상된 Reflog 파일 제거
특정 reflog 파일이 손상되어 일반 Git 명령을 차단하는 경우, 백업을 받은 후에 파일을 옮기세요. reflog를 제거하면 로컬 복구 히스토리가 삭제되므로, git fsck, refs 검사, 원격 복구가 실패한 후에만 이 작업을 수행하세요.
mv .git/logs .git/logs.corrupt.backup
6. 최종 복구 옵션: 알려진 양호한 소스에서 클론
저장소 손상이 광범위하거나 필요한 객체가 누락된 경우, 가장 안전하고 신뢰할 수 있는 복구 방법은 현재 로컬 저장소를 포기하고 신뢰할 수 있는 소스(일반적으로 GitHub, GitLab 또는 Bitbucket과 같은 원격 서버)에서 다시 클론하는 것입니다.
# 1. 손상된 저장소의 작업 변경 사항 백업
# (예: 커밋되지 않은 파일을 임시 위치에 복사)
# 2. 손상된 저장소 디렉토리 이름 변경 또는 삭제
mv myrepo myrepo_bad
# 3. 새 복사본 클론
git clone <remote_url> myrepo
# 4. 백업된 작업 변경 사항을 새 저장소에 적용
이 방법은 보장된 깨끗하고 검증된 저장소 히스토리 사본으로 시작하여 지속적인 손상 위험을 최소화합니다.
핵심 요점
손상된 Git 저장소를 수정하려면 인덱스, 객체 또는 참조에 대한 대상 복구를 적용하기 전에 git fsck를 사용한 신중한 진단이 필요합니다. 시작하기 전에 .git 디렉토리를 백업하여 항상 안전을 우선시하세요. git reflog와 같은 로컬 복구 방법은 히스토리 복구에 강력하지만, 심각한 손상의 경우 원격 저장소에서 클론하는 것이 가장 신뢰할 수 있는 해결책입니다.
핵심 요점:
- 먼저 백업하세요. (항상).
git fsck --full로 진단하세요.- 인덱스 문제는 일반적으로
git reset --hard로 수정됩니다. - 누락된 객체는 일반적으로 원격에서 가져와야 합니다.