База знаний
Перенос репозитария из SVN в git

Не такое уж это и простое дело…

Говорят, перенос можно автоматизировать. Даже скрипты пишут. Я им пока не верю, а перенос делаю под контролем.

Устанавливаем git-svn

Это, собственно, часть гита, так что достать ее можно без проблем

sudo apt-get install git-svn

Собираем авторов коммитов

Дело в том, что в SVN пользователи – это идентификаторы, а в git – email-ы.

Выполняем такой вот скрипт в папке SVN-репозитария:

#!/usr/bin/env bash
authors=$(svn log -q | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { print $2 }' | sort | uniq)
for author in ${authors}; do
  echo "${author} = NAME <USER@DOMAIN>";
done

Результат работы скрипта сохраняем куда-нибудь в ~/svn-authors, не забывая заполнить реальные адреса.

Клонируем репозитарий

Указываем URL репозитария, а НЕ транка!

git svn clone -s --authors-file=/home/user/svn-authors svn://repo/location .

Метаданные нам нужны, без них не будут работать команды типа git svn create-ignore

После этого имеем гит-репозитарий с содержимым SVN - но пока еще не полный.

Разбираемся с ветками

Для начала вытягиваем удаленные ветки в локальный репозитарий.

git fetch . refs/remotes/*:refs/heads/*

Че делать с пустыми папками?

Пустых папок из SVN в репозитарии нет. (ну как с этим бороться?)

Бета-версия Ruby-скрипта, который занимается обработкой логов git svn и созданием недостающих папок, тут: Скрипт для переноса пустых папок из SVN в git

Кроме того, можно, забив на историю, просто найти все пустые директории в текущем репозитарии SVN и закоммитить их в гит.

Затягиваем svn:ignore

Для каждой ветки:

git checkout branch
git svn create-ignore
git commit -a -m "imported svn:ignore" 

Само собой, при попытке создать .gitignore для несуществующей (а ранее пустой) папки скрипт выкинет ошибку.

Вычищаем из репозитария упоминания об SVN

Удаляем все удаленные (гы) ветки. Кроме того, удаляем ту ветку, которая является мастером; практика показывает, что это самая свежая ветка. Возможно, правильнее удалить мастер, а потом переименовать транк в мастер (надо проверить)

for branch in `git branch -r`; do git branch -rd $branch; done
git branch -d trunk

Наконец, удаляем метаданные SVN

git config --remove-section svn-remote.svn
rm -Rf .git/svn/