svn2git 을 사용하여 svn 저장소를 git(gitlab) 으로 이관하기.


TODO


사전 준비

ruby 와 패키지 설치

ruby 로 개발되었으므로 루비 인터프리터와 gem 설치가 필요

  1. ruby 패키지 설치 (ruby 2.0, 2.1 을 rpmbuild 해서 yum 으로 설치하기)
  2. svn2git 설치

    gem install svn2git
    CODE

이관

  1. git 으로 이관할 프로젝트 디렉터리 생성(Ex: from-svn)
  2. 생성한 프로젝트 디렉터리로 이동

    cd from-svn
    CODE
  3. svn 프로젝트의 URL 확인 (Ex: https://svn.example.com/svn/myproject)
  4. 작업자 정보 이관을 위한 authors 파일 생성 (아래의 Authros 항목 참고)

    mkdir ~/.svn2git
    vi ~/.svn2git/authors
    CODE
  5. svn2git 명령어로 svn 프로젝트를 git 으로 이관  (하단의 사용법과 옵션 항목 참고)

    svn2git https://svn.example.com/svn/myproject
    CODE
  6. 생성한 로컬 git 프로젝트를 remote 에 푸시

    git remote add origin git@gitlab.example.com:group/myproject.git
    git push -u origin master
    CODE
  7. svn 에서 이관한 tags 가 있을 경우 모든 tags 도 푸시

    git push --tags origin
    CODE
  8. 모든 브랜치 푸시

    git push --all origin
    CODE


사용법 및 옵션

svn2git SVN_URL [options]


옵션

option의미기본값
--trunk TRUNK_PATHtrunk 디렉터리 이름trunk
 --branches BRANCHES_PATH branch 디렉터리 이름branches
--tags TAGS_PATHtags 이름tags
--rootistrunksvn root 가 trunk 이고 tags, branches 가 따로 없는 경우(trunk 만 있는 경우가 자주 있음)
--notrunktrunk import 안 함
--nobranchesbranches import 안 함
--revision START_REV[:END_REV]특정 리비전부터 이관 시작. 종료 리비전이 필요할 경우 : 뒤에 기술. 다음은 30 부터 215까지 이관 --revision 30:215
--notags  tags import 안 함
--exclude REGEX제외할 파일이 있을 경우 Perl 의 정규식 패턴으로 기술하면 git 에 포함되지 않음. --exclude 옵션은 여러 번 기술 가능
--authors AUTHORS_FILE svn-to-git authors mapping 파일의 경로~/.svn2git/authors
-v, --verbose이관시 자세한 정보 출력(디버깅으로 유용)


Authors 파일

git 으로 이관중 수정자의 id 도 git 에 등록된 id 로 변환할 수 있도록 ~/.svn2git/authors 파일을 만들고 다음과 같이 매핑 파일을 작성

좌측에는 svn 의 id 를 적고 우측은 git 의 계정 정보를 기록 (이름과 email 을 적어야 에러가 발생하지 않음)

jcoglan = James Coglan <jcoglan@never-you-mind.com>
stnick = Santa Claus <nicholas@lapland.com>


svn 커밋 id 알아내기

svn 에서 커밋한 작업자 id 목록을 미리 알아내어 authors 에 추가하여 이관 도중에 없는 id라고 중지하지 않는다.


  1. svn 프로젝트를 체크아웃 받는다. 

    svn co http://svn.myhost.com/myproj myproj
    CODE
  2. 체크아웃 받은 디렉터리로 이동한다.

    cd myproj
    CODE
  3. 다음 스크립트를 구동하면 커밋한 id 내역을 출력한다.

    svn log|grep "^r[0-9]"|awk -F\| '{print $2}'| sed -e 's/^[ \t]*//'|sort|uniq
    CODE
  4. 출력된 id 를 authors 파일에 추가한다.

이관

svn 저장소가 표준 구성(trunk, branches, tags) 일 경우

으로 되어 있을 경우 다음과 같이 svn 저장소의 URL 을 입력

svn2git http://svn.example.com/path/to/repo
CODE


암호가 있을 경우

yes 명령어뒤에 svn 로그인 암호를 넣고 명령어 실행

yes svn-password | svn2git --username lesstif http://svn.example.com/path/to/repo
CODE


표준 구성이 아니고 trunk 와 tags 만 있고 폴더 이름이 다를 경우 

svn2git http://svn.example.com/path/to/repo --trunk dev --tags rel --nobranches
CODE


표준 구성이 아니지만 trunk, tags, branches 가 각각 다른 경로에 있을 경우

project 명이 my-proj 이고 trunk, tag, branch 가 다른 레벨의 경로에 있을 경우 

  • parent : /path/to/repo
  • trunk: /path/to/repo/trunk/my-proj
  • tags: /path/to/repo/tags/my-proj
  • branches: /path/to/repo/branches/my-proj

다음과 같이 각각 경로를 직접 지정

svn2git http://svn.example.com/path/to/repo --trunk trunk/my-proj --tags tags/my-proj --branches branches/my-proj
CODE



root 디렉터리에 바로 소스가 있을 경우(root 가 trunk)

svn2git http://svn.example.com/path/to/repo --rootistrunk
CODE

위 옵션을 사용하면 다음과 같은 에러가 발생하고 제대로 동작하지 않음

 E: 'https:/my.svnserver.com/svn/easy/' is not a complete URL  and a separate URL is not specified  command failed:

다음과 같은 트릭 사용

svn2git http://svn.example.com/path/to/repo --trunk / --nobranches --notags
CODE


doc 디렉터리와 vim 의 백업 파일은 제외

--exclude 옵션은 제대로 동작하지 않는 것 같음. 확인 필요

svn2git http://svn.example.com/path/to/repo --exclude doc --exclude '.*~$'
CODE