2010-09-06

Развернуто об одной ветке на каждую задачу

Добрейшего.

Периодически читаю посты из командного блога Plastic SCM - продукта, обзор которого я не так давно делал. Продукт очень интересный, поэтому стараюсь быть в курсе того, что у них происходит.
И вот публикуется очередная статья, называется Branch per task workflow explained. Как следует из названия, описывает, почему же надо придерживаться политики ветвления "одна задача - одна ветка". Предполагаемый уровень читателя - новички в области контроля версий, применяющие простые практики.
Так понравилась, что решил перевести. Думаю, многим покажется интересной, несмотря на то, что объясняются, в общем-то, простые вещи.

Итак, текст.

Цель статьи - объяснить как работает шаблон "одна ветка на задачу", и почему контролировать проекты - это хорошо. Шаблон этот также известен как "ветка для фичи", "отладочная ветка", "ветка для задачи" и даже "ветка для ошибки".
Ветвление и слияние с последнее время стали горячо обсуждаемой темой, особенно в связи с ростом популярности распределенных систем контроля версий, так что, думаю, вам эта заметка будет весьма кстати :)
Я также попытаюсь обозначить взаимосвязь между этим шаблоном и гибкими методологиями типа Scrum.
Ещё я объясню почему "ветка на задачу" является основой для параллельной разработки, и почему этот шаблон гораздо лучше последовательной разработки ("разработки на транке").

Что такое задача

Для начала позвольте задать вопрос: вы используете систему отслеживания запросов на изменения? Если да - переходите к следующему подразделу. Нет - продолжайте читать!

Так значит, у вас нет системы багтрекинга?! Это надо исправить в первую очередь. Возьмите уже хоть какую-нибудь систему. Нет, не надо тут разводить долгих и скучных оценок и сравнений, просто возьмите любую, ведь любая система - это лучше, чем ничего. А вообще, прочитайте Joel's test: 12 steps to better code и трижды проверьте пункт 4.
Есть много систем, которые можно использовать:
  • Бесплатные: Bugzilla, Mantis, Trac
  • Коммерческие: Jira, OnTime, Rally, VersionOne
И много других.
Системы отслеживания запросов на изменения предназначены для отслеживания любых запросов (и ошибок), не ограничиваясь одними лишь ошибками.

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

Да, может показаться невероятным то, что вы до сих пор ничего подобного не делаете, однако запомните: никогда больше не делайте изменений в коде без соответствующей задачи. Не важно, исправляете ли вы ошибку, выравниваете кнопочку или же разрабатываете абсолютно новую фичу: создайте для них задачу!

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

Задача должна быть короткой!

Предполагается, что задачи должны быть короткими, как и исправления ошибок. Так что не заводите задачи, которые предполагается решать 3 недели. Разделите её на более короткие. Если вы более привычны к гибким методикам вроде Scrum, то вы сразу вспомните одно из ключевых правил, гласящих, что длительность задач надо держать не выше 16 часов. Думаю, это очень хорошее правило.

Жизненный цикл задачи

Схема ниже показывает, как работает жизненный цикл задачи, её взаимоотношение со всем процессом Scrum. Примечание: задачи, на которые я ссылаюсь, это те задачи, на которые разбиваются истории пользователей - user stories в терминологии Scrum - во время планирования спринта.



Контроль версий находится в самом центре схемы в качестве координатора картинки в целом, однако давайте посмотрим, каковы основные компоненты.

Задача


О чем это? Любой чих будет задачей, а задачи, как уже говорилось выше, управляются вашей любимой системой отслеживания. Что важнее, задачи возникают из списка пожеланий по продукту (заявок от клиентов, списка пожеланий, и т.п.)
Кто это использует? Все. Завести задачу может разработчик, также как и менеджер; тестеры могут найти ошибку, дефект и т.д.
Задача - это центральный элемент в координации проекта.

Ветка

О чем это? Это основа работы разработчика. Разработчики будут всегда работать на ветках, и никогда - на главной ветке (транке). Каждая задача будет всегда начинаться из хорошо известной точки, базовой конфигурации или стабильного релиза.
Кто это использует? Разработчики в повседневной работе. Интеграторы, когда надо создать релиз. Каждая задача тестируется и валидируется, прежде чем её метят как завершенную в системе отслеживания.

Интеграция

О чем это? Когда ряд задач закончен, самое время создать новый релиз. Помните, что "выпускайте пораньше, выпускайте почаще" - это лучшая практика для предотвращения "большого взрыва при интеграции", корня всех зол в мире SCM.
Кто это использует? Интеграторы. Интеграторами могут быть разработчики, играющие эту роль раз в неделю, раз в день - в зависимости от частоты создания релизов.
В больших проектах интегратор может быть полноценной штатной единицей. Они не только сливают изменения обратно на главную ветку, но и отвечают за то, что отстройка производится правильно. Поэтому они, вероятнее всего, бегло просмотрят код, зададут  вопросы разработчикам, если что-то не совсем ясно или ведет к конфликтам. Ответственность - вот ключевое слово, стоящее за ролью интегратора.

Примечание для маньяков continuous intergration: да, после continuous integration жизнь есть и, вообще говоря, ветки для задач, исправляют типичные упущения CI и переводят его на другой уровень. Пройдите по указанной выше ссылке и посмотрите на следующие шаги, упомянутые в книге Дюваля про CI.

Релиз

Что это? Результатом интеграции является новый стабильный релиз. "Стабильный" означает, что он прошел все тесты и не осталось ни одной известной ошибки (или все они хорошо известны).
Кто это использует? Вся команда. Как только релиз закончен, он может быть отдан команде тестирования (если таковая есть). Разработчики будут использовать свежевыпущенный релиз как отправную точку для новых задач, над которыми они будут работать во время следующего рабочего цикла.

Часто задаваемые вопросы

Вопрос: Ну так всё-таки, что же такое ветка для задачи?
Ответ: Вы, наверное, слышали про концепцию отладочных веток или веток для фич, не так ли? Ладно, даже если не слышали, ответ таков: это ветка, которую вы используете для решения задачи. Она кратковременна и её назначение - быть использованной для отдельной фичи или исправления ошибки.

Вопрос: Но ведь ветки - это зло?
Ответ: Да кто ж вам такое сказал? Вычитали наверное где-нибудь в руководстве или на форуме по Subversion, может даже на каком-то другом сайте по SCM, да? Ветки - это великолепный инструмент разработчика, но в большинстве систем контроля версий они неправильно реализованы - в том же CVS или Subversion, SourceSafe, Perforce, Team Foundation Server и многих других. А потом говорят, что ветвление - это нехорошо. Наглая ложь! Ветвление - отличная вещь, и надо использовать его ежедневно, вот только инструмент для него надо использовать правильный.

Это не про DVCS

В последнее время буквы DVCS (распределенные системы контроля версий) стали буквально заклинанием на программерских форумах. Благодаря Git и  Mercurial целые орды программеров заинтересовались распределенными системами и, что ещё важнее, ветвлением и слиянием. И хотя ветка на задачу - базовый сценарий работы для большинства практиков DVCS (включая Plastic SCM), это не означает, что он является следствием их распределенной структуры. Отнюдь - это лишь следствие того, что они хорошо работают с ветвлением и особенно слиянием.

Факты говорят за себя: хорошие распределенные системы хороши с ветвлении и слиянии, однако ветка на задачу - это не только из области распределения, их можно отлично сделать и в централизованных системах. Вот только большинство централизованных систем вроде Subversion, CVS, TFS, Perforce и им подобных не умеют обрабатывать ветки нормальным образом.

Почему ветка на задачу лучше?

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

Столкновение миров: последовательная разработка против параллельной

Давайте рассмотрим типичный проект, который работает по шаблону последовательной разработки, более известному как "разработка на транке" или "разработка на главной ветке". Он всего лишь означает, что все кладут (или "чекинят", от "check in") свои изменения на одну и ту же ветку. Подобный подход очень легко настраивается, очень легко понимается и именно ему следуют большинство разработчиков, использующих инструменты типа Subversion, CVS, SourceSafe и иже с ними.


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

В примере на схеме видно как Пэт (Pat) создает новую форму загрузки, но вносит ошибку через набор изменений 10476. После чего должна поправить её и чуть позже внести на главную ветку (cset:10478). Это значит, что отстройка была поломана между изменениями 10476 и 10478, а все, кто обновляет свои копии в промежутке между ними, будут затронуты этой ошибкой. Именно так, скорее всего, и произошло с Пабло (pablo) после того, как он внёс набор изменений 10477 и обновил свою рабочую копию.

Особо внимательные могли заметить, что мы смешиваем важные изменения в cset:10474 (большое изменение в одном из базовых запросов, которое может поломать приложение самыми экзотическими способами) и cset:10475. Что это значит? Это значит, что если бы нам надо было выпустить очередную версию системы, то базовая конфигурация получилась бы неготовой или недостаточно стабильной.

А теперь посмотрим, как этот сценарий выглядел бы при параллельной разработке.



Как видно, здесь задействованы несколько веток, поскольку каждая задача теперь - это отдельная ветка. А ещё есть стрелки слияния (зеленые такие) и базовые конфигурации (baselines, мы и раньше могли их создавать, однако с новым шаблоном их создание стало ещё понятнее). Взяв этот пример за основу, я пройдусь по проблемам, с которыми мы можем столкнуться при последовательной разработке, объясню как их поможет избежать параллельная разработка и почему эта модель лучше.

Код всегда под контролем

Как часто вы чекинитесь (вносите изменения в систему контроля), когда работаете на транке (при разработке на единственной ветке)? Спорим, вы прежде пять раз подумаете, потому как очень не хочется видеть коллег по работе, орущих на вас за то, что из-за ваших изменений отстройка упала?

Ну так вот, вы работаете над трудной задачей - сложные изменения, несколько дней работы - где вы храните код? Он под контролем версий? Скорее всего, нет, ведь вы не чекините код, который не компилируется, не закончен или конфликтует другими изменениями. Это немалая проблема и одновременно обычная вещь при применении единственной ветки: изменения долго находятся за пределами контроля версий до тех пор, пока разработчики не закончат работу. Контроль версий используется лишь как механизм доставки вместо полноценной системы.

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

Боковая панель - она же работала 5 минут назад!!! Наверняка с вами такое случалось: работаете над изменениями, код работает, что-то поменяли, всё поломалось и вы теряете время, пытаясь понять (обычно комментируя и раскомментируя куски кода), что же вы сделали не так. Такие вещи вполне обычны, когда вы экспериментируете, изучаете API или работаете над чем-то сложным. Если вы на своей ветке - почему бы не чекиниться после каждого изменения? Тогда вам не придется полагаться на (рас)комментирование кода для проверки вариантов работы.

Держите главную ветку нетронутой


Поломка отстройки - вещь достаточно частая при разработке на одной ветке. Чекините какой-то код, который не протестировали как следует - и вы уже не проходите какие-то тесты или даже хуже: код перестает строиться.

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

Имейте хорошие точки отсчета, не стреляйте по движущимся мишеням!

Когда вы работаете на единой ветке, то чаще всего трудно сказать, от чего ты ведете отсчет своей рабочей копии.

Позвольте пойти чуть дальше: как видно из картинки ниже, в какой-то момент вы обновляете рабочую копию с /main. Что это за момент? Это явно не BL130, потому что после неё были ещё некоторые изменения. Поэтому если появляется ошибка, какова её причина - предыдущие изменения или ваши?



Конечно, вы можете сказать: если использовать continuous integration, то всегда можно убедиться, что отстройка проходит нормально (при том, что это достаточно инертная техника - сначала ломаем билд, потом его чиним), поэтому что бы вы ни залили - оно будет в порядке. Да, вы правы, однако что это за конфигурация? Если обновиться в этот момент, то вы будете работать с промежуточной конфигурацией, чем-то малоопробованным... вы будете стрелять по движущейся мишени!

А сейчас посмотрите, как ситуация будет выглядеть при использовании ветки на задачу:


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

Заставляйте создавать базовые конфигурации

Создание базиса - это наилучшая практика. Использование базовых конфигураций займет  центральное место в вашей повседневной работе. Нет лучше способа внедрить и закрепить практику, чем поставить её в центр всего рабочего процесса.

Независимость задач

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

Почему они связаны? Потому что на каждый чекин, если вы изменили один из ранее измененных файлов, вам придется сливать вместе изменения из разных задач. И даже если изменяли не те же файлы, всё равно тестировались они вместе, поэтому есть нечеткая зависимость. Такого просто не бывает, если вы используете ветку на задачу.

Важно отметить, что при использовании веток усиливается весь процесс, ведь вы выбираете - что пойдет в следующий релиз (путем выбора веток для слияния) вместо того, чтобы брать всё, что есть на главной ветке.



Ветки как единица изменения

Давайте окунемся в глубины истории SCM: в начале не было никаких наборов изменений и вся работа делалась пофайлово. Не было нормального способа узнать какие изменения связаны с какой задачей, кроме ведения списков файлов в системах отслеживания ошибок, навешивания меток или же записи заметок об изменениях.

Потом на сцену вышли наборы изменений и жизнь стала налаживаться: теперь можно связать изменение 10474 с правками в запросе к БД. Зачастую система отслеживания запросов на изменения может хранить ссылку на набор изменений и наоборот. Проблема в том, что такой подход заставляет разработчика использовать наборы изменений как атомарные единицы изменений, а это не очень удачная идея. И вот почему: по определению набор изменений может содержать одну версию каждого файла или директории - и что если вам надо сделать более чем один чекин для одного файла по ходу работы над одной задачей? А нельзя. Так что всё кончится тем, что чекиниться будете редко, а это небезопасно. И это неправильно!

Ну а потом появилось следующее поколение систем SCM, которые могли правильно работать с ветвлением и слиянием. Вот поэтому сейчас, вместе с Plastic, стало возможным использовать ветки как нормальную единицу изменения. И ветки не ограничены числом версий файла или директории - пожалуйста, делайте коммиты так часто, как захотите!

Хватить распространять ошибки

Люди, имеющие отношение к опасным материалам, работают контролируемом окружении, обычно за закрытыми дверями, для того, чтобы предотвратить распространение катастрофических последствий, если таковые появятся. Мы можем у них многому научиться.

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




Теперь посмотрим на ситуацию с точки зрения "ветки на задачу". Ошибка всё равно будет, однако у нас есть возможность среагировать прежде чем она затронет главную ветку. Есть разногласия и есть стратегия по предотвращению.


Улучшенное отслеживание

Лучшее подтверждение - на практике: взгляните на ветку task115. Вы знаете, что это за задача в системе отслеживания запросов на изменения? Видимо, 115, да? Клёво. Есть связь. Достигнута полное отслеживание по шкале CMMi. Проще и быть не может.


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

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

Закругляемся!

Длинная получилась заметка!

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

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

48 комментариев:

  1. >Примечание: задачи, на которые я ссылаюсь, это не те задачи, на которые разбиваются истории пользователей - user stories в терминологии Scrum - во время планирования спринта.

    Я тогда не понял, на какие "задачи" Вы "ссылаетесь". На сами user stories ?

    Или еще что-то есть, помимо user stories и их декомпозиции ?

    >Взгляните на следующий пример: Пэт (pat) вносит ошибку, и сразу же все, кто работают с главной веткой, будут её затронуты.

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

    С другой стороны, не очень понятно, почему вдруг сразу и все будут затронуты.

    >Важно отметить, что при использовании веток усиливается весь процесс, ведь вы выбираете - что пойдет в следующий релиз (путем выбора веток для слияния) вместо того, чтобы брать всё, что есть на главной ветке.

    Это тоже не очень понятно. В главной ветке лежит то, что запланировано для текущей сборки. Т.е. задача занесена в backlog, произведена оценка, задача привязана к sprint backlog.

    С какой стати она не попадет в сборку-то ? Это ж все "проплачено", пользователи ждут и так далее.

    Как теоретический экзерсис такое можно понять, но на практике сталкиваться с этим не приходилось.

    >Ну так вот, вы работаете над трудной задачей -
    сложные изменения, несколько дней работы - где вы храните код? Он под контролем версий? Скорее всего, нет, ведь вы не чекините код, который не компилируется, не закончен или конфликтует другими изменениями.

    Это противоречит правилу "Задача должна быть короткой!"

    У меня такое ощущение что такой подход призван подпирать разработку с длинными задачами без следования принципам TDD. Т.е. так, как работает Линус Торвальдус :)

    ОтветитьУдалить
  2. > Я тогда не понял, на какие "задачи" Вы "ссылаетесь".

    Вот это я пролетел... ошибка в переводе :( и смысл поменялся на противоположный! Поправил, спасибо.

    > Так это хорошо - ошибка вылезет на самой ранней стадии.

    Если это ошибка компиляции, то будет поломана отстройка у всех, кто коммитится после неё (ведь они сделают update её исходников)
    Если ошибка функционала - аналогично.

    > Я бы вообще назвал это недостатком рассматриваемого подхода, в нем меньше вероятность выявить ошибку.

    Вероятность обнаружения - меньше. Код будет сливаться на транк - и при отстройке у интегратора (перед коммитом на транк) оно упадет - и транк останется нетронутым.
    Если же речь про заваленное тестирвание - ну так оно будет вестить опять же на ветке и транк вообще не пострадает от поломанной функциональности.

    > С другой стороны, не очень понятно, почему вдруг сразу и все будут затронуты.

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

    > С какой стати она не попадет в сборку-то ?

    Ну, если фичу ждет кастомер - то, конечно, попадет. Только сильно перед этим усложнит жизнь всем остальным :)

    > Это противоречит правилу "Задача должна быть короткой!"

    Там приводилась оценка - порядка 16 часов, это пара-тройка дней работы. 3 дня без коммита кода - это жесть :) можно ведь элементарно захотеть откатиться на тот код, который был точно работал на второй день, но который поломали на день третий. Причем вполне может быть так, что код будет доведен до состояния отстройки только на третий день, а предыдущие 2 дня - во временные папки сохранять? :)

    > У меня такое ощущение что такой подход призван подпирать разработку с длинными задачами без следования принципам TDD.

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

    ОтветитьУдалить
  3. >Если это ошибка компиляции, то будет поломана отстройка у всех, кто коммитится после неё (ведь они сделают update её исходников). Если ошибка функционала - аналогично.

    Смысла коммитить некомпилируемый код не вижу никакого. Если есть ошибка функционала, не покрытая тестами, то чем раньше она выявится, тем лучше. В том числе и ценой того, что у кого-то что-то сломается. Людям специально деньги платят, чтобы они ошибки искали, а тут "само" найдется. В такой формулировке не вижу вообще проблемы.

    Меняй формулировку (с)

    >Потому что при работе на транке перед коммитом надо проапдейтиться с тем, что было закоммичено последнее.

    Кому надо-то ? Я лично так делаю очень редко. Сбросил свое и ладушки.

    > Ну, если фичу ждет кастомер - то, конечно, попадет. Только сильно перед этим усложнит жизнь всем остальным :)

    Этого не понял. Я не припомню из своей практики выпуска сотни релизных сборок чтобы сделанную задачу исключали из сборки. Надуманный сценарий, на мой взгляд, вот про что речь. В мире linux - может быть это распространено :)

    > 3 дня без коммита кода - это жесть :) можно ведь элементарно захотеть откатиться на тот код, который был точно работал на второй день, но который поломали на день третий.

    На мой взгляд с такой практикой надо бороться, а не поощрять ее, применяя обходные технологии.

    При TDD, если классы loosely coupled ничего сломаться не может, если не коммитить специально то, что не компилируется и не проходит тесты.

    Более того - при таком подходе разработка в одном месте по определению слабо затрагивает другое.

    >Да и принцип TDD - он про качественную разработку, а не про СМ :) это вещи скорее ортогональные.

    Речь о том, что работа по принципам TDD устраняет необходимость в подходе одна ветка - одна задача. И должность интегратора заодно :)

    ОтветитьУдалить
  4. >Вот это я пролетел... ошибка в переводе :( и смысл поменялся на противоположный! Поправил, спасибо.

    Еще одна аналогичная ошибка:

    Было

    "(есть всё-таки обстоятельства, когда НЕ надо так часто ветвиться, однако это бывает не так "часто).

    Надо:


    "(есть всё-таки обстоятельства, когда надо так часто ветвиться, однако это бывает не так "часто).

    Шутка :)

    ОтветитьУдалить
  5. Для начала откомментирую пост про git branching model

    > Никаких проблем с этим никто не испытывает, в том числе и при определении впоследствии, зачем был сделан тот или иной коммит.

    ОК, по этому пункту возражений нет. Инструментальный костыль вместо отдельной практики :)

    > В tag делается копия по выпуску чтобы знать точный состав выпущенной версии.

    Это при том, что содержимое tags можно менять также, как и содержимое других директорий... :)

    > Теперь мне надо задним числом пофиксить что-то. tags\B82 - это уже своего рода "эталон", его трогать не нужно.

    Это то, что называется baseline. И SVN в данном случае просто никакой в плане его создания и поддержки. Отсутствие нормальных меток порождает вот такие вот полурешения типа создания веток, которые просто все договариваются не трогать. Ужас, в общем.
    Кстати, отсутствие нормальных веток, в том числе, и отвращает людей от излишнего ветвления.

    > Смысла коммитить некомпилируемый код не вижу никакого.

    Я к примеру хочу иметь возможность прерваться посреди процесса кодинга и сохранить свои изменения. И не хочу при этом следить за тем, компилится мой код или нет.

    > Кому надо-то ? Я лично так делаю очень редко. Сбросил свое и ладушки.

    Есть ревизия 123, с которой ты сдела себе экспорт в локаль. После этого люди понаделали ревизий для транка и текущая стала 132. Ты хочешь закоммитить 133. И что? SVN тебе говорт - твоя копия не up-to-date с последней, обновись-ка. Вот и вышло "при работе на транке перед коммитом надо проапдейтиться с тем, что было закоммичено последнее."

    > На мой взгляд с такой практикой надо бороться, а не поощрять ее, применяя обходные технологии.

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

    > Речь о том, что работа по принципам TDD устраняет необходимость в подходе одна ветка - одна задача.

    Согласно тебе, TDD вообще устраняет необходимость веток :))

    > И должность интегратора заодно :)

    Был я интегратором в начальной стадии одного продукта. Моторола тогда осваивала чипсеты Qualcomm для мобильников. Мне довелось быть контрактором от своей фирмы, который был в гуще событий. Представь пару сотен разработчиков, которые делают экстремальнейший перенос кода с двух платформ совместно на третью новую. И их усилия объединяются воедино в одной точке - интеграционной команде. Тогда код начал отстраиваться только через 3 или 4 месяца после того, как была написана его первая строчка. Ещё через какое-то время он перестал падать на линковке. Ещё через месяц - телефон начал полноценно запускаться. TDD, говоришь... Посмотрел бы на то, как волшебный TDD обошелся бы без интеграторов, одиними только мантрами про постоянную отстройку и автотесты... Адский адъ.

    Конечно, надо стремиться к тому, чтобы код полноценно строился и тестился перед попаданием изменений куда бы то ни было. Однако без веток это делать не так комфортно.

    Ещё раз приведу любимую цитату:
    "FAQ: But, weren’t branches supposed to be evil?
    ANSWER: Who told you that? I bet you found that on some Subversion guide, forum or manual, maybe even on some other SCM website, didn’t you? "

    :)

    ОтветитьУдалить
  6. >ОК, по этому пункту возражений нет. Инструментальный костыль вместо отдельной практики :)

    Ну я вижу проблему по другому :) Список почему-ветка-на-задачу теперь выглядит так:

    -не agile
    -больше кол-во параллельных версий
    -отсутствует инструментарий трекинга задач. вместо этого используются листочки/салфетки/гениальные головы/google wawe :)

    Наверное, ядро linux - типичный пример.

    >Это при том, что содержимое tags можно менять также, как и содержимое других директорий... :)

    Tag можно сделать в область, защищенную от записи. На практике достаточно организационных мер.

    >И SVN в данном случае просто никакой в плане его создания и поддержки. Отсутствие нормальных меток порождает вот такие вот полурешения типа создания веток, которые просто все договариваются не трогать. Ужас, в общем.

    С метками было бы лучше, согласен. Однако аналог метки делается одной быстрой операцией, т.е. практически имеем очень мелкое неудобство, не более.

    >Есть ревизия 123, с которой ты сдела себе экспорт в локаль. После этого люди понаделали ревизий для транка и текущая стала 132. Ты хочешь закоммитить 133. И что? SVN тебе говорт - твоя копия не up-to-date с последней, обновись-ка.

    Даже и не знаю....Нам она ничего такого не говорит. Мы пользуемся eclipse и "черепахой".

    >Я к примеру хочу иметь возможность прерваться посреди процесса кодинга и сохранить свои изменения. И не хочу при этом следить за тем, компилится мой код или нет.

    В этом редком случае да, надо сделать ветку. В SVN это делается легко, там есть branch с рабочей копий, далее commit и вуаля - мы в изолированной ветке.

    >Согласно тебе, TDD вообще устраняет необходимость веток :))

    Будем так говорить - следование Agile-практикам + трекер задач устраняют необходимость следования парадигме "одна ветка на задачу".

    >Представь пару сотен разработчиков, которые делают экстремальнейший перенос кода с двух платформ совместно на третью новую. И их усилия объединяются воедино в одной точке - интеграционной команде. Тогда код начал отстраиваться только через 3 или 4 месяца после того, как была написана его первая строчка.

    Это не попадает под Agile/Scrum/TDD и т.д., соответствено, моя аргументация нерелевантна.

    В таких случаях,наверное, ветвление необходимо.

    >Конечно, надо стремиться к тому, чтобы код полноценно строился и тестился перед попаданием изменений куда бы то ни было. Однако без веток это делать не так комфортно.

    Ну не знаю, нам очень комфортно. В чем некомфорт-то, конкретный сценарий каков, в котором нам будет более комфортно ветвиться на каждую задачу ?

    Тут интересно получилось. Мы решили перейти на git. Пока не удалось - два дня коллега бился с конвертацией репозитория ( 900Mb) - "не шмогла". Падает при конвертации.

    Ладно, решили попробовать "ветвится на задачу". С ветвлением особых проблем нет. Но у народа возник вопрос - а зачем, что это даст ?

    Я пока не виду ответа, кроме того, что можно несколько раз промежуточно сделать commit, прежде чем отослать в "центр".

    ОтветитьУдалить
  7. > -не agile

    Неправда. Посмотри сводную страницу по основам SCM - там есть ссылка на статью Version Control for Multiple Agile Teams, где ветвление используется именно в agile.

    > -отсутствует инструментарий трекинга задач

    Опять неверно... без трекинга задач практика ветка-на-задачу в принципе не осуществима :))))
    Да и где сейчас встретишь команду без трекинга?

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

    > Будем так говорить - следование Agile-практикам

    agile - не панацея, а лишь один из видов организации жизненного цикла работы над проектом. Ты ведь больше про TDD говоришь, а он к подобных вещам не привязан.


    > В таких случаях,наверное, ветвление необходимо.

    Вот и я об том - гибкими методиками решатся далеко не все проблемы организации работы :)

    > Ладно, решили попробовать "ветвится на задачу". С ветвлением особых проблем нет. Но у народа возник вопрос - а зачем, что это даст ?

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

    > Я пока не виду ответа, кроме того, что можно несколько раз промежуточно сделать commit, прежде чем отослать в "центр".

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

    ОтветитьУдалить
  8. >> -не agile
    >Неправда.

    А мы понимаем друг друга ? Я утверждаю, что если не agile, то надо ветвиться.

    >Опять неверно... без трекинга задач практика ветка-на-задачу в принципе не осуществима :))))

    Не виду препятствий. Scrum-доска, excel и вперед.

    http://scrum.org.ua/scrum-i-xp-zametki-s-peredovoj/
    "Мы так же пробовали использовать Jira (нашу систему учёта дефектов) для хранения product backlog’а. Но для большинства product owner’ов навигация по Jira была слишком обременительна. В Excel’е манипулировать историями намного проще и приятней".

    >agile - не панацея, а лишь один из видов организации жизненного цикла работы над проектом. Ты ведь больше про TDD говоришь, а он к подобных вещам не привязан.

    Я сделал индукцию с TDD на agile-практики. agile практики => TDD. Если эта импликация не работает, беру обобщение обратно :)

    >Вот и я об том - гибкими методиками решатся далеко не все проблемы организации работы :)

    Это вообще отдельная тема, по-моему.

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

    Здесь дело совершенно в другом. Я пока не видел подходящего аргумента, зачем нужно делать ветку на задачу, и прошу практического примера. Был, например, такой - "Самый простой пример - нельзя сказать по отдельно взятому коммиту на транке, зачем он был сделан".

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

    ОтветитьУдалить
  9. > Я утверждаю, что если не agile, то надо ветвиться.

    А я утверждаю, что если agile - то тоже надо ветвиться :)

    > Но для большинства product owner’ов навигация по Jira была слишком обременительна.

    Ну так может это проблема Jira а не вообще использования трекеров для бэклога?

    > В Excel’е манипулировать историями намного проще и приятней

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

    > Пример не сработал, ибо по любому коммиту я знаю, зачем был нужен - он привязан к задаче.

    Я в начале разговора упомянул, что если убарть из статьи упоминания поломаных билдов, то остальные аргументы вполне подойдут для обоснования - и даже перечислил их :) ОК, убираем аргумент про отслеживание привязки. Осталось ещё немало пунктов :)

    ОтветитьУдалить
  10. > А я утверждаю, что если agile - то тоже надо ветвиться :)

    Тезис понятен. Аргументация не очень понятна.

    Первое. Ты привел аргументы:

    1) "стрельба по движущейся мишени", "независимость задач"
    2) "ветки как единица изменения"
    3) "улучшенное отслеживание".

    Допустим, мы перейдем наg git и всегда будем делать ветку на каждую задачу. Я хочу услышать практический пример, где нам это поможет. Высказывание "ветка как еденица измерения" мне ничего не говорит, хотелось бы рассмотреть конкретный сценарий использования, user story, где мы получим выгоду.

    Пока мы делаем ветки только по мере необходимости.

    Второе. Вот реальная декомопозиция из нашего трекера по версии 5, затачивали трекер под Scrum.
    http://www.triniforce.com/img/gmp/scrum1.png

    В задачах декомпозиции задействовано три человека. Сколько веток мне надо делать и как организовать работу трех человек над этим ? Рекомендации, что прозвучали на хабре - типа сделать peer-to-peer между разработчиками, либо отдельный репозиторий, который потом слить с главным - просто ужасны.

    ОтветитьУдалить
  11. > Ты привел аргументы:

    Да, привел. Аргументы эти расписаны в самой статье, нет смысла их пересказывать. И я пока не услышал принципиальных возражений пока - чем они плохи :)

    > Я хочу услышать практический пример, где нам это поможет.
    ...
    > В задачах декомпозиции задействовано три человека.

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

    ОтветитьУдалить
  12. Этот комментарий был удален автором.

    ОтветитьУдалить
  13. >И я пока не услышал принципиальных возражений пока - чем они плохи :)

    Ну давай в духе Kanban ограничим число активных задач одной. Рассмотрим фрагмент:

    "В примере на схеме видно как Пэт (Pat) создает новую форму загрузки, но вносит ошибку через набор изменений 10476. После чего должна поправить её и чуть позже внести на главную ветку (cset:10478). Это значит, что отстройка была поломана между изменениями 10476 и 10478, а все, кто обновляет свои копии в промежутке между ними, будут затронуты этой ошибкой"

    Возражения.

    1) Это описание подходит и под "ветка-на-задачу". Все то же самое. Сделал ветку, сделал задачу с ошибкой, слил ветку.
    2) При следовании TDD коммитится код, прошедший компиляцию и тестирование. Если там таки есть ошибка, не покрытая тестами, то пусть она и выявится кем-то между 10476 и 10478, это гораздо дешевле, чем потом ее вылавливать у клиента.

    Выводы. Use case нечеткий. Описанное является скорее недостатком, ввиду того, что понижается вероятность выявления ошибки на стадии разработки.

    Еще раз оговорюсь - все это при условии Scrum + TDD

    ОтветитьУдалить
  14. > Все то же самое. Сделал ветку, сделал задачу с ошибкой, слил ветку.

    Не совсем. На транк версия сливается человеком с проектной ролью "интегратор" - этот человек слитые вместе ветки сначала отстраивает, затем отдает на регрессионные тесты (ну, в идеале). И тут уже вылезут и баги отстройки, и недостаток тестирования.
    Если всё делается одним человеком - конечно, ему проще будет всё это сделать у себя а машине и не заморачиваться.
    Я же рассматриваю изначально более сложный случай - задач много, людей много, посему есть роль интегратора.

    > Еще раз оговорюсь - все это при условии Scrum + TDD

    Да как угодно - ни одна практика не избавит до конца от сложностей в крупных проектам. А именно - совместное владение кодом, постоянная интеграция изменений, повышенный риск поломки отстройки и функционала.

    Хоть трижды протестируй у себя с помощью TDD изменения - как только они входят в соприкосновение с чужими изменениями - нужны более сложные практики, чем просто общий транк.

    ОтветитьУдалить
  15. >На транк версия сливается человеком с проектной ролью "интегратор" - этот человек слитые вместе ветки сначала отстраивает

    Боюсь я не очень теперь понимаю, какова структура центрального репозитария. Прямо в центальном репозитарии хранятся "ветки-на-задачу" ? И по этим веткам работает "интегратор", сливая их в trunk ?

    Если так, я привлекаю в качестве свидетеля Линуса Торвальдса.

    "Другая заморочка — это ветки. Даже если вы очень эффективно реализовали ветвления, сам факт того, что вы создаете ветки и каждый может их увидеть, потому что все централизовано, означает, что волей-неволей вам не захочется делать никаких веток.
    У вас будут проблемы с пространством имен.
    Как вы назовете свою ветку? Вы назовете ее «test»? Ага-ага, уже есть 5000 других веток, названных «test1», «test2», … «test5000», так что вам теперь придется выдумывать новые правила именования ваших веток, потому что у вас централизованная система с централизованным пространством имен у ветвей, что совершенно неизбежно при работе с централизованной системой"

    Совершенно согласен в данном вопросе с Линусом.

    ОтветитьУдалить
  16. > Боюсь я не очень теперь понимаю, какова структура центрального репозитария. Прямо в центальном репозитарии хранятся "ветки-на-задачу" ? И по этим веткам работает "интегратор", сливая их в trunk ?

    В случае с DVCS ветки могут лежать где угодно, например могут перед интеграцией пушиться в базу интегратора, результат мержа - сливается в основную базу.

    > У вас будут проблемы с пространством имен.

    Проблемы не будет, если именовать ветки по номерам задач в трекере, как и указано в статье.
    Вообще, порядок именования веток - он прописывается для всей команды сразу, чтобы девелоперу не думать, как бы ему обозвать свой бранч. У нас на мотороловских проектах, к примеру, было порядка 5-6 типов веток, каждая из которых имела свой формат. Девелоперу нужны были всего пара - бранч под задачу (CR branch вида crnumber_developerid_developersite_misccomment) и дебажный бранч (dbg_developerid_developersite_misccomment), для временных пробных решений. Выбираешь нужный - и вперед.

    > Как вы назовете свою ветку? Вы назовете ее «test»?

    Вот-вот, и я о том же - формат именования един для всего проекта. Ветки с именем вида "test123" - это квинтессенция бардака в СМе... Даже если каждый у себя локально в репо такие ветки будет создавать - через пару месяцев работы он утонет в этих test1, testX, test_one_more, fuck_this_test. Конечно, если не захочет их поубивать все :)))

    > Совершенно согласен в данном вопросе с Линусом.

    Разработка Линукса в данном случае далеко не эталон SCM. Такое броуновское движение исходников ещё надо поискать. Порядок поддерживается исключительно энтузиазмом интеграторов (ну или как там называют тех, кто принимает патчи). Убери энтузиазм и единоначалие в вопросах приемах патчей - всё рухнет, останется бардак, который поглотит проект.

    ОтветитьУдалить
  17. >В случае с DVCS ветки могут лежать где угодно, например могут перед интеграцией пушиться в базу интегратора, результат мержа - сливается в основную базу.

    Это "жесть". Вот смотри, статистика по нашей последней сборке:

    http://www.triniforce.com/img/gmp/summary.png

    168 задач, с учетом декомпозиции.

    Интеграционные тесты системы в сборе длятся 5 часов. 168 раз "проинтегрировать" проект ... это ужас, просто ужас.

    Ну, в целом понятно. Для случая ( Scrum + TDD ) где команда по определению:

    а) небольшая
    б) самоорганизуется
    в) код, попадает в базу только после прохождения unit-тестов

    такая технология попросту вредна - лишняя потеря времени.

    Конечно же, так мало кто делает в таких условиях. А делают вот так:

    http://scm-notes.blogspot.com/2010/09/successful-git-branching-model.html
    $ git checkout develop
    Switched to branch 'develop'
    $ git merge --no-ff myfeature
    Updating ea1b82a..05e9557
    (Summary of changes)
    $ git branch -d myfeature
    Deleted branch myfeature (was 05e9557).
    $ git push origin develop

    Т.е. разработчик самостоятельно сливает локальную ветку-на-задачу и удаляет ее

    ОтветитьУдалить
  18. Ну что ж, если команда может обосновать принятые ей практики - значит практики как минимум выстраданные и нелишние :)

    Главное - это периодически пересматривать сложившийся порядок и оценивать - стоит ли что-нибудь менять. В данном случае, я так понимаю, менять пока рано :)

    ОтветитьУдалить
  19. >Главное - это периодически пересматривать сложившийся порядок и оценивать - стоит ли что-нибудь менять. В данном случае, я так понимаю, менять пока рано :)

    Ну, когда проект начнет загибаться и мы отойдем от Scrum + TDD, тогда можно будет пересмотреть практику :)

    Надеюсь, причина, почему плохо 168 раз интегрировать, понятна.

    Еще раз подчеркну, что как только не выполняется условие Scrum + TDD, интегрировать, возможно, становится хорошо и правильно.

    PS: Отписался на оригинальной теме. У нас там аватары такие интересные - типа, русские идут.

    ОтветитьУдалить
  20. > Надеюсь, причина, почему плохо 168 раз интегрировать, понятна.

    Осмелюсь преложить интегрироваться чуть более часто ;)

    > PS: Отписался на оригинальной теме.

    :) Пабло после переписки когда мой перевод увидел - проникся и выпустил этот текст отдельным white paper! Спецрассылку сделал на кастомеров! Я туда тоже вошел, т.к. качал Plastic на evaluation для написания заметки сюда в бложик.

    Хороший продукт. Жаль, что платный :)

    > У нас там аватары такие интересные - типа, русские идут.

    "Снайпер бьёт издалека, но всегда наверняка!"

    ОтветитьУдалить
  21. Переходим к следующему вопросу.

    Имейте хорошие точки отсчета, не стреляйте по движущимся мишеням!
    Как видно, здесь большая разница: все задачи начинаются из одной хорошо известной отправной
    точки


    Вернемся к примеру:
    http://www.triniforce.com/img/gmp/scrum1.png

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

    Как ты представляешь себе работу вместе с интегратором в этом случае ?

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

    Но это противоречить концепции "ветка-на-задачу" и декларациям:
    -Задача должна быть короткой!
    -Правило для применения: всё, что угодно, может быть задачей - любое изменение, которое делается в коде, имеет соответствующую задачу.

    ОтветитьУдалить
  22. Aquary комментирует...
    >> Надеюсь, причина, почему плохо 168 раз интегрировать, понятна.
    >Осмелюсь преложить интегрироваться чуть более часто ;)

    Вот так и "пилится бабло" :)

    После каждой из 168 задач запускать пятичасовые интеграционные тесты и при этом настаивать на увеличении частоты этого процесса - это ж одному интегратору не справиться, конечно, тут помощник нужен (c)

    ОтветитьУдалить
  23. > Можно "отстрелить" верхнюю задачу в отдельную ветку, туда пустить трех разработчиков, а потом ее уже "проинтегрировать" - это разумный сценарий.

    Верхнюю задачу разбей на более мелкие - и нормально.

    > После каждой из 168 задач запускать пятичасовые интеграционные тесты

    Я говорил о тем, чтобы интегрировать не 168 за раз (и уж тем более не 168 раз по разу), а кусками по несколько десятков. Во-первых, интегрировать (мёржить) за раз меньше, во-вторых, фича-тестов меньше гонять, т.к. фич меньше., в третьих, и риска поломать приложения - тоже в разы меньше.

    > Вот так и "пилится бабло" :)

    По твоему, Яндекс тоже пилит бабло? :))

    ОтветитьУдалить
  24. >По твоему, Яндекс тоже пилит бабло? :))

    Я думаю, у них не Scrum + TDD

    ОтветитьУдалить
  25. >Я говорил о тем, чтобы интегрировать не 168 за раз (и уж тем более не 168 раз по разу), а кусками по несколько десятков.

    И это звучало как "Осмелюсь преложить интегрироваться чуть более часто" (чем 168 раз) :)

    Но в целом мысль понятна. Т.е. есть очень умный дядя, который декомпозирует очередную задачу из backlog, ага, тут у нас есть серверная часть, клиентская, значит так - Петя делает прототип серверной части, чтобы Вася мог ими воспользоваться, затем сбрасывает прототип, я все тщательно проверяю, этот прототип сливаю с trunk, затем Вася "догоняет" trunk и начинает работать над GUI, затем Петя доделывает серверную часть, сбрасывает ( заметим - два коммита уже по серверу ), я все тщательно проверяю, делаю слияние, потом Вася опять "догоняет" trunk, доделывает GUI, сбрасывает, я еще более тщательно все проверяю, интегрирую, и ага, все в trunk, можно проверять (три commit).

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

    Это все понятно, в каких-то условиях - применимо, и возможно, где-то так и работают. Но это не Scrum.

    ОтветитьУдалить
  26. > Я думаю, у них не Scrum + TDD
    ...
    > Это все понятно, в каких-то условиях - применимо, и возможно, где-то так и работают. Но это не Scrum.

    Ну так ведь не обязательно у всех должен быть Скрам и ТДД. Вот у Яндекса, к примеру - да, нет всех этих страшных слов. Более того, в некоторых командах точно также не практикуется разбиение на ветки. Однако это не из-за перечисленных тобой причин, а из-за причин совершенно других. Но! Тем не менее у них есть роль интегратора и они сильно ищут отдельного челвека, котроый мог бы им быть full time. И связано это не со сложностью интеграции кода, а со сложностью процесса deployment'а.

    В общем, Скрам и ТДД ради скрама и тдд - не должно быть целью совершенствования процесса. Это не серебряная пуля.

    И СМный процесс - в нём точно также не может быть одного универсального рецепта. Однако есть практики, к которым чаще всего приходят многие команды. Ветка-на-задачу - это одна из таких практик. Не универсальная, нет, но - чаще всего востребованная.

    ОтветитьУдалить
  27. Кстати, наверное видел уже
    http://habrahabr.ru/company/microsoft/blog/105462/

    Тут тебе и Scrum, и механизм веток, который органично встроен в MS TFS. Про там ветки не сказано напрямую, но в TFS задачи по дефолту привязаны к веткам. Так что смею предположить, что ветки всё-таки используются :)

    ОтветитьУдалить
  28. > Ну так ведь не обязательно у всех должен быть Скрам и ТДД.

    Это бесспорно.

    >Тем не менее у них есть роль интегратора и они сильно ищут отдельного челвека, который мог бы им быть full time.

    Думаю, у них не Scrum + TDD

    > Ветка-на-задачу - это одна из таких практик. Не универсальная, нет, но - чаще всего востребованная.

    Предположу, что чаще всего востребован вот такой вид этой практики:

    http://scm-notes.blogspot.com/2010/09/successful-git-branching-model.html
    $ git checkout develop
    Switched to branch 'develop'
    $ git merge --no-ff myfeature
    Updating ea1b82a..05e9557
    (Summary of changes)
    $ git branch -d myfeature
    Deleted branch myfeature (was 05e9557).
    $ git push origin develop

    Т.е. разработчик сам осуществляет слияние ветки и сам ее удаляет.

    ОтветитьУдалить
  29. > Я бы вообще назвал это недостатком рассматриваемого подхода, в нем меньше вероятность выявить ошибку.

    Думаю, нужно учитывать не только вероятность выявления ошибки, но цену, которую вы готовы за нее платить.

    Допустим в вашей команде 3 человека, которые работают достаточно независимо: Пэт, Вася и Вова. Пэт сделала ошибку и скоммитила. Вася счекаутил, запустил билд, обнаружил аномалию и сказал про это Пэт. На все-про-все Вася потратил 15 минут. А Вова в это время выше покурить и ничего не заметил. В остатке, глюк найден и исправлен за 15 минут. Профит.

    Допустим в вашей команде 50 человек: Пэт, Вася, Вова и 47 китайцев-трудоголиков. Пэт сделала ошибку и скоммитила. Далее по индукции. Вася и 47 китайцев счекаутили, запустили билд, обнаружили аномалию и сказали про это Пэт. На все-про-все каждый из них потратил 15 минут. Глюк найден и исправлен. Но. Китайцы в сумме отъели 12 часов, а ещё Пэт потратила пол дня, чтобы прочитать кучу сообщений об ошибке, используя русско-китайский словарь, и написать ответы. Итого, порядка 16 человеко-часов. Возможно, вы сочтете, что это слишком дофига за 15-минутную веселуху. Для того, чтобы такие казусы случались как можно реже, и нужно как-то локализовывать изменения. Например, используя независимые бранчи. Тогда, на сэкономленные средства, вы сможете нанять необходимого интегратора, дюжину тестировщиков и при этом всё еще останетесь в профите. :)

    ОтветитьУдалить
  30. >Допустим в вашей команде 50 человек:

    Тогда это будет уже не Scrum, тут другие технологии. В том числе и ветка-на-задачу (в центральном репозитории, замечу, по данной статье) с интеграторами.

    ОтветитьУдалить
  31. > Тогда это будет уже не Scrum

    Разве Скрам не работает в больших командах?

    ОтветитьУдалить
  32. >Разве Скрам не работает в больших командах?

    Если рекомендованного размера scrum-команды ( до 9 человек ) мало, то лучше завести несколько команд.

    Например: "Допустим, у вас одна Scrum-команда из 12 человек, которую нереально разбить на две независимые команды только потому, что исходный код страшно запущен. Вам придётся приложить максимум усилий, чтобы отрефакторить (вместо того чтобы клепать новый функционал) исходный код до такой степени, чтобы над ним могли работать независимые команды."

    Cмысла в большой команде для scrum нет - она должна самоорганизоваться.

    ОтветитьУдалить
  33. > Тогда это будет уже не Scrum, тут другие технологии.

    Мм.. Scrum в команде из 50 человек.. это должно быть весело... :)

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

    Если такие кусочки, функционально зависят от проекта, то данная идея понятным
    образом выражается в виде отдельных бранчей внутри репозитария, и мы закономерно
    приходим к схеме "задача - бранч". В таком случае, багфиксы для ошибок,
    найденных в корневых бранчах, придется оперативно мержить в несколько веток.
    Следовательно они так же будут оформляться бранчами. Но это уже техника.

    Если же куски функционала, полученные при декомпозиции, не зависят от проекта,
    то мы приходим к компонентам, для которых имеет смысл поднимать собственные
    репозитарии. "Задача - репозитарий" -- так тоже бывает. :)

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

    ОтветитьУдалить
  34. >В таком случае, их можно разрабатывать параллельно (тем самым сократив сроки в реальном масштабе времени), мелкими командами, практикующими Scrum. ;)

    И чтобы объединить их усилия требуется дополнительное звено - интегратор, релиз-инженер и т.д. Тут, конечно, возможны всякие подходы.

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

    Я схожий по смыслу пример приводил
    http://www.triniforce.com/img/gmp/scrum1.png

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

    Но статья недвусмысленно против такого варианта - она предлагает как раз "мельчить".

    ОтветитьУдалить
  35. > И чтобы объединить их усилия требуется дополнительное звено - интегратор,
    > релиз-инженер и т.д.

    Согласен. Кстати, в OpenSource проектах, такую роль часто играет автор или
    ответственный разработчик (maintainer). В проектах с коллективным управлением —
    core-team.

    > Но статья недвусмысленно против такого варианта - она предлагает как раз
    > "мельчить".

    У меня осталось такое же впечатление. Мне кажется, что идея актуализировать их
    "на каждый чих", представляет исключительно теоретический интерес (скажем, как
    идеальный газ) :) Ведь с каждой задачей связаны не нулевые накладные расходы:
    завести в баг-трекер, создать бранч, дойти до разработчика, чтобы объяснить
    нюансы и т.д.

    ОтветитьУдалить
  36. > Ведь с каждой задачей связаны не нулевые накладные расходы:
    завести в баг-трекер, создать бранч, дойти до разработчика, чтобы объяснить
    нюансы и т.д.

    Завести задачу - минута. Завести ветку - одна команда. Объяснять нюансы - так ведь разработчик и так их знает, тут лишь вопрос заведения отдельной записили или её незаведения.
    Расходы, по-моему, стремятся к нулю :)

    Но соглашусь, что на каждый чих заводить таки не надо - и об этом также есть в статье.

    ОтветитьУдалить
  37. >Объяснять нюансы - так ведь разработчик и так их знает

    Откуда, интересно ? Если он знает ньюансы, он сам все сделает, ему не нужен интегратор.

    >Расходы, по-моему, стремятся к нулю :)

    Сомнительно. Декомпозировать полсотни задач, выявить зависимости, объяснить разработчикам порядок действий по декомпозиции, все это тщательно отслеживать и интегрировать - это специально выделенный человек должен быть.

    >Но соглашусь, что на каждый чих заводить таки не надо - и об этом также есть в статье.

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

    ОтветитьУдалить
  38. > Декомпозировать полсотни задач, выявить зависимости, объяснить разработчикам порядок действий по декомпозиции

    Так ты что предлагаешь - пусть эта полсотня задач будет одной огромной задачей, которая будет интегриться сразу на транк?

    ОтветитьУдалить
  39. >Так ты что предлагаешь - пусть эта полсотня задач будет одной огромной задачей, которая будет интегриться сразу на транк?

    Зачем же такие крайности.

    1) Вместо максимы "ветка-в ЦР-на-задачу" я предлагаю практическое "ветка-в ЦР-где-нужно".
    ЦР = центральный репозиторий.
    2) Роль интегратора веток в ЦР для Srum + TDD считаю излишней. Если команд несколько - это другое дело.
    3) Практику ветка-на-задачу в локальном репозитории всячески поддерживаю.

    ОтветитьУдалить
  40. Ну, стало быть, на этом и сойдемся :) Потому как считаю, что практика эта не должна быть завязана на методологию - Скрам это будет или что-то ещё.

    Повторюсь, если для твоего проекта отсутствие веток не мешает работе - значит они пока там не нужны :) Сответственно, интегратор пока тоже не особенно нужен.

    ОтветитьУдалить
  41. >Потому как считаю, что практика эта не должна быть завязана на методологию - Скрам это будет или что-то ещё.

    Статья-то связывает практику со Scrum, и как раз в этой методологии от нее больше вреда, чем пользы.

    > Повторюсь, если для твоего проекта отсутствие веток не мешает работе - значит они пока там не нужны :)

    Ну почему же - у меня ветки в ЦР есть - там, где они нужны.

    ОтветитьУдалить
  42. Почему-то захотелось дать коммент юмора http://mazda.drom.ru/scrum/
    ;)

    У меня с понедельника отпуск, так что с пятницей ;)

    ОтветитьУдалить
  43. Да, "Мазда Скрам" это прикол :)

    Когда обратно ? А то у меня вопросы накопились :)

    ОтветитьУдалить
  44. Да я никуда не деваюсь, так что комменты как обычно открыты :)
    Вот только тут комментов уже целая простыня, блогспот с ними ужасно работает. А так - велкам.

    ОтветитьУдалить
  45. Перечитал все, что я тут написал ранее... даааааа, век живи, век учись. Стереть бы :)

    ОтветитьУдалить
  46. Слово "отстройка", которое часто упоминается в статье, мне режет слух, по-русски
    это сборка. В остальном, ветка на задачу, хороший подход, который стал реализуем в реальном производстве благодаря появлению DVCS.

    ОтветитьУдалить
    Ответы
    1. По сборке - согласен, так лучше. Это жаргонизм, который в тот момент я использовал в работе.

      Насчёт DVCS - тут не соглашусь. Практика "ветка на задачу" применялась у нас ещё когда DVCS только в зачатке была. В частности, в ClearCase (истинно централизованная VCS) работа с ветками - просто песня.

      Удалить