Перенос SVN-репозитария в git 22 июля 09
Душа просит git, а старые репозитарии остались под SVN. Что же делать? Простое решение – закоммитить текущее состояние проекта в гит – нас явно не устраивает, хочется ведь и историю сохранить, и ветки перетянуть. Приступим.
Фанбои заявляют, что переход с SVN на гит проходит безболезненно. Ну и пусть себе заявляют, мы-то знаем, что все зависит от сложности репозитария, того, какие возможности SVN использовались, и, также, наличия пустых папок. Мне нужно было переносить ветки и svn:ignore. (И пустые папки, конечно.)
Устанавливаем git-svn
Это, собственно, часть гита, так что достать ее можно без проблем. Например, на Ubuntu это делается так:
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} = EMAIL"; done
Результат работы скрипта сохраняем куда-нибудь в ~/svn-authors, не забывая заполнить реальные адреса.
Клонируем репозитарий
Указываем URL репозитария, а НЕ транка!
git svn clone -s --authors-file=/home/user/svn-authors svn://repo/location .
-s– понимать стандартные папки SVN (trunk, branches, tags)--authors-file=...– использовать файл с авторами с предыдущего шага
Теперь имеем git-репозитарий с содержимым SVN – но пока еще не полный. (Без пустых папок, ну ты понял.)
Разбираемся с ветками
Вытягиваем удаленные ветки в локальный репозитарий.
git fetch . refs/remotes/*:refs/heads/*
Что с пустыми папками?
А, это. Ну в общем git хранит только информацию о файлах. О папках он вообще ничего не знает. Поэтому папку без файлов закоммитить не удастся, и, соответственно, при переносе из SVN они все теряются (drama). Придется создавать их ручками.
Кстати, git-svn сообщает о несозданных папках в лог, который находится в .git/svn/branch/unhandled.log.
Вытягиваем svn:ignore
Для каждой ветки:
git checkout branch git svn create-ignore git commit -a -m "imported svn:ignore"
Само собой, при попытке создать .gitignore для несуществующей (а ранее пустой) папки скрипт выкинет ошибку. Пусть это будет для тебя знаком, что такую папку надо создать.
Вычищаем из репозитария упоминания об SVN
Наконец, мы готовы отдать проект в руки git. Разумеется, репозитарий SVN как был, так и остался, поскольку работаем мы с локальной копией. Но в дальнейшем планируется использовать только git, можно убрать из репозитария данные git-svn.
Удаляем все svn-ветки – те, которые git считает удаленными (remote). Кроме того, удаляем ту ветку, которая является мастером; практика показывает, что это самая свежая ветка. Еще можно удалить мастер, а потом переименовать самую свежую ветку в мастер.
for branch in `git branch -r`; do git branch -rd $branch; done git branch -d trunk
Последний штрих: удаляем метаданные git-svn
git config --remove-section svn-remote.svn rm -Rf .git/svn/
Готово! Имеем полностью перенесенный под git репозитарий. Можно пользоваться им сразу, а можно залить на github или на свой сервер в gitosis (о нем я тоже постараюсь рассказать).

Подписаться на RSS

Комментарии
>>а можно залить на github
github сам все импортирует с историей вместе.
А что делать, если фирма не хочет (пока) переходить на гит, но локально уже гит на реальном проекте попробовать хочется? Какие-то подобные статьи имеются?
Если в svn использовались svn:externals, то все так просто не пройдет, ибо это не поддерживается git-svn и собственно самим git тоже.
мое приключение с гит имело целью использовать его для работы с центральным репозиторием.
Первый облом – время сетевого импорта.
Второй облом – он не осилил импорт из локального репо полученного svnsync’ом (svn 1.6, гит июльский ). 3й облом – черепаший ui отказывался выполнять команды с центральным репозиторием (версия была свежая). Из командной строки fetch шел, но указать ему ключик от cygwin ssh мне не удалось (это к слову про еще один кривой юникс под виндой).
так что пока не впечатлило.
зы идея выкладывания корпоративного репо на гитхаб жжот напалмом.
Сетевой импорт вытягивает содержимое всех ревизий из SVN, разумеется, он занимает долгое время. Я бы советовал вытягивать его прямо на сервере, так git-svn не придется таскать по сети столько данных.
Черепаший ui – это tortoisegit? Да, он еще очень сырой.
Не знаю, как с гитом под windows, говорят, что плохо, но с другой стороны рядом со мной сидит человек, он замечательно работает c msysgit с авторизацией по ключу.
Спасибо, помогло. Самому было трудно разобраться…
а что делать, если заказчик ну никак не хочет слышать про гит – вообще падает в обморок от этого слова :)
делать так:
$ git init
$ echo .svn > .gitignore # Git будет игнорить папки SVN
$ git add .
$ git commit -m «git init»
$ svn propset svn:ignore .git # property ’svn:ignore’ set on ‘.’
$ svn commit -m «ignoring git folder»
$ git add .
$ git commit -m «commit for deploy to heroku»
И работать с гитом локально, а заказчик будет видеть прежний svn-репозиторий
Скажите, правильно ли я понимаю, что для того, чтобы иметь основной, «центральный», репозиторий где-то на удаленном хосте, доступном через SSH, нужно, чтобы на этом хосте был установлен Git?
Для меня эта необходимость до сих пор неочевидна. Почему для того, чтобы удаленно пользоваться файлами (по сути ведь репозиторий — это файлы), нужно дополнительное серверное ПО?
Можно ли как-то вынести центральный репозиторий на shared-хостинг, на котором нет возможности устанавливать дополнительное ПО?
Если кратко – Git не умеет работать с удаленным репозитарием как с файлами. Это даже описано в Git FAQ.
Думаю, разработчики не спешат устранять эту проблему, поскольку можно просто смонтировать репозитарий по sshfs (точнее, смонтировать каталог по sshfs и выкладывать туда репозитарий).
git-svn вполне работоспособная альтернатива тупому svn