Вместе с 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 такого не позволит. По крайней мере, управление разными проектами в рамках одного репозитория по отдельности тут невозможно.
![](http://habrastorage.org/getpro/habr/post_images/9d6/aa4/cc4/9d6aa4cc4b5a213736352b30b8cde3e6.jpg)
Начинаем миграцию
Git-TF – это основная утилита, которая, исключая мозг и знания о коде, понадобится при миграции.
Установка Git-TF
Качаем утилиту миграции. Она на java.
Открыв ее, читаем документацию по настройке. Это не долго, советую потратить на это пару минут.
![](http://habrastorage.org/getpro/habr/post_images/71f/e94/51b/71fe9451b6514c209808117c66b49901.jpg)
В целом, она тривиальная. Поставить java, прописать пути в переменной окружения на java и на команду Git-TF. Java нужна, чтобы утилиту можно было запустить и на не Windows машинах.
Clone кода
После того, как настройки завершили, выполняем клонирование из консоли.
Синтаксис: git tf clone tfs-server:8080/tfs/*Collection $/Project –deep
–deep означает клонирование с историей, а не только последний слепок кода.
![](http://habrastorage.org/getpro/habr/post_images/0a8/ae8/787/0a8ae87878bb7b25b456fca0d40db3d0.jpg)
После окончания выкачки кодов в home каталоге (C:/users/myuser) будет находиться проект с именем, соответствующим проекту в TFS.
![](http://habrastorage.org/getpro/habr/post_images/0d1/b9e/e61/0d1b9ee618c3440a7e88c38e11ace1fd.jpg)
При этом будет перенесена вся история, которая была в этом репозитории.
Каждый коммит будет помечен тэгом. Тэг — это номер коммита в TFS (очень помогает, если нужно посмотреть, как все было до git).
Варианты миграции
Концепции системы хранения кода в TFS и GIT различные. Поэтому сконвертировать одной командой с сохранением веток TFVC в Git репозитории не так уж просто.
Тут есть ещё второй момент: будет ли это перманентная миграция или какое-то время вы готовы работать.
В зависимости от этого я бы выделил такие варианты миграции:
Перманентно №1
Git-TF может скопировать весь рапозиторий, и будет одна ветка в git- master. Все TFS ветки будут вместе как папки. Вам придется руками создать ветки и так же вручную разложить в них код так, как вам нужно.
![](http://habrastorage.org/getpro/habr/post_images/2ee/fdc/a3e/2eefdca3eca9c30910747c7a62c3732a.jpg)
Проблема тут очевидна — до точки разделения кода в Git все изменения лежат скопом.
Уже потом придется приводить проект к нормальному для Git виду.
![](http://habrastorage.org/getpro/habr/post_images/04d/c7f/468/04dc7f468758c4d305fa7d11d02bfac6.jpg)
Перманентно №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, чтобы потом можно было искать соответствие.
![](http://habrastorage.org/getpro/habr/post_images/b92/7b6/58d/b927b658d5776d0498726d7225bac75d.jpg)
Раскладывание кода, в случае Перманентно 1
В моем случае, весь перенос растянулся на 2 дня.
Проект был разделен на 12 подпроектов, т.к. именно столько разных логических проектов в нем жило, и все это вынесено в отдельный projectCollection.
![](http://habrastorage.org/getpro/habr/post_images/734/c16/e88/734c16e88f1118f20d4608a1c56e71ed.jpg)
Основным ограничивающим фактором было:
- Наличие определенного беспорядка в репозитории;
- Необходимость самому создать и проверить на собираемость все ветки;
- Подключить submodules;
- Создать бинарные ветки в репозиториях с кодом;
- Непонимание в одном из проектов какая ветка жива, какая не жива.
Все это относится не к методу, а к проекту в целом.
Merge, Git TF pull, Rebase в случае не перманентной миграции
Если схематически рисовать, то будет примерно так.
![](http://habrastorage.org/getpro/habr/post_images/e6e/445/d30/e6e445d30c59de0f3721ada1b0c3a015.png)
![](http://habrastorage.org/getpro/habr/post_images/e54/a9a/e96/e54a9ae96cb979fd27cf42874ea9c8d3.png)
![](http://habrastorage.org/getpro/habr/post_images/a9c/c03/573/a9cc03573aabd93bd0b8dadf883203f5.png)
![](http://habrastorage.org/getpro/habr/post_images/6b1/102/fd4/6b1102fd4fcc5551aaa497f93aeaf080.png)
![](http://habrastorage.org/getpro/habr/post_images/7c8/d80/42a/7c8d8042af694daafadf39f39065ec2c.png)
![](http://habrastorage.org/getpro/habr/post_images/983/9c4/8af/9839c48af77f947ebfccb0905334467f.png)
При такой миграции нам повезло — никаких 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 (тестовые примеры, видео как их выполнить).
Очень помогает для обучение разработчиков, у которых есть некоторые теоретические знания по работе с распределенными системами хранения исходных кодов, но нет практического опыта. Я его на своих коллегах опробировал.
Ну а совсем для профи, можно мне с этим проектом помочь, есть набор задач, до которых у меня пока руки не дошли.
ссылка на оригинал статьи http://habrahabr.ru/post/228319/
Добавить комментарий