Перенос кода с tfs на git

в 3:36, , рубрики: Git, tfs 2013, метки: ,

В один прекрасный день, наш TFS2012 был обновлен до TFS2013.
Вместе с TFS2013 у нас появилась возможность, оставаясь в рамках привычного интерфейса администрирования и менеджмента прав, перейти на распределенную source control git. (Про плюс и минусы распределенного source control сказано уже столько, что повторять не стоит, т.к. холиваров уже было много.)

Задача: перенести разработку build на git, сохранив при этом историю изменений.
Риски

  • Не всю историю удастся перенести: если вы активно перемещали ваш код, иногда часть теряется;
  • Код придется переразложить на ветки руками;
  • Возможно, придется некоторое время «жить» параллельно на 2 системах контроля версий;
  • Если при build вы использовали более одного проекта, то придется подключить их в качестве submodules или придумывать другие способы подключения зависимостей (nuget, к примеру в .net, gem в ruby и т. п.);
  • Придется перенести не только код, но и build.
Перед началом миграции кода...

Перед тем, как будете переносить репозиторий, рекомендую погасить технические долги в плане version control: удалить мертвые ветки; смержить то, что нужно смержить; удалить ненужный/неиспользуемый код, файлы, которые не должны быть в source control, в принципе (промежуточные этапы компиляции, индексы resharper и т.п.). Это лучше сделать на TFS, т.к. тащить это в GIT все равно смысла не имеет. Чем меньше сущностей для переноса, тем лучше.
Заранее стоит подумать и о том, как в git будет этот переносимый код разложен. Например, TFS позволял в рамках одного TFS Project вести хоть сотню проектов в смысле кода, и каждым из них управлять отдельно, делать коммиты в отдельную папку и т.п. Git такого не позволит. По крайней мере, управление разными проектами в рамках одного репозитория по отдельности тут невозможно.

Внешний вид такого проекта

Перенос кода с tfs на git
Начинаем миграцию

Git-TF – это основная утилита, которая, исключая мозг и знания о коде, понадобится при миграции.

Установка Git-TF

Качаем утилиту миграции. Она на java.
Открыв ее, читаем документацию по настройке. Это не долго, советую потратить на это пару минут.

Вот такая вебстраничка

Перенос кода с tfs на git

В целом, она тривиальная. Поставить java, прописать пути в переменной окружения на java и на команду Git-TF. Java нужна, чтобы утилиту можно было запустить и на не Windows машинах.

Clone кода

После того, как настройки завершили, выполняем клонирование из консоли.
Синтаксис: git tf clone tfs-server:8080/tfs/*Collection $/Project –deep
–deep означает клонирование с историей, а не только последний слепок кода.

Как-то так

Перенос кода с tfs на git

После окончания выкачки кодов в home каталоге (C:/users/myuser) будет находиться проект с именем, соответствующим проекту в TFS.

И выглядеть так

Перенос кода с tfs на git

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

Варианты миграции

Концепции системы хранения кода в TFS и GIT различные. Поэтому сконвертировать одной командой с сохранением веток TFVC в Git репозитории не так уж просто.
Тут есть ещё второй момент: будет ли это перманентная миграция или какое-то время вы готовы работать.
В зависимости от этого я бы выделил такие варианты миграции:

Перманентно №1

Git-TF может скопировать весь рапозиторий, и будет одна ветка в git- master. Все TFS ветки будут вместе как папки. Вам придется руками создать ветки и так же вручную разложить в них код так, как вам нужно.

Изначально же проект будет выглядеть следующим образом

Перенос кода с tfs на git

Проблема тут очевидна — до точки разделения кода в Git все изменения лежат скопом.
Уже потом придется приводить проект к нормальному для Git виду.

К вот такому

Перенос кода с tfs на git
Перманентно №2

Используя GIT TF, можно вытащить все нужные ветки и сделать их ветками-сиротами (orphan), и уже по необходимости в git делать merge. Тут проблема диаметрально противоположная — до точки слияния коды разных веток независимые.

Не перманентно

Если вы готовы некоторое время жить частично в Git, частично TFVC, то этот вариант для вас. Миграция ветки main из TFVC в ветку main на Git. Далее уже бранчуемся от этой перенесенной ветки.
По мере готовности веток в TFVC к слиянию делать merge внутри TFVC, а затем делать Git TF pull из ветки main TFVC в Git main. Таким образом, мы заберем разницу между коммитами в TFVC и Git. Далее делаем rebase по необходимости. Проблема тоже очевидная — жить в 2 разных project какое-то время с 2 разными системами контроля версий. Можно очень хорошо разойтись на уровне кода.

Общие моменты для всех вариантов

После того, как вы локально получили код и его историю, нужно сделать несколько вещей:
Создать в новом TFS projectCollection (это опционально) и все projects. Не буду на этом заострять внимание — можно погуглить или прочесть мою статью про миграцию SVN в Git-TFS.

Push на remote

Далее добавить новый удаленный репозиторий (remote), сделать туда push. Обязательно вместе с tags, чтобы потом можно было искать соответствие.

В GitExtensions это здесь

Перенос кода с tfs на git

Раскладывание кода, в случае Перманентно 1

В моем случае, весь перенос растянулся на 2 дня.
Проект был разделен на 12 подпроектов, т.к. именно столько разных логических проектов в нем жило, и все это вынесено в отдельный projectCollection.

Получилось вот так:

Перенос кода с tfs на git

Основным ограничивающим фактором было:

  • Наличие определенного беспорядка в репозитории;
  • Необходимость самому создать и проверить на собираемость все ветки;
  • Подключить submodules;
  • Создать бинарные ветки в репозиториях с кодом;
  • Непонимание в одном из проектов какая ветка жива, какая не жива.

Все это относится не к методу, а к проекту в целом.

Merge, Git TF pull, Rebase в случае не перманентной миграции

Если схематически рисовать, то будет примерно так.

Шаг 1

Перенос кода с tfs на git

Шаг 2

Перенос кода с tfs на git

Шаг 3

Перенос кода с tfs на git

Шаг 4

Перенос кода с tfs на git

Шаг 5

Перенос кода с tfs на git

Шаг 6

Перенос кода с tfs на git

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

Ограничение истории:

Git-TF ничего не знает про другие проекты, кроме того, который вы указали. Т.е. если ваш код когда-то был в другом project collection или другом project, то в TFS коммиты из них не увидите — только те, которые в текущем проекте (файлы при этом конечно же будут на диске). Как вы видели историю в TFS, так же вы ее увидите в Git.
Пример: вы сделали move куска кода из одного TFS project в другой. Тогда команда
git tf clone tfs:8080/tfs/DefaultCollection $/ TargetProjects --deep вытащит только последний коммит, без истории.
Если move был сделан недавно, то можно забрать историю из старого проекта, указав последний перед move коммит.
git tf clone tfs:8080/tfs/DefaultCollection $/SourceProjects --deep --version=57012
Если же эти изменения были сделаны давно, то это будет крайне тяжело — вытащить историю, т.к. нужно будет проделать много ручных манипуляций.

Не наступайте на наши грабли:

  • “Решили переходить на Git, переходите на Git”, – эта фраза кажется банальной, но если переходить на Git по полгода, то в это время возникнет слишком много проблем, которые сильно измотают всем нервы.
  • Git — это source control. Не надо пытаться вместе с Git сразу поменять build систему и процессы разработки. Сделайте сначала одно, затем другое. Именно из-за того, что Git рассматривался в контексте изменения процесса разработки-тестирования-внедрения-сопровождения у одной из команд очень долго идет процесс миграции. Уже полгода…
  • Убедитесь, что все разработчики хотя бы минимальную практику работы с Git получили до начала. Иначе может наступить момент, когда “некогда думать, надо делать”. А тут вдруг окажется, что человек не знает, как свой код объединить с другой ветки и выложить на remote repository.

P.S.
Есть у меня небольшой проект GitQuiz (тестовые примеры, видео как их выполнить).
Очень помогает для обучение разработчиков, у которых есть некоторые теоретические знания по работе с распределенными системами хранения исходных кодов, но нет практического опыта. Я его на своих коллегах опробировал.
Ну а совсем для профи, можно мне с этим проектом помочь, есть набор задач, до которых у меня пока руки не дошли.

Автор: SychevIgor

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js