Структура Mercurial Repository для функций, стабильных выпусков и т. Д.

Я буду более конкретен с вопросом, если мне нужно будет, или сделаю это в вики сообщества, если вы все думаете, что это подходит, но мой вопрос:

Моя команда разработчиков недавно начала использовать Mercurial (перешла из Subversion), и до сих пор нам это нравится. Мне интересно, есть ли ресурс «передовой опыт» об архитектуре репозитория. Что меня интересует, так это то, как лучше всего оставить стабильную копию репозитория (для доставки / исправления ошибок в чрезвычайных ситуациях) во время работы над функциями и новыми версиями. Я много читал об именованных ветках и клонированных репозиториях, и я надеюсь, что некоторые из вас, ребята, смогут пролить свет на то, что работает для вашей команды.

Что проще объединить после того, как функция была протестирована и готова к следующему выпуску? Есть ли серьезные недостатки у двух упомянутых мной методов? Существуют ли другие стратегии управления репо?

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

Позвольте мне перефразировать некоторые основы, с которыми я все еще борюсь. Допустим, я заканчиваю 2.0.0 завтра ... Я хочу начать работу над 2.1.0, что мне делать? Клонируйте мое репо, назовите его «работа / проекты / виджеты2.1» и продолжайте двигаться вперед, готовый к использованию в ситуациях исправления ошибок мой «рабочий / проекты / виджеты2.0»?

Кроме того, если клиент звонит и говорит, что есть ошибка, и машина с виджетами трясется и дым начинает подниматься, нужно ли открывать виджеты 2.0, исправлять ошибку, развертывать на сервере, а затем фиксировать / нажимать? Могу ли я затем вернуться к widgets2.1 и вытащить / объединить исправление ошибки?


person IniTech    schedule 02.10.2010    source источник
comment
Ответ на этот вопрос может быть тем, что вы ищете. Также ознакомьтесь с этим блог posts.   -  person anton.burger    schedule 03.10.2010


Ответы (4)


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

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

Имея это в виду, я дам несколько общих предложений по рабочему процессу между ветвями, независимо от того, как они представлены в Mercurial (в виде отдельных репозиториев, именованных ветвей и т. Д.). Если вы хотите узнать больше о том, какую модель ветвления выбрать, я предлагаю вам прочитать Руководство Стива Лоша по ветвлению в Mercurial и мое сообщение в блоге на выбор модели ветвления в Mercurial.

Во-первых, даже без каких-либо веток вы всегда можете вернуться к более ранней версии кода, например. версии 2.0 и исправьте там ошибку. Это позволит легко пометить и выпустить новую версию (скажем, 2.0.1) с единственным изменением, которое будет исправлено.

Вы делаете это, просто обновляя, исправляя и фиксируя:

$ hg update 2.0
hack hack hack
$ hg commit -m "Fix nasty bug"
$ hg tag 2.0.1

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

Это даст вам две головы, которые вы можете объединить с hg merge, вернув исправление в разрабатываемую версию.

Если у вас есть отдельный репозиторий для выпуска 2.0, вы вносите исправление в него, а затем переносите его в репозиторий разработки, где затем выполняете слияние. Базовый принцип - это тот, который изложил Ry4an: вы вносите изменение там, где еще не было внесено множество других изменений, которые вам не нужны.

Вот пример:

Там, где я работаю, у нас много репозиториев, представляющих разные отрасли. Большая часть разработки происходит в ветке "dev". Когда приближается выпуск релиза, мы клонируем этот репозиторий в новый под названием, скажем, «release-2.4». В этой ветке / репозитории мы тестируем и исправляем ошибки для предстоящего релиза. Дополнительные экспериментальные разработки, которые не будут готовы до следующего релиза, могут происходить параллельно в «dev».

Когда релиз протестирован и готов к выпуску, мы перетаскиваем все из «release-2.4» в «prod», которое содержит только выпущенные версии кода. Мы помечаем его номером версии и выпускаем для всего мира. Затем мы можем удалить ветку «release-2.4» и перенести все из «prod» в «dev». Для этого может потребоваться слияние, но тогда мы вернем все изменения, внесенные в процессе выпуска, в «dev» и можем продолжить работу над следующим выпуском.

Если мы хотим исправить ошибку, выходящую за рамки запланированных более крупных выпусков, мы можем сделать это двумя способами. Если исправление невелико (пара коммитов) или в нем не участвует много разработчиков, мы можем просто зафиксировать его прямо в «prod», пометить выпуск и отправить его. После этого мы перетаскиваем из «prod» в «dev», чтобы убедиться, что исправление присутствует и в следующем выпуске.

Если выпуск с исправлением ошибок больше и займет больше времени, мы можем вместо этого создать новую ветку на «prod», проделать всю нашу работу над выпуском там, а затем перенести изменения в «prod». Когда он выпущен в «prod», мы можем «вытащить» из «prod» в «dev», чтобы получить там изменения. Затем специальную ветку выпуска можно удалить.

person Joakim Hårsman    schedule 16.10.2010
comment
Спасибо за все ответы - мы пошли с чем-то очень похожим на это с моделью с 3 репо (стабильная, разработанная и предварительная версия), и она работает хорошо. - person IniTech; 26.10.2010
comment
+1 Я нашел этот ответ наиболее информативным. Я также рекомендую людям прочитать ваш блог на эту тему. - person Beyers; 25.01.2011

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

hg update 400
vi .... # fix bug
hg commit

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

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

Перенос изменения без его предков требует "выбора" одной формы другой посредством импорта / экспорта, трансплантации или какого-либо другого внеполосного механизма.

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

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

person Ry4an Brase    schedule 02.10.2010
comment
См. Мое пояснение выше. Вы говорите, что я исправлю ошибку в наборе изменений, который был впервые введен (даже если это было, когда репо было перенесено из svn - набор изменений 1), а затем перенесу это исправление в свою экспериментальную ветку, где я работаю над всеми видами сумасшедших вещей? - person IniTech; 02.10.2010
comment
@IniTech: только если вам это нужно в экспериментальной ветке (то, что я называю функциональной веткой в ​​своем ответе). Если вам не нужно это конкретное исправление - просто оставьте его в покое! - person dls; 02.10.2010

Вот одно хорошее руководство по "структуре":

http://hginit.com/05.html

Я тоже начал использовать Mercurial после того, как хорошо познакомился с Subversion, и меня вполне устраивает этот переключатель - hg определенно решил для меня некоторые проблемы. Я в основном не заморачиваюсь ни с одной из «именованных ветвей» и просто полагаюсь на головы в выполнении моей работы. Я убеждаюсь, что использую журнал адекватно, чтобы выяснить, куда мне нужно перейти, когда мне нужно вернуться к более старой версии. Конечно, теги тоже действительно хороши, и об этом рассказывается в руководстве.

person Andrew    schedule 02.10.2010
comment
Да, я читал статью Джоэла (вероятно, это было то, что заставило меня перебороть решение о переходе на DVCS). Он не особо обращает внимание на именованные ветки и клонированные репозитории, хотя у меня такое чувство, что он склоняется к последнему. См. Мое пояснение к вашему ответу. - person IniTech; 02.10.2010
comment
@IniTech: вы, вероятно, обнаружите, что несколько руководств и даже некоторые инструменты обходят именованные ветки. Это совершенно функциональная функция Hg, но она не обсуждается так часто, как повторное клонирование. - person dls; 02.10.2010

Компания, в которой я работаю, увлекается переходом на Mercurial и думает о поддержке «ветвей функций» для каждой разрабатываемой функции. Ветвь функции - это именованная ветка, которая содержит либо некоторые новые разработки, либо обновления существующей функции - в основном, все, что вы хотите.

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

Как только общее репо будет обновлено до уровня стабильности, его можно пометить и выпустить. Исправления ошибок могут быть применены к помеченной версии, и если требуется длительная или параллельная разработка, может быть создана вторая активная ветвь разработки с помеченной версией в качестве родительской. Здесь также можно применить метод исправления ошибок Ry4an.

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

измените, чтобы ответить на ваш недавно добавленный конкретный вопрос

Допустим, я завтра закончу 2.0.0 ... Я хочу начать работу над 2.1.0, что мне делать?

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

Кроме того, если клиент звонит и говорит, что есть ошибка, и машина с виджетами трясется и дым начинает подниматься, нужно ли открывать виджеты 2.0, исправлять ошибку, развертывать на сервере, а затем фиксировать / нажимать?

Исправления для 2.0.0 можно было бы сделать путем обновления до набора изменений 2.0.0 (т. Е. Тега) и последующего создания новой именованной ветки (возможно, с названием version2.0.0). Эта ветвь никогда не объединяется полностью с ветвью default, которая теперь перешла на разработку 2.1.0, и эта ветка, вероятно, останется открытой на неопределенный срок. Он будет содержать любые исправления на основе 2.0.0.

После того, как вы исправили ошибку 2.0.0, есть несколько способов переместить конкретный chagneset из 2.0.0 в ветку default (2.1.0). Вы можете создать патч для определенного набора изменений и применить его к ветви default, или вы можете выполнить слияние от версии 2.0.0 до default если это имеет смысл.

person dls    schedule 02.10.2010
comment
Есть одна вещь, которую я не понимаю в вашей модели. Давайте вернемся к тому экстренному исправлению 2.0.0 ... Я предполагаю, что мне придется клонировать тег 2.0.0 и внести исправление, верно? В противном случае куча вещей, включенных в мою линию разработки 2.1.0, будет включена во все библиотеки DLL, которые мне нужно будет отправить с этим исправлением ошибки. Думаю, я просто не понимаю, как я начинаю с 2.0.0 и только с кодом 2.0.0, делаю изменения и продвигаюсь в производство без включения кода 2.1.0 в сборки. Может, мне просто не хватает чего-то фундаментального об именованных ветвях ... - person IniTech; 04.10.2010