Правильное использование тегов в SCM - PullRequest
8 голосов
/ 08 апреля 2009

Мои коллеги и я спорим о значении и использовании тегов в системах выпуска / SCM. Мы надеемся, что сообщество StackOverflow высказывает свои мысли, чтобы помочь нам решить проблему.

Одна сторона утверждает, что теги являются ценным дополнением к управлению релизами. Пример их использования: мы делаем релиз Maven, который создает новый тег (назовите его 1.0), который представляет собой снимок кода, используемый для этого выпуска. Этот тег должен быть веткой READONLY. Когда нужно исправить ошибку, мы можем сделать копию тега в новую ветвь (назовите ее 1.1). Исправления ошибок идут туда. Эти исправления могут быть объединены обратно в Trunk, так что основная ветка разработчика получает исправления ошибок. Наконец, 1.1 выпущен и тег 1.1 автоматически создается. Этот цикл продолжается. Основным преимуществом тега здесь является то, что если вам когда-либо понадобится переиздание версии 1.0 по любой причине, вы можете просто выпустить тег 1.0 с уверенностью, что он никогда не был изменен кем-либо. Кроме того, высказывание «Release Tag 1.0» более понятно, чем высказывание «Release revision 1 of branch 1.0, которая является исходной версией 1.0 без исправлений».

Другая сторона утверждает, что теги не дают каких-либо ценных преимуществ, особенно в такой системе, как Subversion с глобальными ревизиями, которая действует как тег в CVS. Кроме того, Subversion выдает предупреждение только при фиксации тега; это на самом деле не останавливает это. Их метод разрабатывается в Trunk, и после выпуска вы создадите ветку с именем 1.0. Вы продолжите исправление ошибок в Trunk, и если вам нужно будет повторно выпустить эти исправления ошибок в производство, вы объедините их в 1.0 Branch и переиздадите 1.0. В какой-то момент, возможно, после серьезных исправлений или функций в Trunk, вы выпустите и создадите Branch 1.1. Цикл продолжается. Если вам когда-нибудь понадобится выпустить оригинальную версию 1.0, вам нужно будет проверить версию 1.0 Branch.1.

Очевидно, что оба метода работают. Мне бы хотелось услышать мнение сообщества о том, какой метод предпочтительнее и почему.

Редактировать: Я немного обеспокоен тем, что "лучший" способ зависит от базовой системы SCM. Либо воспользуйтесь Subversion для ответов, либо, если возможно, оставьте их независимыми от SCM.

Ответы [ 8 ]

4 голосов
/ 08 апреля 2009

С точки зрения агностики SCM тег очень отличается от ревизии.

Оба могут быть реализованы одинаково, оба представляют «временную линию», но их цель различна:

  • тег представляет собой неизменное состояние, в котором все файлы имеют уникальный идентификатор. Это имя , представляющее многие вещи , но в основном стабильное состояние, ...)
  • ревизия представляет транзакцию фиксации ( не все SCM имеют такие , особенно старые с «подходом к файлу») Все коммиты не представляют «стабильное» состояние (как в «compile» или «execute» успешно). Это просто новый элемент мировой истории.

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

4 голосов
/ 08 апреля 2009

По моему мнению, теги полезны. В какой-то момент в жизни проекта будут случаи, когда вы сталкиваетесь с ошибкой или изменением, и вы хотите знать, было ли это в предыдущем выпуске. Будут причины сравнивать код из одного выпуска с другим, чтобы измерить эффективность как в производительности, так и в действительности при разработке кода.

Конечно, есть шанс, что вы можете облажаться, но это всегда можно отменить. На самом деле нет причин не делать этого, и есть несколько причин, по которым это может пригодиться в будущем. Для меня это ежу понятно.

Я согласен, что вы также должны использовать ветки и делать там свою разработку, но каждый раз, когда вы что-то действительно выпускаете, делайте из этого тег.

1 голос
/ 15 апреля 2009

Мы используем теги (метки) при создании новых базовых линий. Мы делаем это один раз в неделю, но некоторые команды делают это даже несколько раз в день.

Смысл (для нас) всегда в том, чтобы убедиться, что новый базовый уровень стабилен: так что это не просто сборка, это сборка, которая проходит весь набор тестов, несколько часов автоматических тестов плюс потенциально ручные исследовательские тесты.

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

Обычно мы помещаем теги (метки) только в основную ветвь (или транк или мастер в зависимости от вашего вида SCM), которая является точкой интеграции для всех остальных ветвей.

Когда мы выпускаем официальный продукт, мы создаем «ветку релиза для него», поэтому он будет получать исправления только тогда, когда новая разработка остается на «основном». Тогда эти «ветки обслуживания» (надеюсь, только по одной или две одновременно) тоже могут быть помечены.

1 голос
/ 08 апреля 2009

Да, вы хотите использовать теги.

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

Если вы выполняете ветвление после выпуска, вы всегда можете выяснить, какая ревизия была выпущена в производство, но это немного сложнее, чем просто смотреть на тег. Если вы не используете ветки релизов, то будет легко потерять отслеживание того, какая ревизия использовалась для создания конкретной сборки.

Проблема с SVN в том, что он стирает различие между тегами и ветвями. Любой может всегда фиксировать тег, поэтому он не гарантированно будет фиксированным / неизменным. В других VCS, таких как PVCS, «тег» неизменен. Вы можете принять групповое соглашение для предотвращения фиксации тегов или даже использовать хуки фиксации для предотвращения фиксации тегов.

0 голосов
/ 08 апреля 2009

Я бы объединил оба подхода. Всякий раз, когда вы делаете релиз, пометьте его. Теги никогда не должны изменяться, поэтому наличие тега "1.0.0" является показателем того, что вам не следует пытаться выпустить что-либо еще как 1.0.0.

В то же время, когда пришло время сделать 1.0.0, я поместил его в ветку 1.0. Итак, поток таков: ветвь ствола до 1.0, пометьте этот новый 1.0 как 1.0.0 и разверните Затем можно исправить ошибки в ветке 1.0 (чтобы избежать путаницы с разработкой, нацеленной на 1.1, которая уже может быть в транке) и объединить в транк. Каждый выпуск фиксированной версии 1.0 помечается как 1.0.x из ветви 1.0. Это в основном подход, который мы используем при работе с Perforce, и он очень похож на Subversion. (Читая ответы, я думаю, что это практически идентично рекомендации Винсента)

Что касается комментария о том, что теги являются избыточными из-за того, что у вас есть номера ревизий - это в значительной степени верно, за исключением того, что теги также определяют область действия: то есть, какие файлы в хранилище охватываются тегом. Вы можете разумно попросить кого-нибудь взглянуть на /svn/proj1/tag/1.0.0, и они сразу же посмотрят на согласованное рабочее пространство. Если вы попросите их взглянуть на ревизию X, они должны сначала взглянуть на ревизию X, чтобы увидеть, что она меняется (скажем) / svn / proj1 / trunk / Makefile, и, следовательно, сделать вывод, что / svn / proj1 / trunk / @ X - это то, что они должны смотреть. Что произойдет, если версия X коснулась файлов в proj1 и proj2? Что, конечно, зло, но, строго говоря, вы должны сказать / svn / proj1 / trunk / @ X. И где хранится список номеров ревизий? Откуда мы знаем, что 1.0.0 является ревизией X? ИМХО должно быть возможно определить это только из хранилища.

В таких системах, как Git, теги и ветви все еще в основном одно и то же (просто ссылки на базу данных объектов), но соглашение *1008* состоит в том, что ссылки на теги не меняются, а ссылки на ветки делают (и желательно с определенным ограничением на то, как они меняются). Perforce также имеет «метки», которые представляют собой способы группировки набора версий файла независимо от списка изменений; который по сути является тегом, но более запутанным: исторически мы использовали номера списков изменений (эквивалентные номерам ревизий Subversion), в которых указывалось название ветви, в которой они должны находиться, для идентификации версий. В любом случае, они почти идентичны, так что я думаю, что TMTOWTDI.

0 голосов
/ 08 апреля 2009

В SVN техническая разница между использованием тега и отслеживанием ревизии равна нулю. Я считаю себя минимизирующим использование тегов, основываясь на том, что реализация SVN является просто дешевой копией и загромождает ваше «пространство структуры».

Реальная разница возникает тогда, когда сообщает конкретную базовую линию большой команде разработчиков. Отслеживание редакций приносит дополнительный уровень абстракции, который может стать источником ошибок. И, как мы все знаем, когда вы имеете дело с 50+ разработчиками, любой источник ошибок станет областью путаницы и потерянного времени. Подробная метка может устранить эту путаницу и устранить любые сомнения относительно цели базовой линии.

0 голосов
/ 08 апреля 2009

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

Я не могу сказать вам, сколько раз кто-то приходил ко мне и говорил: «Этот код микроконтроллера не работает, вы можете помочь?» и я спрашиваю их: «Какую версию вы используете?» и они говорят: «Я не уверен», потому что они не справляются с управлением выпусками (по крайней мере, наклеивая стикер на устройство, лучше поместить информацию о версиях в EEPROM, которую можно запрашивать в реальном времени). >: (* ​​1003 *

0 голосов
/ 08 апреля 2009

Мне нравится думать о тегах как о "просто причудливом названии для ревизии". Я всегда думал о них таким образом, и IIRC в Mercurial они просто так. Однако в Subversion, как вы говорите, они действительно (дешевые) копии транка / * для тегов / fancy-name /

Честно говоря, я бы объединил две стратегии для достижения оптимальных результатов: тег и ветвь после выпуска. Ваш тег называется 1.0.0, ветвь 1.0-MAINT. Исправления попадают в ветки, а выпуски исправлений снова являются тегами (1.0.1 может быть тегом, предназначенным для псевдонима 1.0-MAINT в определенной точке.)

Не забывайте, однако, что теги и ветки в Subversion - это одно и то же: дешевые копии. Единственная разница между ними заключается в семантике, которую вы / ваша команда им приписываете, поэтому все сводится к тому, чтобы заставить людей договориться об одном частном методе и придерживаться его (может быть применено на сервере, например, запрещать коммиты в тегах для координаторов релизов и т. д.)

Проблема, с которой я сталкиваюсь при втором подходе, заключается в следующем: как вы сможете легко провести различие между программным обеспечением в полевых условиях, если вы переиздадите 1.0? Это означает, что у вас может быть 1.0 и другая 1.0, фактически ссылающаяся на другую кодовую базу ....

...