Перенос сложной иерархии ветвей из SVN в Git

#svn #git

#svn #git

Вопрос:

Как можно перенести большой репозиторий SVN (несколько GBS) с сотнями ветвей в репозиторий Git? Не ищу, чтобы они работали бок о бок, просто способ избавиться от SVN.

Из некоторых экспериментов, которые я провел с git svn , неясно, как указать сложную иерархию ветвей. Особенно когда ветви часто удаляются в SVN…

Вот пример иерархии, о которой я говорю:

 trunk/
tags/
vendors/boost/
branches/ProjectA/
branches/ProjectA/MajorVersion/
branches/ProjectA/MajorVersion/MinorVersion/
branches/Experimental1/
branches/RecycleBin/OldDiscardedBranch
  

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

Есть ли способ передать всю информацию о местоположении этих ветвей в Git? Что будет делать git-svn, когда попытается перенести ревизию, принадлежащую удаленной ветви?

Комментарии:

1. вы можете быть конкретны? что насчет git svn clone --stdlayout http://url gitrepo/ не работает?

2. нет, это не так, поскольку он не знает, как определить, какие пути в репозитории svn на самом деле являются ветвями. Он просто предполагает стандартную иерархию ветвей, которая не соответствует нашей конкретной настройке.

Ответ №1:

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

  • Используется git filter-branch для перезаписи из одних проектов в другой. Т.е. используйте git filter-branch для переименования всего, что находится в подкаталоге, в родительский. В моем случае у меня есть несколько модулей под магистралью, и я использую filter-branch для перемещения всего внутри одного каталога наверх.
  • Сделайте это также для каждой ветви, но также удалите все ветви, которые не относятся к конкретному проекту

Таким образом, в итоге у вас будет несколько git репозиториев, которые содержат только один проект на репозиторий (так и должно быть).

Если каталоги ветвлений / тегов являются сложными, git svn clone команда позволит вам указать несколько каталогов тегов и ветвей, используя запятую (если я правильно помню).

Кроме того, запустите git gc --aggressive после завершения извлечения всего, чтобы немного уменьшить размер репозитория.

Комментарии:

1. Не уверен, что понял. Это то, что вы рекомендуете мне сделать после преобразования из svn в git? Кроме того, мы не можем принять метод «один проект для каждого репозитория». У нас слишком много проектов, которые используют слишком много общих библиотек (сотни).

2. Да, преобразуйте репозиторий svn в один репозиторий git, а затем сделайте несколько его копий и отфильтруйте каждую копию до нужного вам модуля. Вам не обязательно иметь несколько репозиториев git, если вы не хотите, но обычно это намного проще и чище сделать. Если у вас есть несколько библиотек, которые влияют на несколько проектов, это не должно мешать вам размещать их в отдельных модулях. У вас даже может быть родительский модуль, содержащий «подмодули» со всеми необходимыми элементами.

3. Если это обычно один проект целиком и в нем нет нескольких частей, то не разделяйте его. Если это так, то вам все равно, вероятно, потребуется использовать filter-branch в странных случаях ветвей, которые имеют основные и второстепенные версии внутри ветвей. Я думаю, это потребует некоторой работы.

4. Я все еще не понимаю, как я должен преобразовать репозиторий в Git? Если я просто использую git svn clone, то я остаюсь с репозиторием, где каждая ветвь фактически является каталогом, что означает несколько сотен гигабайт одного большого поврежденного репозитория, где нет надлежащей истории ветвей. Короче говоря, как я могу научить svn-git тому, что является ветвью, а что нет?

5. Вот где вам нужно осторожно использовать —branches в вашем git svn init (или git svn clone ). НАПРИМЕР, с несколькими ветвями: --branches branches/ProjectA/MajorVersion/MinorVersion --branches branches/ProjectA/Experiment1 … Возможно, вы захотите сначала выполнить некоторые svn mv действия, если это упростит задачу. Т.е. сначала переименуйте некоторые ветви, основанные на глубине, перед запуском git svn .