Skip to content

Latest commit

 

History

History
162 lines (144 loc) · 8.36 KB

File metadata and controls

162 lines (144 loc) · 8.36 KB

Mercurial

Mercurial과 Git의 버전은 개념이 아주 비슷하다. 그리고 사실은 Git이 좀 더 유연해서 Mercurial 프로젝트를 Git 프로젝트로 변환하는 작업은 아주 쉽다. "hg-fast-export" 라는 툴을 사용하며 아래와 같이 내려 받는다.

$ git clone https://github.com/frej/fast-export.git

우선 처음 할 일은 변환할 Mercurial 저장소 전체를 Clone 하는 일이다.

$ hg clone <remote repo URL> /tmp/hg-repo

변환에 사용할 저자 매핑 파일을 하나 작성한다. Mercurial의 Changeset에 적는 저자 정보의 형식은 Git에 비해 자유롭기 때문에 한 번 정리하는 것이 좋다. 저자 매핑 파일은 아래와 같은 한 라인으로 된 bash 명령을 사용한다.

$ cd /tmp/hg-repo
$ hg log | grep user: | sort | uniq | sed 's/user: *//' > ../authors

프로젝트 크기에 따라 다르겠지만 위 명령을 실행하면 아래와 같은 매핑 파일이 생성된다.

bob
bob@localhost
bob <bob@company.com>
bob jones <bob <AT> company <DOT> com>
Bob Jones <bob@company.com>
Joe Smith <joe@company.com>

예제를 보면 Bob 이라는 한 사람은 적어도 네 가지의 다른 저자 정보를 Changeset에 기록했다. 어떤 정보는 Git에서 쓸 수 있지만 어떤 정보는 Git에서 쓰기에 적절치 않다. Hg-fast-export 에서는 "<input>"="<output>" 규칙을 사용하여 <input><output> 에 매핑할 수 있다. <input><output> 문자열에는 Python의 string_escape 인코딩을 사용하는 이스케이프 문자열을 사용할 수 있다. <input> 에서 찾을 수 없는 문자열을 만나는 경우 Git은 그 저자 내용을 변경하지 않고 그대로 사용한다. 물론 저자 정보가 모든 Changeset에 제대로 입력돼있다면 이런 변환 과정을 거치지 않아도 된다. 예제에서는 아래와 같이 저자 정보를 수정한다.

"bob"="Bob Jones <bob@company.com>"
"bob@localhost"="Bob Jones <bob@company.com>"
"bob <bob@company.com>"="Bob Jones <bob@company.com>"
"bob jones <bob <AT> company <DOT> com>"="Bob Jones <bob@company.com>"

이와 같은 매핑 규칙을 Mercurial에서 사용하고 있지만 Git에서 사용하기 불가능한 브랜치나 태그이름에 대해서도 같은 방식으로 적용할 수 있다.

다음은 Git 저장소를 새로 만들고 변환 스크립트를 실행한다.

$ git init /tmp/converted
$ cd /tmp/converted
$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors

-r 옵션으로 변환할 Mercurial 저장소의 위치를 지정하고 -A 옵션으로 저자 매핑 파일의 위치를 지정한다. (브랜치는 -B, 태그는 -T) hg-fast-export.sh 스크립트는 Mercurial Changeset을 분석하여 Git의 "fast-import"에(곧 자세히 설명한다) 쓰는 스크립트를 생성한다. 명령을 실행하면 아래와 같이 보여준다.

$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
Loaded 4 authors
master: Exporting full revision 1/22208 with 13/0/0 added/changed/removed files
master: Exporting simple delta revision 2/22208 with 1/1/0 added/changed/removed files
master: Exporting simple delta revision 3/22208 with 0/1/0 added/changed/removed files
[…]
master: Exporting simple delta revision 22206/22208 with 0/4/0 added/changed/removed files
master: Exporting simple delta revision 22207/22208 with 0/2/0 added/changed/removed files
master: Exporting thorough delta revision 22208/22208 with 3/213/0 added/changed/removed files
Exporting tag [0.4c] at [hg r9] [git :10]
Exporting tag [0.4d] at [hg r16] [git :17]
[…]
Exporting tag [3.1-rc] at [hg r21926] [git :21927]
Exporting tag [3.1] at [hg r21973] [git :21974]
Issued 22315 commands
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:     120000
Total objects:       115032 (    208171 duplicates                  )
      blobs  :        40504 (    205320 duplicates      26117 deltas of      39602 attempts)
      trees  :        52320 (      2851 duplicates      47467 deltas of      47599 attempts)
      commits:        22208 (         0 duplicates          0 deltas of          0 attempts)
      tags   :            0 (         0 duplicates          0 deltas of          0 attempts)
Total branches:         109 (         2 loads     )
      marks:        1048576 (     22208 unique    )
      atoms:           1952
Memory total:          7860 KiB
       pools:          2235 KiB
     objects:          5625 KiB
---------------------------------------------------------------------
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =      90430
pack_report: pack_mmap_calls          =      46771
pack_report: pack_open_windows        =          1 /          1
pack_report: pack_mapped              =  340852700 /  340852700
---------------------------------------------------------------------

$ git shortlog -sn
   369  Bob Jones
   365  Joe Smith

상당히 많은 Changeset을 Git 커밋으로 변환했다. Mercurial 저장소의 모든 태그는 Git Tag로 변환되고 브랜치, 북마크은 Git 브랜치로 변환된다. 이제 서버 저장소를 만들고 Push 하면 된다.

$ git remote add origin git@my-git-server:myrepository.git
$ git push origin --all