Lobsters

Migrating Git repos to SHA-256

Git 저장소를 SHA-256으로 이전하기

Git 저장소를 SHA-1에서 SHA-256으로 바꾸는 절차와 서브모듈 처리 방법을 설명합니다. 서브모듈 저장소를 먼저 변환하고 marks 파일로 객체 ID를 다시 연결해야 하며, Forgejo 저장소를 제자리에서 바꾸는 방법에는 기존 커밋 참조가 깨질 위험이 있습니다.

AI 요약

Git 2.42부터 SHA-256 객체 형식을 사용할 수 있습니다. 글쓴이는 SHA-1의 충돌 방지 구현인 SHA-1dc도 충분하다고 보고, SHA-256이 보안을 크게 높이기보다는 객체 ID를 더 길게 만들고 일부 서드파티 도구와 호환성 문제를 일으킨다고 설명합니다. 다만 이미 변환을 하기로 했다면 저장소에 서브모듈이 있는지 먼저 확인해야 합니다.

기본 저장소 변환

서브모듈이 없는 저장소는 기존 저장소에서 git fast-export --all로 내보낸 뒤, 새 저장소를 git init --object-format sha256으로 만들고 git fast-import로 가져옵니다. 이 간단한 절차는 서브모듈이 있을 때 실패합니다. 서로 다른 해시 형식을 쓰는 저장소를 서브모듈로 섞을 수 없으며, 그대로 가져오면 fast-import가 객체를 찾지 못해 중단될 수 있습니다.

서브모듈이 있는 저장소 변환

먼저 각 서브모듈을 SHA-256으로 변환하고, 기존 객체 ID와 새 객체 ID의 대응을 marks 파일에 기록해야 합니다. 서브모듈 저장소에서 git fast-export --export-marks=marks --all로 내보낸 뒤 새 SHA-256 저장소에서 git fast-import --export-marks=marks로 가져옵니다. 그런 다음 상위 저장소를 내보내고 가져올 때 --rewrite-submodules-from과 --rewrite-submodules-to 옵션을 짝지어 전달합니다. 예를 들어 blah:../old-submodule/marks와 blah:../new-submodule/marks를 지정하면 이전 서브모듈 객체 ID를 새 ID로 바꿉니다. 여러 서브모듈을 처리할 때는 각각 고유한 이름을 사용하고, 두 옵션에서 같은 이름을 지정해야 합니다.

기존 상위 저장소가 현재 브랜치에 없는 커밋을 참조한 적이 있다면 --all만으로 필요한 객체를 전부 내보내지 못할 수 있습니다. 강제 푸시로 브랜치에서 사라진 커밋이 그런 경우입니다. 해당 고아 객체를 fast-export 인수에 추가해야 합니다.

Forgejo 저장소를 제자리에서 바꾸기

Forgejo 서버에 접근할 수 있다면 저장소 파일을 직접 바꾸고 데이터베이스도 수정하는 방식으로 이전할 수 있습니다. 글쓴이는 이 방법이 위험한 해킹이라고 경고합니다. 기존 커밋을 정확한 객체 ID로 가리키는 참조는 깨질 수 있지만 태그 참조는 유지된다고 설명합니다.

서버에서 작업한다면 기존 저장소를 별도 이름으로 보존하고 새 저장소를 git init --bare --object-format sha256으로 만듭니다. 변환 결과를 확인한 뒤 기존 저장소를 지우고 새 저장소의 이름을 바꿉니다. 로컬에서 변환하는 경우에는 서버 저장소를 비운 뒤 SHA-256 bare 저장소를 만들고 git push --mirror로 내용을 올립니다.

이후 Forgejo 데이터베이스에서 저장소 내부 ID를 확인하고 repository 테이블의 object_format_name을 sha256으로 갱신합니다. 마지막으로 사이트 관리 메뉴에서 누락된 브랜치 동기화, 태그 동기화, 저장소 Git 훅 재동기화를 순서대로 실행합니다. 글쓴이는 이 과정으로 이슈, 위키, PR, 프로젝트를 유지한 채 저장소를 이전했다고 적습니다.

커밋 서명

git rebase --exec 'git commit --amend --no-edit --no-verify --gpg-sign' --root를 실행하면 모든 커밋을 다시 쓰면서 서명할 수 있습니다. 다만 커밋을 다시 쓰면 marks 파일로 설정한 서브모듈 관계가 깨지므로 서브모듈이 있는 저장소에는 적용하지 말아야 합니다. 글쓴이는 브랜치 끝의 커밋 하나만 서명해도 커밋 체인을 신뢰하는 데 충분하다고 설명하며, 이 옵션은 SSH 키를 이용한 커밋 서명에도 작동한다고 덧붙입니다.

Lobsters 반응

  • @jbe_ — 서브모듈 호환성 문제는 몰랐는데 알아두면 좋겠네요. 서브모듈이 들어 있는 프로젝트가 하나뿐이니, 그 서브모듈 프로젝트도 언젠가 변환되면 함께 바꾸면 되겠네요.

원문: 개인 기술 블로그 / 번역·요약: Trawling