Skip to content

Latest commit

 

History

History
143 lines (108 loc) · 8.68 KB

File metadata and controls

143 lines (108 loc) · 8.68 KB

Subversion

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

Вдобавок к этому, импортирование не идеально, так что вы, возможно, захотите сделать его как можно более правильно с первой попытки. И первая проблема — это информация об авторстве. В Subversion на каждого участника рабочего процесса заведён пользователь, информация о пользователе сохраняется вместе с каждой ревизией. В предыдущем разделе вы могли видеть пользователя schacon в некоторых местах, типа вывода команды blame или git svn log. Если вы хотите видеть подробную информацию об авторстве в Git, вам потребуется задать соответствие между пользователями Subversion и авторами в Git. Создайте файл users.txt со следующим содержимым:

schacon = Scott Chacon <schacon@geemail.com>
selse = Someo Nelse <selse@geemail.com>

Чтобы получить список имён пользователей в SVN, выполните следующее:

$ svn log --xml --quiet | grep author | sort -u | \
  perl -pe 's/.*>(.*?)<.*/$1 = /'

Эта команда выводит историю коммитов в формате XML, затем оставляет только строки с информацией об авторе, удаляет дубликаты и обрезает XML-теги. Естественно, она сработает только на компьютерах с установленными grep, sort и perl. Перенаправив вывод этой команды в файл users.txt, вам останется только дописать в каждой строке соответствующих авторов для Git.

Note

Если вы пытаетесь выполнить это на компьютере с Windows, то у вас может возникнуть ряд проблем. Однако, Microsoft предоставила несколько полезных советов по миграции https://learn.microsoft.com/ru-ru/azure/devops/repos/git/perform-migration-from-svn-to-git.

Для точного сопоставления авторов коммитов передайте файл users.txt команде git svn. Добавив флаг --no-metadata в команды clone или init, можно указать git svn исключить импорт метаданных, которые импортируются по умолчанию. Как часть метаданных, git-svn-id включается в каждое сообщение коммита, генерируемое Git при импорте, что может привести к необоснованному увеличению истории и сделать её более запутанной.

Note

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

В результате, команда import примет вид:

$ git svn clone http://my-project.googlecode.com/svn/ \
      --authors-file=users.txt --no-metadata --prefix "" -s my_project
$ cd my_project

Теперь у вас будет красивая копия репозитория Subversion в каталоге my_project. Вместо коммитов типа

commit 37efa680e8473b615de980fa935944215428a35a
Author: schacon <schacon@4c93b258-373f-11de-be05-5f7a86268029>
Date:   Sun May 3 00:12:22 2009 +0000

    fixed install - go to trunk

    git-svn-id: https://my-project.googlecode.com/svn/trunk@94 4c93b258-373f-11de-
    be05-5f7a86268029

вы получите следующее:

commit 03a8785f44c8ea5cdb0e8834b7c8e6c469be2ff2
Author: Scott Chacon <schacon@geemail.com>
Date:   Sun May 3 00:12:22 2009 +0000

    fixed install - go to trunk

Теперь не только поле Author выглядит лучше, но и git-svn-id не мозолит глаза.

Также вам следует немного почистить репозиторий сразу после импорта. Во-первых, следует удалить ненужные ссылки, устанавливаемые git svn. Для начала, переместим теги, потому как в действительности это теги, а не странные удалённые ветки; затем все удалённые ветки сделаем локальными.

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

$ for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do git tag ${t/tags\//} $t && git branch -D -r $t; done

Эта команда берёт ссылки на удалённые ветки, которые располагаются в refs/remotes/tags/, и делает их настоящими (легковесными) тегами.

Затем, переместим оставшиеся ссылки из refs/remotes, чтобы сделать из них локальные ветки:

$ for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch $b refs/remotes/$b && git branch -D -r $b; done

Возможно, для одной ветки Subversion будут созданы дополнительные ветки с суффиксом @xxx (где ххх — это число). Это связано с особенностью Subversion, которая называется «peg-revisions», для которой Git не имеет синтаксического аналога. Поэтому, git svn просто добавляет номер версии svn в название ветки, точно так же как вы бы это сделали в svn при добавлении peg-revision для ветки. Если эти ревизии вам больше не нужны, то просто удалите их используя команду:

$ for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git branch -D $p; done

Теперь все ветки стали настоящими Git ветками, а теги — настоящими Git тегами.

К сожалению, git svn создаёт дополнительную ветку с названием trunk, которая соответствует ветке по умолчанию в Subversion и аналогична ветке master. Так как master больше подходит для Git, удалим лишнюю ветку:

$ git branch -d trunk

Последнее, что нужно сделать — это добавить ваш Git сервер в качестве удалённого репозитория и залить данные на него. Вот пример добавления удалённого репозитория:

$ git remote add origin git@my-git-server:myrepository.git

Так как вы хотите отправить все ваши ветки и теги, выполите следующие команды:

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

Наконец, все ваши ветки и теги перенесены на Git сервер и облагорожены!