#tfs #branch #branching-and-merging
#tfs #ветвь #ветвление и слияние
Вопрос:
Мы рассматриваем возможность перехода с SVN на TFS, поэтому я пытаюсь найти правильный рабочий процесс для использования в TFS, чтобы удовлетворить наши потребности. Существует множество обсуждений схемы ветвления, но большинство из тех, которые я видел, имеют 1 общую черту, которая не соответствует нашим потребностям; почти все схемы ветвления предполагают, что ваши ветви можно тестировать.
Итак, мы создаем некоторые ветви функций из магистрали:
Trunk --(branch)--> Feature1
Trunk --(branch)--> Feature2
Trunk --(branch)--> Feature3
В нашем случае мы создаем «функциональные» ветви, каждая функциональная ветвь может быть протестирована модулем, но не может быть проверена QA. Это связано с тем, что каждая ветвь функций должна иметь свой собственный экземпляр базы данных и веб-сервер, а у нас просто нет ресурсов для этого. Итак, мы объединяем наши функциональные ветви обратно в ветку тестирования. Затем наша команда контроля качества тестирует все функции (по мере их готовности) в ветке тестирования.
Feature1 --(merge)--> Testing
Feature2 --(merge)--> Testing
Feature3 --(merge)--> Testing
Вот тут-то все и становится странным…
Обратите внимание, что ветви функций на самом деле не имеют той же иерархии, что и ветвь тестирования. В SVN, я думаю, вы бы назвали это «необоснованным» слиянием, которое, я думаю, не поддерживает TFS…
При тестировании QA определенная функция может не пройти тестирование, или, что более часто, бизнес решит «неважно, мы не хотим, чтобы Feature2 выходил в этом выпуске, мы подождем до следующего выпуска».
В какой-то момент, когда функция прошла проверку качества и бизнес подписывает ее, мы объединяем наши принятые функции с магистралью (выпуск / производство).
Feature1 --(merge)--> Trunk
Feature3 --(merge)--> Trunk
Затем мы создаем наш релиз из магистрали (и помечаем его номером версии)
Итак, я ищу способ заставить что-то подобное работать в TFS. Поскольку вы, похоже, можете объединяться только с предком, я мог бы настроить это следующим образом:
Trunk
|- Testing
|- Feature1
|- Feature2
|- Feature3
И переход от ветвей функций к тестированию. Однако тогда мне нужно было бы объединить только ревизии, созданные из Feature1 и Feature3, из Testing в Trunk, игнорируя ревизии Feature2. Похоже, что это была бы ужасно утомительная, подверженная ошибкам работа по проверке каждого изменения вручную, чтобы узнать, из какой ветки оно пришло? Вот почему в нашей схеме SVN мы бы объединили нашу функциональную ветвь непосредственно обратно в магистраль.
Похоже, что наличие ветвей функций, которые необходимо повторно интегрировать в общую ветку тестирования, должно быть довольно распространенным явлением, но, думаю, я не вижу простого способа получить только наборы изменений, созданные в определенном листе, для следующего шага слияния.
У кого-нибудь есть какие-либо данные? Мы, безусловно, открыты для пересмотра нашей схемы ветвления. То, что мы делали раньше, просто работает нормально в SVN. Я подозреваю, что это было бы нетрудно и в git, поскольку вы могли бы фактически объединить всю функцию в один коммит и просто объединить этот коммит с любой другой веткой.
Спасибо за любой вклад!
Другие примечания:
Мы используем TFS 2010. Я забыл упомянуть об этом ранее.
Другим вариантом было бы удаление всех изменений функции из ветки тестирования, прежде чем объединять ее с магистралью. Это будет «обратное слияние» в SVN. Я видел, что есть tf.exe /rollback
команда, но похоже, что для нее требуется номер набора изменений. Каждая функция может содержать несколько наборов изменений, поэтому я до сих пор не вижу способа определить список наборов изменений в тестировании, которые возникли в результате слияния с featureX…
Комментарии:
1. Смотрите Руководство по ветвлению Visual Studio Team Foundation Server 2010
Ответ №1:
В TFS поддерживаются необоснованные слияния, их просто нужно выполнить через командную строку. Смотрите Здесь введение о том, как это работает. После того, как вы выполнили необоснованное слияние, устанавливается дополнительная «связь» между ветвями, и с этого момента вы сможете объединяться из графического интерфейса.
Таким образом, предлагаемая вами структура может работать:
Trunk
|- Testing
|- Feature1
|- Feature2
|- Feature3
при условии, что вы выполнили три необоснованных слияния (Feature1 -> Магистраль), (Feature2 -> Магистраль) amp; (Feature3 -> Магистраль).
Другим аналогичным, но, возможно, немного лучшим подходом может быть следующий:
Trunk
|- Feature1
|- Feature2
|- Feature3
|- Testing
а затем — вручную — установление с помощью необоснованных слияний (Feature1 -> Тестирование) amp; (Feature2 -> Тестирование).
Таким образом, вы сможете использовать Testing
ее в качестве дамп-зоны, и как только все будет проверено нормально для featureX in Testing
(тесты ok, mgmnt решает использовать его), вы сможете отправить его в свою магистраль.
В целом, необоснованное слияние не считается «лучшей практикой» в руководстве ALM rangers по ветвлению TFS. Глядя на ваш рабочий процесс, я боюсь, что не смогу найти для вас альтернативу ATM, которая ее не использует.
Комментарии:
1. Спасибо за идеи. На самом деле наша текущая схема SVN похожа на ваш 2-й подход, где мы необоснованно переходим от функции к тестированию. Затем мы периодически выбрасываем ветку тестирования. Я просто не понимал, что вы можете необоснованно объединить из строки cmd.
Ответ №2:
Определенно есть компромиссы между обоими, и, на мой взгляд, это сводится к тому, насколько сильно ваши функциональные группы пересекаются друг с другом. Как отметил пантелиф, вы действительно можете выполнять необоснованные слияния и в TFS, но это менее гламурно, чем когда у вас есть правильные отношения слияния между ветвями, и вы теряете много возможностей слияния при выполнении необоснованного слияния.
Я думаю, что определение наборов изменений для объединения на вашей второй иллюстрации:
Trunk
|- Testing
|- Feature1
|- Feature2
|- Feature3
менее утомительно, чем вы думаете. Учтите, что при объединении нескольких наборов изменений (скажем, 1, 2 и 3) из функции 1 в тестирование, это слияние будет зафиксировано как единый набор изменений в ветке тестирования (скажем, набор изменений 4). Когда вы завершите работу над функцией, вы можете выполнить слияние до магистрали, просто объединившись с выбранными наборами изменений и выбрав набор изменений 4. (То есть вам не нужно повторно выбирать все эти исходные наборы изменений 1, 2 и 3.) Вам, конечно, придется немного поработать, чтобы определить, какой набор изменений слияния содержит эту функцию, но я предполагаю, что вы не так часто объединяетесь в trunk, что было бы трудно определить. (И если это неверное предположение, то игнорируйте меня.)
Но большая проблема с этой структурой заключается в том, что требуется объединение между работой функции 1 и работой функции 2. Допустим, они оба вносят изменения в одни и те же классы. Теперь, если вы хотите продвинуть только одну из ветвей функций до уровня Trunk, вам придется отменить эти изменения, пока работа другой функции не будет готова к продвижению. И это звучит утомительно и подвержено ошибкам.
Если это полный крайний случай, и ваши функциональные ветви работают в основном независимо друг от друга с небольшим перекрытием и тривиальными слияниями, я бы выбрал эту структуру. Если, однако, это обычный сценарий, то я бы, вероятно, выбрал маршрут необоснованного слияния.
Комментарии:
1. Спасибо за информацию, Эдвард. При «слиянии» становится 1 набор изменений; Проблема, возникающая в SVN и TFS; Если у меня есть ожидающие изменения в ветке, в которую я объединяюсь, тогда впитывайте изменения 2 3 4 из функции и зафиксировать как набор изменений 5, теперь я, возможно, случайно также зафиксировал ожидающие изменения изветка, в которую я слился.
2. (2-й комментарий из-за слишком большого количества символов) … Также иногда функция объединяется для тестирования несколько раз, для исправления ошибок или дополнительных изменений, и поскольку каждый объединенный набор изменений получает собственное сообщение о фиксации, разработчик должен сделать хорошее сообщение о фиксации, в котором говорится: «это слияние с Feature1» или что-то еще. Но вы знаете, как это происходит… вы получаете 80 коммитов с текстом «исправления ошибок» или «объединены» 🙂 В любом случае, это уже то, с чем мы имеем дело в SVN, но надеялись, что мы сможем справиться с этим лучше в TFS.
3. Да, я понимаю первую проблему — я выполняю слияния в отдельной рабочей области TFS, чтобы у меня не было никаких шансов случайно интегрировать ожидающие изменения. Конечно, для этого требуется в 2 раза больше дискового пространства, что может быть непосильным для огромных проектов. И ваша проблема с исправлением ошибок, конечно, отличный момент. Я предвзято отношусь к необоснованным слияниям, потому что мне нравятся блестящие пользовательские интерфейсы с визуализацией ветвей и перетаскиваемыми битами, но здесь вполне может быть правильный путь.
Ответ №3:
Поэтому я думаю, что, как правильно упоминали люди выше, вам поможет необоснованное слияние из командной строки. Во-вторых, вы упомянули о 80 коммит. В нашем проекте мы создаем задачи в TFS. Согласно процессу, каждый разработчик может зафиксировать только в том случае, если он сначала «сопоставит» свою регистрацию с задачей. Поэтому, если у меня есть исправление x, я создаю задачу для того же, а затем, даже если есть 80 коммитов, все они связаны с этой задачей, что позволяет мне легко просматривать группировку в любое время в будущем.