Как перенести репозиторий SVN с историей в новый репозиторий Git? - PullRequest
1459 голосов
/ 17 сентября 2008

Я прочитал руководство по Git, FAQ, Git - SVN и т.д., и все они объясняют то и это, но нигде не найти такой простой инструкции как:

Репозиторий SVN в: svn://myserver/path/to/svn/repos

Git репозиторий в: git://myserver/path/to/git/repos

git-do-the-magic-svn-import-with-history \
svn://myserver/path/to/svn/repos \
git://myserver/path/to/git/repos

Я не ожидаю, что это будет так просто, и я не ожидаю, что это будет одна команда. Но я ожидаю, что он не попытается что-либо объяснить - просто сказать, какие шаги предпринять в этом примере.

Ответы [ 32 ]

1516 голосов
/ 19 октября 2010

Создайте файл пользователей (т.е. users.txt) для сопоставления пользователей SVN с Git:

user1 = First Last Name <email@address.com>
user2 = First Last Name <email@address.com>
...

Вы можете использовать этот однострочный шаблон для создания шаблона из вашего существующего хранилища SVN:

svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt

SVN остановится, если обнаружит отсутствующего пользователя SVN, которого нет в файле. Но после этого вы можете обновить файл и забрать, где вы остановились.

Теперь извлеките данные SVN из хранилища:

git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp

Эта команда создаст новый репозиторий Git в dest_dir-tmp и начнет извлекать SVN-репозиторий. Обратите внимание, что флаг "--stdlayout" подразумевает, что у вас есть общая структура SVN "trunk /, branch /, tags /". Если ваш макет отличается, ознакомьтесь с параметрами --tags, --branches, --trunk (в общем случае git svn help).

Разрешены все распространенные протоколы: svn://, http://, https://. URL должен быть нацелен на базовый репозиторий, что-то вроде http://svn.mycompany.com/myrepo/repository. Это должно , а не , включая /trunk, /tag или /branches.

Обратите внимание, что после выполнения этой команды очень часто выглядит, что операция «зависла / зависла», и вполне нормально, что она может застрять на долгое время после инициализации нового репозитория. В конце концов вы увидите сообщения журнала, которые указывают, что он мигрирует.

Также обратите внимание, что если вы опустите флаг --no-metadata, Git добавит информацию о соответствующей ревизии SVN к сообщению фиксации (т. Е. git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>)

Если имя пользователя не найдено, обновите файл users.txt, затем:

cd dest_dir-tmp
git svn fetch

Возможно, вам придется повторить эту последнюю команду несколько раз, если у вас большой проект, пока не будут получены все коммиты Subversion:

git svn fetch

После завершения Git извлечет SVN trunk в новую ветку. Любые другие филиалы настроены как удаленные. Вы можете просмотреть другие ветви SVN с помощью:

git branch -r

Если вы хотите сохранить другие удаленные ветки в своем хранилище, вам нужно создать локальную ветку для каждой из них вручную. (Пропустите магистраль / мастера.) Если вы этого не сделаете, ветви не будут клонированы на последнем шаге.

git checkout -b local_branch remote_branch
# It's OK if local_branch and remote_branch are the same name

Теги импортируются как ветки. Вы должны создать локальную ветку, создать тег и удалить ветку, чтобы они были в Git как теги. Чтобы сделать это с тегом "v1":

git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1

Клонируйте свой репозиторий GIT-SVN в чистый репозиторий Git:

git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir

Локальные ветви, которые вы создали ранее из удаленных ветвей, будут скопированы только как удаленные ветви в новый клонированный репозиторий. (Пропустите магистраль / мастера.) Для каждой ветви, которую вы хотите сохранить:

git checkout -b local_branch origin/remote_branch

Наконец, удалите пульт из вашего чистого Git-репозитория, который указывает на удаленный временный репозиторий:

git remote rm origin
515 голосов
/ 17 сентября 2008

Magic:

$ git svn clone http://svn/repo/here/trunk

Git и SVN работают очень по-разному. Вам нужно изучить Git, и если вы хотите отслеживать изменения из SVN upstream, вы должны изучить git-svn. Справочная страница git-svn имеет хороший раздел примеров:

$ git svn --help
185 голосов
/ 17 сентября 2008

Чистая миграция вашего репозитория Subversion в репозиторий Git . Сначала вы должны создать файл, который сопоставляет имена авторов ваших коммитов Subversion с коммиттерами Git, скажем ~/authors.txt:

jmaddox = Jon Maddox <jon@gmail.com>
bigpappa = Brian Biggs <bigpappa@gmail.com>

Затем вы можете загрузить данные Subversion в Git-репозиторий:

mkdir repo && cd repo
git svn init http://subversion/repo --no-metadata
git config svn.authorsfile ~/authors.txt
git svn fetch

Если вы работаете на Mac, вы можете получить git-svn от MacPorts, установив git-core +svn.

Если ваш репозиторий subversion находится на той же машине, что и желаемый репозиторий git, тогда вы можете использовать этот синтаксис для этапа инициализации, в противном случае все то же самое:

git svn init file:///home/user/repoName --no-metadata
69 голосов
/ 01 февраля 2011

Я использовал svn2git скрипт и работает как шарм.

57 голосов
/ 17 сентября 2008

Я предлагаю освоиться с Git, прежде чем пытаться использовать git-svn постоянно, т.е. сохранять SVN в качестве централизованного репо и использовать Git локально.

Однако, для простой миграции со всей историей, вот несколько простых шагов:

Инициализация локального репо:

mkdir project
cd project
git svn init http://svn.url

Отметьте, как далеко вы хотите начать импорт ревизий:

git svn fetch -r42

(или просто "git svn fetch" для всех оборотов)

На самом деле получить все с тех пор:

git svn rebase

Вы можете проверить результат импорта с помощью Gitk. Я не уверен, что это работает в Windows, работает в OSX и Linux:

gitk

Если у вас есть SVN-репозиторий, клонированный локально, вы можете перенести его в централизованное Git-репо для упрощения совместной работы.

Сначала создайте пустое удаленное репо (может быть, на GitHub ?):

git remote add origin git@github.com:user/project-name.git

Затем, при необходимости, синхронизируйте основную ветку, чтобы операция извлечения автоматически объединяла удаленный мастер с вашим локальным мастером, когда оба содержат новый материал:

git config branch.master.remote origin
git config branch.master.merge refs/heads/master

После этого вас может заинтересовать мой собственный инструмент git_remote_branch, который помогает работать с удаленными ветками:

Первый пояснительный пост: " Git удаленных веток "

Продолжение самой последней версии: " Время работать с git_remote_branch "

30 голосов
/ 25 ноября 2011

Существует новое решение для плавного перехода от Subversion к Git (или для одновременного использования обоих): SubGit .

Я работаю над этим проектом сам. Мы используем SubGit в наших репозиториях - некоторые из моих товарищей по команде используют Git и некоторые Subversion, и пока он работает очень хорошо.

Чтобы перейти с Subversion на Git с SubGit, вам нужно выполнить:

$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL 

После этого вы получите Git-репозиторий в svn_repos / .git и сможете его клонировать, или просто продолжите использовать Subversion и этот новый Git-репозиторий вместе: SubGit обеспечит синхронизацию обоих.

Если в вашем хранилище Subversion есть несколько проектов, в каталоге svn_repos / git будет создано несколько хранилищ Git. Чтобы настроить перевод перед запуском, выполните следующие действия:

$ subgit configure svn_repos
$ edit svn_repos/conf/subgit.conf (change mapping, add authors mapping, etc)
$ subgit install svn_repos

С SubGit вы можете перейти на чистый Git (не git-svn) и начать использовать его, сохраняя при этом Subversion столько времени, сколько вам нужно (например, для уже настроенных инструментов сборки). 1017 *

Надеюсь, это поможет!

17 голосов
/ 17 сентября 2008

См. Официальную страницу git-svn . В частности, посмотрите в разделе «Основные примеры»:

Отслеживание и участие во всем управляемом Subversion проекте (завершено с стволом, метками и ветками):

# Clone a repo (like git clone):
    git svn clone http://svn.foo.org/project -T trunk -b branches -t tags
13 голосов
/ 12 февраля 2011
13 голосов
/ 06 февраля 2015

SubGit (против Синего экрана смерти)

subgit import --svn-url url://svn.serv/Bla/Bla  directory/path/Local.git.Repo

Это все.

+ Для обновления из SVN, Git-репозиторий, созданный первой командой.

subgit import  directory/path/Local.git.Repo

Я использовал способ мгновенной миграции на Git для огромного хранилища.
Конечно, вам нужна подготовка.
Но вы можете вообще не останавливать процесс разработки.

Вот мой путь.

Мое решение выглядит так:

  • Перенос SVN в хранилище Git
  • Обновите Git-репозиторий непосредственно перед переключением команды на .

Миграция занимает много времени для большого хранилища SVN.
Но обновление завершенной миграции всего за несколько секунд.

Конечно, я использую SubGit , мама. Git-SVN делает меня Синий экран смерти . Просто постоянно. И git-svn надоел мне фатальной ошибкой Git " filename too long ".

ШАГИ

1. Скачать SubGit

2. Подготовка команд переноса и обновления.

Допустим, мы делаем это для Windows (портирование на Linux тривиально).
В каталоге установки SubGit bin (subgit-2.X.X \ bin) создайте два файла .bat.

Содержимое файла / команды для миграции:

start    subgit import --svn-url url://svn.serv/Bla/Bla  directory/path/Local.git.Repo

Команда «пуск» здесь необязательна (Windows). Это позволит увидеть ошибки при запуске и оставить оболочку открытой после завершения SubGit.

Вы можете добавить сюда дополнительные параметры, аналогичные git-svn . Я использую только - домен по умолчанию myCompanyDomain.com , чтобы исправить домен адреса электронной почты авторов SVN.
У меня есть стандартная структура репозитория SVN (ствол / ветви / теги), и у нас не было проблем с «отображением авторов». Так что я больше ничего не делаю.

(Если вы хотите перенести теги, такие как ветви, или ваш SVN имеет несколько папок веток / тегов, вы можете использовать более подробный SubGit подход )

Совет 1 : Используйте --minimal-revision YourSvnRevNumber, чтобы быстро увидеть, как все происходит (какая-то отладка). Особенно полезно видеть разрешенные имена авторов или электронные письма.
Или ограничить глубину истории миграции.

Совет 2 : Миграция может быть прервана ( Ctrl + C ) и восстановлена ​​путем запуска следующей команды / файла обновления.
Я не советую делать это для больших репозиториев. Я получил "Недостаточно памяти Java + Windows исключение".

Совет 3 : Лучше создать копию вашего репозитория результатов поиска.

Содержимое файла / команды для обновления:

start    subgit import  directory/path/Local.git.Repo

Вы можете запускать его любое количество раз, когда хотите получить последние коммиты команды в свой репозиторий Git.

Внимание! Не прикасайтесь к своему голому репозиторию (например, создание веток).
Вы получите следующую фатальную ошибку:

Неустранимая ошибка: не синхронизированы и не могут быть синхронизированы ... Перевод версий Subversion в коммиты Git ...

3. Запустить первую команду / файл. Это займет много времени для большого хранилища. 30 часов для моего скромного хранилища.

Это все.
Вы можете в любое время обновить Git-репозиторий из SVN любое количество раз, запустив второй файл / команду. И до перехода вашей команды разработчиков на Git.
Это займет всего несколько секунд.



Есть еще одна полезная задача.

Перенесите ваш локальный репозиторий Git в удаленный репозиторий Git

Это твой случай? Давайте продолжим.

  1. Настройка пультов

Пробег:

$ git remote add origin url://your/repo.git
  1. Подготовка к первоначальной отправке вашего огромного локального репозитория Git в удаленный репозиторий

По умолчанию ваш Git не может отправлять большие куски. смертельно: удаленный конец неожиданно зависает

Давай побежим за этим:

git config --global http.postBuffer 1073741824

524288000 - 500 МБ1073741824 - 1 ГБ и т. Д.

Исправьте локальные проблемы с сертификатом . Если ваш git-сервер использует испорченный сертификат.

Я отключил сертификаты .

Кроме того, ваш Git-сервер может иметь ограничения количества запросов, которые необходимо исправить .

  1. Отправка всей миграции в удаленный Git-репозиторий команды.

Запуск с локальным Git:

git push origin --mirror

( git push origin '*: *' для старых версий Git)

Если вы получаете следующее: ошибка: невозможно создать git: нет такого файла или каталога ... Для меня полное восстановление моего хранилища решает эту ошибку (30 часов). Вы можете попробовать следующие команды

git push origin --all
git push origin --tags

Или попробуйте переустановить Git ( для меня бесполезно ). Или вы можете создавать ветви из всех своих тегов и нажимать их. Или, или, или ...

9 голосов
/ 20 марта 2015

reposurgeon

Для сложных случаев, репохирург Eric S. Raymond является инструментом выбора. В дополнение к SVN он поддерживает многие другие системы контроля версий в формате fast-export, а также CVS . Автор сообщает об успешных конверсиях древних репозиториев, таких как Emacs и FreeBSD .

Инструмент, по-видимому, нацелен почти на идеальное преобразование (например, преобразование свойств svn:ignore SVN в .gitignore файлы) даже для сложных макетов репозитория с длинной историей. Во многих случаях другие инструменты могут быть проще в использовании.

Прежде чем углубляться в документацию командной строки reposurgeon, обязательно прочитайте превосходное руководство по миграции DVCS , которое шаг за шагом описывает процесс преобразования.

...