Как я могу импортировать SVN с несовместимой структурой ветвления в Git? - PullRequest
0 голосов
/ 06 марта 2012

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

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

История, с которой я знаком, начиная с присоединения к компании, заключается в том, что мы используем одну основную магистральветка, из которой мы создаем ветки релизов и ветки функцийОднако структура этих ветвей не просто стандартная структура соединительных линий / веток / тегов.У нас есть несколько подпапок для разных типов веток.Например, ветки релиза идут в branch_release, функциональные ветки в branch_feature и т. Д., Например:

branches_feature/featureA
branches_release/2.0

Я выяснил, как заставить этот клон / выборку работать должным образом, изменив конфигурацию репозитория Git так, чтобы

branches = {branches_feature,branches_release}/*:refs/remotes/branches/*

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

branches_feature/username/branchname

К сожалению, чтобы выяснить это (трудный путь), мне пришлось "git svn fetch" иобнаружим, что все эти ветки в соответствии с более старым соглашением о ветвлениях были свернуты, так что в Git у каждого пользователя есть одна ветвь, в которой существует каждая созданная ветвь.Итак,

branches_feature/username/featureA
branches_feature/username/featureB

были свернуты в:

branches_feature/username

Очевидно, этого недостаточно для правильно воспроизведенной истории репозитория SVN, но я не уверен, как изменить ветку конфига в конфигурациичтобы инкапсулировать все эти ветви и все еще правильно использовать новый формат ветвления.Я пытался манипулировать им различными способами, но я получаю либо ошибки, либо просто неудачу в моих попытках.

Если кто-то может предложить хороший способ надлежащим образом сохранить историю репозитория SVN при импорте изSVN Git, я был бы очень признателен.

Спасибо.

Ответы [ 2 ]

1 голос
/ 06 марта 2012

TL; DR : Для чего-либо, кроме самого тривиального хранилища, вы никогда не сможете полностью сохранить содержимое хранилища Subversion в хранилище git svn.

Я адаптирую это от моего ответа на похожий вопрос .

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

/
|--branches_feature/
|  |--featureA/       *
|  |--userB/          *
|  |  |--featureB/    * (Possibly now deleted, but existed previously)
|  |  `--featureC/    *
|  `--userC/          *
|--branches_release/
|  |--V1.0/           *
|  `--V2.0/           *
`trunk/               *

К сожалению, git svn не может справиться с таким хранилищем особенно разумным способом. Вы не получите Git-репозиторий, в котором есть все ветви вашего Subversion-репозитория и нет ни одного, которого у него не должно быть.

Ваши варианты таковы:

  • Обрабатывайте branches_feature и branches_feature/userB как папки ветвей.

    В итоге вы получите несколько веток Git, которые, если вы их проверите, дадут вам кучу папок, каждая из которых содержит папку ветки Subversion, и git svn fetch операции с этими папками могут занять больше времени, так как выборка нужно будет сделать как для контейнерной ветви, так и для реальной ветви. Поскольку Git умен, он, по крайней мере, займет очень мало дополнительного дискового пространства.

    Я ожидаю, что у вашего .git/config будут строки, подобные приведенным ниже:

    branches = branches_feature/*:refs/remotes/branches/*
    branches = branches_feature/userB/*:refs/remotes/branches/*
    branches = branches_release/*:refs/remotes/branches/*
    
  • Игнорировать некоторые папки веток. Только не говорите git svn о них и продолжайте в веселом невежестве.

  • Выберите интересующие вас ветки и подберите их вручную. Если вам нужна папка userB, вам все равно нужно быть осторожным с историей, которую вы выбираете, однако, если ее дочерние ветви были удалены и вы не хотите их поднимать.

    Здесь я ожидал бы, что ваш .git/config будет иметь полную загрузку строк, как показано ниже:

    fetch = branches_feature/featureA:refs/remotes/branches/featureA
    fetch = branches_feature/userB/featureB:refs/remotes/branches/featureB
    fetch = branches_feature/userC:refs/remotes/branches/userC
    
  • Патч вашей версии git svn, чтобы каким-то образом справиться с этим сценарием. Бонусные баллы, если они будут включены в будущие официальные релизы Git.

1 голос
/ 06 марта 2012

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

Если вы просто ограничите свое преобразование ветвями релизов и транком, станет ли проблемой отсутствие ветвей функций? У вас все еще должны быть коммиты (потому что они появятся при слиянии), поэтому единственные коммиты, которые не будут присутствовать, это те, которые не были объединены обратно в транк.

При необходимости вы можете позже преобразовать ветви функций, которые вам нужны, и привить их на место с помощью git replace и git filter-branch.

...