Преобразование SVN в Git через реструктуризацию хранилища с использованием SubGit

Я работаю над переносом хранилища Subversion в Git с использованием SubGit 2.0.3, пытаясь сохранить полную историю всей реструктуризации. У меня есть конфигурация, которая поддерживает историю реструктуризации для филиалов, но не транк.

Сама реструктуризация была немного... необычной... и включала промежуточную планировку.

Первоначальный макет:

  • транк: /ProjectOldName
  • филиалы: /ProjectOldName / релизы
  • теги: н / д

Промежуточный макет:

  • транк: /trunk/ProjectNewName
  • филиалы: / релизы / ProjectNewName
  • теги: н / д

Окончательный макет:

  • trunk: / ProjectNewName / trunk
  • отделения: / ProjectNewName / отделения / выпуски
  • теги: / ProjectNewName / теги

Таким образом, отображения subgit, которые я использовал для преобразования, были:

trunk = ProjectNewName/trunk:refs/heads/master
branches = trunk/ProjectNewName:refs/heads/old-master-interim
branches = ProjectOldName:refs/heads/old-master
branches = ProjectNewName/branches/releases/*:refs/heads/releases/*
branches = releases/ProjectNewName/*:refs/heads/old-releases-interim/*
branches = ProjectOldName/Releases/*:refs/heads/old-releases/*
tags = ProjectNewName/tags/*:refs/tags/*
shelves = ProjectNewName/shelves/*:refs/shelves/*

Это поддерживало историю веток релиза, журнал для файла выходил бы за рамки реструктуризации... хотя, казалось, он остановился на создании ветки (которая произошла до реструктуризации). Однако история того же файла на главном сервере остановилась на создании последнего шага реструктуризации, и ожидаемые ветки 'old-master-interim' и 'old-master' не существовали в хранилище git.

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

  • Начните с /ProjectOldName
  • Добавить каталог /trunk/ProjectNewName
  • Добавить несколько каталогов (большинство, но не все) в /trunk/ProjectNewName/ из /ProjectOldName/, с удалением тех каталогов, которые не были добавлены (как это произошло, я не уверен, так как каталоги еще не существовали в этой ветви)
  • Замените несколько каталогов (такой же набор, как добавлено выше) в / trunk / ProejctNewName / from /ProjectOldName / (с немного другими ревизиями, может быть попытка повторить предыдущее добавление?)
  • Удалить каталог /trunk/ProjectNewName (с комментарием о сохранении истории)
  • Добавить каталог /trunk/ProjectNewName (во второй раз)
  • Добавьте несколько каталогов в /trunk/ProjectNewName/ из /ProjectOldName/, снова тот же набор каталогов, но на этот раз удалений не было
  • Добавить каталог / ProjectNewName / trunk
  • Добавить несколько каталогов в / ProjectNewName / trunk / from /trunk/ProjectNewName/
  • Удалить каталог /trunk/ProjectNewName

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

  • Начните с /ProjectOldName / Releases
  • Добавить каталог / релизы
  • Добавить несколько каталогов (по одному для каждой ветви) в / Releases / из /ProjectOldName / Releases /
  • Удалить каталог / релизы
  • Добавить каталог / Releases / ProjectNewName
  • Добавить несколько каталогов (по одному для каждой ветви) в / Releases / ProjectNewName / из /ProjectOldName / Releases /
  • Добавить каталог / ProjectNewName / филиалы / релизы
  • Добавить несколько каталогов (по одному на каждую ветку) в / ProjectNewName / Branchs / Releases / из / Releases / ProjectNewName /
  • Удалить каталог / Releases / ProjectNewName

Единственным реальным отличием, по-видимому, является шаг "Замена нескольких каталогов", который произошел для транка, но не для ветвей.

Итак, после всего этого:

  • Есть ли способ заставить SubGit преобразовать вышеупомянутое, поддерживая историю через реструктуризацию для транка?
  • Может ли SubGit обрабатывать ветви под стволом, как в исходной компоновке хранилища (т. Е. Ствол в / OldProjectName, ветки в /OldProjectName/Releases)?
  • Есть ли что-то особенное в отображении "ствола"? Или это на самом деле ничем не отличается от отображения "ветвей"? AFAIK для svn и git, нет ничего особенного в каталоге "trunk" и ветви "master" соответственно.
  • Несмотря на то, что история ветвей, похоже, пересекает реструктуризацию, они останавливаются на создании филиала, а не на том месте, откуда оно было создано. Что может вызвать это и как это можно исправить (если это возможно)?

1 ответ

Решение

Есть ли способ заставить SubGit преобразовать вышеупомянутое, поддерживая историю через реструктуризацию для транка?

SubGit может отслеживать историю веток, когда весь каталог веток копируется из одного места в другое:

$ svn cp ^/trunk ^/branches/foo

Однако невозможно отследить историю, когда были скопированы некоторые из подкаталогов ветвей:

$ svn add ^/branches/foo
$ svn cp ^/trunk/dir1 ^/branches/foo/dir1
$ svn cp ^/trunk/dir2 ^/branches/foo/dir2
...
$ svn cp ^/trunk/dirN ^/branches/foo/dirN

К сожалению, именно так была проведена реструктуризация для каталогов ProjectOldName, / trunk / ProjectNewName и /ProjectNewName/trunk. В результате SubGit не может сохранить историю для них.

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

Этот обходной путь, однако, приводит к следующему вопросу:

Может ли SubGit обрабатывать ветви под стволом, как в исходной компоновке хранилища (т. Е. Ствол в /OldProjectName, ветки в /OldProjectName/Releases)?

Нет, SubGit игнорирует каталог OldProjectName в этом случае.

Мы сделали это намеренно: если SubGit попытается импортировать каталог OldProjectName, любая ревизия, которая добавляет ветку к OldProjectName / Releases, займет много времени, так как SubGit рассматривает его как совершенно новый каталог.

Чтобы перенести историю OldProjectName в другие ветви, я бы рекомендовал импортировать эту ветку отдельно:

$ subgit configure --svn-url URL REPO
$ git config -f REPO/subgit/config svn.trunk OldProjectName:refs/heads/master
$ subgit import REPO

После этого вы можете получить импортированные изменения в Git-репозитории, импортированные с уже упомянутыми вами настройками, а затем использовать git replace чтобы присоединиться к истории ProjectOldName, / trunk / ProjectNewName и /ProjectNewName/trunk.

Несмотря на то, что история ветвей, похоже, пересекает реструктуризацию, они останавливаются на создании филиала, а не на том месте, откуда оно было создано. Что может вызвать это и как это можно исправить (если это возможно)?

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

$ svn cp ^/ProjectOldName ^/ProjectOldName/Releases/BRANCH

К сожалению, это означает, что вы можете выбрать импорт ProjectOldName или ProjectOldName/Releases/*, но не оба одновременно. Снова используя git replace может помочь здесь, прививая историю ветвей.

Есть ли что-то особенное в отображении "ствола"? Или это на самом деле ничем не отличается от отображения "ветвей"? AFAIK для svn и git, нет ничего особенного в каталоге "trunk" и ветви "master" соответственно.

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

Нет разницы между стволом и ветвями, если вы импортируете историю SVN в Git.

Предупреждение:
Вы никогда не должны использовать использование git replace Команда на случай, если вы собираетесь синхронизировать Git и SVN-репозитории, а не выполнять одноразовый импорт.

Спасибо за предоставление всех необходимых деталей в вашем вопросе. Надеюсь, мой ответ достаточно полезен.

Другие вопросы по тегам