손상되지 않은 git 저장소가 있습니다(모든 개체 파일이 보존되어 커밋할 수 있습니다 등).
최근에 "커밋 오류"로 인해 일부 오래된 커밋이 중단된 것을 발견했습니다.
git fsck --완료 개체 디렉터리 확인: 100%(256/256), 완료되었습니다. 커밋 오류 1e04e033e642f9310bd7b0e6745f3ef775a15f15: 잘못된 작성자/커미터 줄 - 잘못된 이메일
개별 커밋을 살펴보았습니다.
zpipe -d <.git/objects/1e/04e033e642f9310bd7b0e6745f3ef775a15f15 276tree 591e98a0b53880a22f18f5bedefe133166d3e67d 제출 상위 4c33ebce11897dd52528defa41890eabc59135e3 저자 마틴 린드<[이메일 보호됨] > 1382869510 +0100 마틴 린드(Martin Lindhe)가 제출함 <[이메일 보호됨] > 1382869510 +0100 메시지 제출
여기에 표시된 것처럼 이메일에는 후행 개행 문자(0x0a, xxd로 파이핑하여 표시됨)가 있습니다.
개체 헤더를 수정할 수 있나요?
답변1
어떤 작업을 하기 전에 로컬 저장소를 백업하세요.
깨진 커밋이 이라고 가정합니다 <corrupted>
.
먼저 손상된 커밋 개체를 기반으로 새 커밋 개체를 만듭니다.
git commit-tree -m "New message line 1" -m "Line 2" <corrupt>^{tree} -p <corrupt>^1
참고: 명령을 조정하십시오(부모를 추가하려면 -p, 메시지 줄을 커밋하려면 -m 등). 작성자 이름/이메일 등을 처리하려면 git-commit-tree 매뉴얼 페이지를 참조하세요.
새로운 커밋 SHA-1을 얻게 됩니다: <fixed>
.
이제 커밋 교체(마이그레이션)를 수행합니다.
git replace <corrupted> <fixed>
이렇게 하면 깨진 커밋을 고정 커밋으로 인위적으로 변경하는 "마이그레이션"이 생성됩니다.
이 수정 사항은 되돌릴 수 있습니다. 이를 제거하거나 git-replace
명령을 통해 표시하거나(맨 페이지 참조!) .git/refs/replace/
디렉토리를 볼 수 있습니다.
영구적으로 만들려면 다음을 사용하세요.git filter-branch
그러나 변경된 모든 부분은 새로운 커밋 개체(예: 새로운 SHA-1)로 구성됩니다..
# HEAD should point to the most recent commit (certainly master)...
git filter-branch <fixed>~1..HEAD
마지막으로 교체를 연기하세요(이제 기록에 영구적으로 남습니다).
git replace -d <corrupted>
이는 하나의 마스터 브랜치에서는 잘 작동하지만, 활성 브랜치가 여러 개인 경우( <corrupted> 이후에 생성됨) 다음과 같이 모두 리베이스해야 합니다.
git rebase --onto <new-root-branch> <old-root-branch> <branch>
어디:
<new-root-branch>
이제 브랜치가 시작되어야 하는 커밋입니다(새 기본 SHA-1).<old-root-branch>
필터 분기가 호출되기 전에 분기가 시작된 커밋입니다.<branch>
리베이스할 브랜치입니다.
다음 로그 명령을 사용하여 이러한 SHA-1을 찾으십시오.
git log --graph --decorate --all --pretty=oneline
모든 것(브랜치 등)이 정상인지 다시 확인하고 git 저장소에 연결된 모든 사람이 무슨 일이 일어나고 있는지 정확히 이해하면 다음을 수행할 수 있습니다.git push --force
당신의 수정.