버전 관리 시스템을 SVN에서 Git으로 전환할 때, 과거 커밋 이력을 보존하는 것이 핵심 과제입니다. Git은 git-svn 도구를 통해 SVN의 전체 히스토리를 Git 형식으로 변환할 수 있으며, 이를 통해 파일 변경 추적과 이전 버전 비교 기능을 그대로 유지할 수 있습니다.
환경 구성
먼저 마이그레이션에 필요한 도구를 설치합니다. CentOS/RHEL 계열에서는 다음 명령으로 git-svn 패키지를 설치할 수 있습니다:
yum install -y git-svn
작성자 매핑 파일 생성
SVN의 계정 정보를 GitLab 사용자와 연결하기 위한 매핑 파일을 준비해야 합니다. SVN 저장소에서 고유한 작성자 목록을 추출하여 authors.txt 파일을 생성합니다:
svn log svn://192.168.1.203 -q | \
awk -F '|' '/^r/ {gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2" = "$2" <"$2"@company.com>"}' | \
sort -u > authors.txt
생성된 파일의 내용을 수동으로 편집하여 GitLab 계정 형식에 맞게 변환합니다:
zhangsan = Zhang San
lisi = Li Si
wangwu = Wang Wu
SVN 저장소를 Git으로 변환
git svn clone 명령을 사용하여 SVN 저장소를 로컬 Git 저장소로 변환합니다. 브랜치와 태그 구조를 명시적으로 지정하여 올바른 Git 레이아웃을 확보합니다:
git svn clone svn://192.168.1.203/XinglvTmc/ \
--no-metadata \
--authors-file=authors.txt \
--trunk=trunk \
--tags=tags \
--branches=branches \
XinglvTmc
--no-metadata 옵션은 SVN 리비전 번호를 Git 커밋 메시지에 포함하지 않아 히스토리를 깔끔하게 유지합니다.
브랜치 및 태그 정리
변환 후 SVN의 원격 참조를 Git 표준 형식으로 재구성해야 합니다. 먼저 태그 참조를 정리합니다:
cd XinglvTmc
mkdir -p .git/refs/tags
cp -Rf .git/refs/remotes/origin/tags/* .git/refs/tags/ 2>/dev/null || true
rm -Rf .git/refs/remotes/origin/tags
다음으로 브랜치 참조를 로컬 브랜치로 변환합니다:
for ref in .git/refs/remotes/origin/*; do
branch_name=$(basename "$ref")
if [ "$branch_name" != "HEAD" ]; then
cp -f "$ref" ".git/refs/heads/$branch_name"
fi
done
rm -Rf .git/refs/remotes
GitLab 원격 저장소 연결
변환된 저장소를 GitLab에 연결합니다. 기존 원격 설정이 있는 경우 먼저 제거합니다:
# 기존 원격 제거 (필요시)
git remote remove origin 2>/dev/null || true
# GitLab 원격 추가
git remote add origin http://192.168.1.203/root/xinglvtmc.git
모든 참조 푸시
브랜치와 태그를 GitLab에 일괄 업로드합니다:
# 모든 브랜치 푸시
git push origin --all
# 모든 태그 푸시
git push origin --tags
일반적인 문제 해결
원격 저장소 중복 오류:
fatal: remote origin already exists.
해결 방법:
git remote rm origin
git remote add origin <새로운-저장소-URL>
빈 응답 오류:
fatal: unable to access '...': Empty reply from server
로컬 변경사항을 커밋하지 않고 푸시하려 할 때 발생합니다. 반드시 git commit 후 git push를 실행하세요.
대용량 저장소 처리
오래된 SVN 저장소가 수 GB에 달하는 경우, git-svn의 단일 스레드 처리 방식으로 인해 마이그레이션이 매우 오래 걸릴 수 있습니다. 이 경우 다음 전략을 고려하세요:
- 히스토리를 특정 시점부터만 마이그레이션:
-r HEAD:10000형식으로 리비전 범위 지정 - 대용량 바이너리 파일은 Git LFS로 전환 고려
- 병렬 처리가 가능한
svn-all-fast-export등 대안 도구 검토