Фото Markus Winkler on Unsplash
Недавно я работал над проектом миграции, который включал перенос нашей кодовой базы с SVN на GitHub. После нескольких проб и ошибок и долгих часов поиска в интернете лучших практик, мне наконец удалось разработать систему, которая не вызвала никаких слез во время процесса, и я подумал, что было бы неплохо поделиться ею с вами.
Я разбил процесс миграции на 4 простых шага:
- Подготовьте свое окружение
- Преобразовать SVN-репозиторий в локальный git-репозиторий
- Преобразуйте все большие файлы в объекты lfs (если необходимо)
- Выложите новый git-репозиторий на GitHub.
Подготовьте свое окружение
На локальной машине создайте папку GitMigration, в которой будет размещено ваше новое git-репозиторий: mkdir -p ~/GitMigration
В другой командной строке обновите SVN-репо, чтобы убедиться, что у вас есть последние ревизии. Также будет разумно сообщить вашей команде, что вы начинаете миграцию, и до завершения процесса миграции не будет разрешено отправлять в SVN больше никаких коммитов.
Как только это будет сделано, вам нужно будет создать файл authors.txt. В нем имена пользователей SVN будут сопоставлены с именами пользователей Git в следующем формате:
jdoe = John Doe <john.doe@gmail.com>
esmith = Emma Smith <emma.smith@gmail.com>
Если вы не хотите искать всех авторов в SVN вручную, вы можете извлечь данные из репозитория SVN с помощью следующей команды, только убедитесь, что конечный формат соответствует структуре, описанной выше:
svn log -q | awk -F '|' '/^r/ {gsub(/ /, "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors.txt
Преобразование SVN-репозитория в локальный git-репозиторий
Если вы хотите перенести только коммиты за определенный период времени, вам нужно будет найти номер ревизии в SVN-репозитории. Для этого выполните следующую команду в папке svn repo:
svn log -r {YYYY-DD-MM}:HEAD --limit 1
В папке GitMigration выполните следующую команду:
git svn clone <svn-repo>/<project> <git-repo-name> --authors-file=authors.txt -r <revision-number>:HEAD
Где <svn-repo> — URI SVN-репозитория, который вы хотите перенести, <project> — имя проекта, который вы хотите импортировать, и номер ревизии, с которой вы хотите перенести (если необходимо). <git-repo-name> — это имя каталога нового Git-репозитория. Этот процесс может занять некоторое время, в зависимости от размера коммитов SVN.
Теперь наступает время очистки, перемещения тегов и любых удаленных ссылок в локальные ветки. Чтобы переместить теги в соответствующие теги Git, выполните следующие действия в каталоге git-репозитория:
for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do git tag ${t/tags//} $t && git branch -D -r $t; done
Затем переместите все ссылки в разделе refs/remote и переведите их в локальные ветки
for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch $b refs/remotes/$b && git branch -D -r $b; done;
for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git branch -D $p; done;
Преобразуйте все большие файлы в объекты lfs
GitHub имеет ограничение на размер файла в 100 МБ, все, что превышает этот размер, будет отказано в размещении в GitHub. Именно здесь на помощь приходит Git Large File Storage (LFS). Git LFS заменяет все большие файлы текстовыми указателями внутри Git’а, а содержимое файлов хранится на удаленном сервере. Использование LFS имеет множество преимуществ, таких как
- Версионирование больших файлов
- Больше места в хранилище
- Более быстрое клонирование и выборка
- Тот же рабочий процесс Git
- Одинаковый контроль доступа и разрешения
Чтобы узнать, сколько файлов превышает лимит в 100 МБ, выполните следующую команду:
git lfs migrate info --everything --above=99MB
Это выведет информацию о различных типах файлов в вашем репозитории, которые превышают отметку 99 МБ (как показано ниже).
Чтобы преобразовать файлы в файловые объекты LFS, выполните следующую команду:
git lfs migrate import --everything --above=99MB
Это перепишет историю git-репозитория, содержащего все файлы размером более 99 МБ, и преобразует их в объекты LSF.
Поместите новый git-репозиторий на GitHub
Последним шагом будет добавление удаленного git-сервера и перенос изменений.
git remote add origin git@my-git-server:myrepository.git
git push origin --all;
git push origin --tags;
Вот и все! Поздравляем, вы перенесли ваш SVN-репозиторий в Git. Следующий шаг — сообщить вашей команде, что миграция завершена, и предоставить им доступ к новому удаленному git-серверу.