Skip to content

Latest commit

 

History

History
124 lines (106 loc) · 6.71 KB

File metadata and controls

124 lines (106 loc) · 6.71 KB

Mercurial

Из-за того что Mercurial и Git обладают похожей моделью ветвления, а также из-за того что Git несколько более гибок, перенос репозитория из Mercurial в Git довольно прост; можете использовать инструмент hg-fast-export, который можно найти здесь:

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

Первым делом нужно получить полную копию интересующего Mercurial репозитория:

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

Следующим шагом создадим файл соответствия авторов. Mercurial менее строг к данным об авторстве коммитов, так что придётся слегка навести порядок. Вот однострочный скрипт на bash, который генерирует заготовку:

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

Пройдёт несколько секунд, в зависимости от размера репозитория, и вы получите файл /tmp/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>

В примере выше, один и тот же человек (Боб) вносил изменения под пятью различными именами, лишь одно из которых правильное, а одно и вовсе не соответствует формату Git. hg-fast-export позволяет быстро исправить ситуацию, преобразовав каждую строку в правило: "<input>"="<output>", где <input> преобразуется в <output>. Строки <input> и <output> могут содержать экранированные последовательности, поддерживаемые кодировкой python string_escape. Если файл сопоставлений авторов коммитов не содержит соответствующего <input>, то значение будет передано Git без модификации. Если же все имена выглядят хорошо, этот файл и вовсе не потребуется. В нашем примере мы хотим чтобы файл выглядел так:

"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 задаёт файл с соответствиями между авторами. Скрипт пробегается по наборам изменений Mercurial и преобразует их в скрипт для fast-import в Git (мы поговорим об этом инструменте чуть позже). Процесс конвертации займёт некоторое время (хотя и намного меньше, чем при конвертации по сети), а мы пока можем наблюдать за подробным выводом в консоли:

$ /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

Вот, собственно, и всё. Все Mercurial теги были преобразованы в теги Git, а ветки и закладки — в ветки Git. Теперь можно отправить репозиторий на новый Git сервер:

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