Pull to refresh

Comments 59

есть несколько типов релизов:
— обычное обновление раз в неделю
— выкатывание неких глобальных изменений

В первом случае теги не ставятся, во втором случае ставятся в формате 1.1, 1.2, 1.3 и т.д. В приложении отображается номер тега и номер билда в формате 1.1.112, 1.1.113
Вообще, первый и второй случай, как правило, лишь различаются мажоными и минорными наименованиями тегов. Недельные можно поменять номером недели, и, если были какие-то критические ошибки, буквой, например, 1.5.14a, 1.5.14b, где цифра 1 — первая версия конечного продукта, 5 — некая промежуточная версия, с новыми фичами и прочим, 14 — номер недели, a и b — буквенная нумерация релиза, так как, по идее, редко бывает больше релизов каждую неделю, которые исправляют какие-то баги.
Ох, не нравится мне 13й пункт
Всегда приходится идти на компромисы между красотой и удобством. Я пробовал вводить отдельную ветку для пред-релизных исправлений, и только после регрессии вливать ее в master. С одной стороны это правильно, но это занимало больше времени и кроме этого (и самое важное) — регрессионное тестирование тогда ведется не на том билде, который попадает на production
Зачем сливать master в dev? там может появиться множество конфликтов.
Слейте в dev, а потом сделайте cherry-pick в ветку, отведенную от мастера и влейте её в мастер.

Кстати, у нас схема подобная, только ветка, в которой ведется разработка — master, а на каждый релиз от неё отводится новая ветка, которая потом никуда не сливается.
CI должен собирать все ветки, а не ждать, пока изменения смержат в Dev.

А так нормально. У нас разработка в мастере, а релизы в отдельных ветках, для каждого энва свои ветки. Используем бранчи, а не таги, т.к. бывают всякие случаи, когда коммиты приходится с мастера черрипиком переносить. Например, когда одна из фич должна попасть в релиз, а какая-то другая — еще нет.
Веток может быть очень много. К примеру 6 разработчиков коммитят свои изменения в свои ветки. Собирать каждую на каждый пуш на гитхаб слишком накладно по ресурсам.
Вы преувеличиваете. У нас в компании 100+ репозиториев, в каждом 2 основные и ~ 15 разработческих веток, ~ 350 пушей в день. Собирается каждая ветка. С этим всем, прекрасно справляются всего 2 ноды сборки.
Это совсем не проблема, темболее если аутсорсить CI на сервис типа circleci.com (рекомендую).
У нас несколько десятков разработчиков, у каждого за день проскакивает по три-четыре ветки, и в каждую улетает по несколько пушей, собирается четыре билда для каждого пуша, и сборочная ферма справляется.
За «git push -f» вас переодически будут вспоминать «добрым» словом. Особенно, если ошибётесь с текущей веткой и веткой куда форсируете push.
Если есть опасения, что кто-то что-то сломает, то можно делать merge вместо rebase, и пушить без -f. Но у меня за год случился только 1 случай, когда разработчик ошибся. Исправили очень быстро и безболезненно.
Преимущество — чистая история без двойных мержей. Кроме этого rebase можно делать больше одного раза, и история будет выглядеть однозначно понятной и удобной для чтения
Я не против rebase'а, я против «push -f». Переименуйте ветвь (или push-нете её с новым именем), а потом делайте ff-only сколько влезет.
Это требует больше времени, шагов, внимания разработчика. И кроме того, как показала практика, в push -f в dev ветку нет ничего страшного. Если даже что-то случилось — всегда есть build сервер с последней версией dev
Чем линейная история понятнее дерева? В дереве точно видно что две фичи делались параллельно, а в случае линейной это можно отследить только по датам, которые, кстати будут перепутаны. К тому же, вы пишете про достаточно небольшие команды, Так что у вас скорее всего не будет больше 10 параллельных бранчей.

Вот кстати хорошие посты были про rebase habrahabr.ru/post/179123/ и habrahabr.ru/post/179673/.
У нас в районе сотни параллельных бранчей, тоже активно используется rebase, ничего не напрягает.

Кстати, rebase тут нужен, чтобы чистый merge происходил на сервере в процессе pull request. Если оказывается, что при мердже возникает конфликт, значит pull request не будет вмерджен, пока его не отребэйзят на свежее состояние ветки.
Ну не обязательно ребэйзить — можно и замержить (в данном случае dev на feature). Если потом будет фастфорвард так и никаких двойных мержей не будет.
В наших условиях не реально — в любом случае придется ждать сборок, а это еще часа два, если очередь пустая, а значит кто-то наверняка успеет что-нибудь вмерджить.
Если кто-то успеет вмержить то чем поможет ребейз? Придется ж ребейз переребейзить.
Обычно еще нужно такое понятие как «Hot Fix». Это когда на боевом сервере нужно срочно что то исправить и добавить это изменение в «dev» чтобы не потерялось. На этот счет вот эта методика http://habrahabr.ru/post/106912/ это лучшее что я видел. Для автоматизации всего этого есть gitflow, еще можно использовать клиент SourceTree, в него эта методика уже встроена.
Вы практически изобрели git flow

push -f после rebase… конечно, Вы получите более изящную структуру истории проекта, но можете получить и неприятности(сам с подобным сталкивался). Лучше уж сливаться.
git flow сложнее, я пробовал его применить, но так мне показалось проще. Кроме этого на практике все работает отлично.
можете рассказать, какие возникли сложности с gitflow?
В чём смысл разделения master и dev ветки, если можно пользоваться тэгами?
Смысл в том, что релизы обычно отстают от разработки. Допустим релиз тестируется неделю перед выходом в продакшн. Всё это время в dev ветке идёт разработка. Затем релиз уходит в продакшн, и на нём обрануживается баг, который необходимо исправить срочно. От master-ветки создаётся некий hotfix-branch, вносится правка, а затем мёрджится в master и в dev. В случае с тегами это будет не так удобно и прозрачно.
Поддерживаю, немного пояснения как у нас:

  • 1 ветка master и теги, а все активности в gerrit
  • в геррите можно
    • создавать патч
    • обновлять патч (заливать новый патч сет)
    • смотреть изменения в между патч сетами одного пуша
    • строить цепочку патчей
    • зачекаутить или зачерипикать любой патч или патчсет и залить новый патч сет
    • ревьювить код
  • для новой фичи берется либо мастер, либо существующий патч
  • когда патч хороший он мержится в master (когда плохой нужно залить новый патч сет с разрешенными конфликтами), для релизов делаются теги
  • для каждого пуша проходят тесты и может собираться рабочая версия (тк веб и в планах собирать рабочую версию автоматически)
ну и зачем тогда git?
gerrit работает с git, все патч сеты это отдельные git ветки в gerrit, не говоря о локальном репозитории, так что боюсь что не понял сути вопроса.
Вместо 5 вот этих команд:
git checkout dev
git pull origin dev
git checkout 1234-bug-login
git rebase dev
git push -f origin 1234-bug-login

Предлагаю использовать вот такие 3:
git fetch origin
git rebase origin/dev
git push -f origin 1234-bug-login
Иногда в origin может быть больше десятка веток для тестирования и прочего, это все выкачивать нет необходимости
да, все верно. Видимо, просто дело привычки
Если команда маленькая (1-3 человека) и задачи выполняются небольшие (из серии: поправить верстку и т.п.) имеет ли смысл создавать в этом случае для каждой задачи ветку? Поделитесь опытом.
Мое мнение, что это стоит делать даже если 1 человек ведет разработку.
да. это особенно удобно когда название ветки соответствует названию таска. плюсом такого подхода вы можете легко переключаться между заданиями или отрываться на исправление срочного бага, а потом возвращаться к работе над задачей. Так же очень легко понять что конкретно реализует эта ветка.

Еще я не вижу смысла в дев ветке (лично я от нее отказался), достаточно иметь мастер со стабильной версией и выполнять слияние только через fast-forfard.
Мастер в любой момент должен быть протестирован и готов к выкатыванию на production сервер. Без dev ветки регрессионное тестирование практически невозможно.
дык тестируйте свой мастер. кто мешает? просто при том подходе что я написал вы не сможете слить ветку с ff не применив на ней все обновления мастера, кто мешает в этот момент прогнать тесты сливаемой ветки?
Ну в общем тут у каждого свое, и все зависит от проекта, от его размера, от того как организовано взаимодействие. Я больше писал про индивидуальный цикл разработки.
А зачем писать bug/feature в названии ветки? Из номера тикета это все можно получить, а так делается ненужное дублирование.

Ну и в целом вы описали по-моему вполне себе обычный способ работы с git. Прочитал и задался вопросом — а что, бывает как-то по-другому?
Мы это делаем, т.к. в истории легче понять что происхдило
«никаких конфликтов быть не будет» — классное выражение
Могу я попросить Вас убрать «Путь Github» из заглавия Вашей блогозаписи?

А не то, знаете ли, имя собственное «GitHub Flow» («Рабочий процесс Гитхаба») достаточно давно принадлежит вон тому рабочему процессу, который в существенной степени отличается от описываемого Вами. И может путаница получиться.
Это рабочий процесс, использующий Github. В самом начале написано «Я расскажу о цикле разработки через Github, который я использую.». Это действительно проблема?
Варианты «Мой путь GitHub» или «Путь через GitHub» уже не путали бы. Буду благодарен, если поменяете.
git push -f origin 1234-bug-login — подходит только если над фичей/фиксом работает один человек. Если два и более, что в принципе иногда случается то проблемы будут.
Известная штука. Сложновато только.
git-flow от nvie упоминалось на этой странице уже не единожды.
Если я правильно понял, то в dev у нас изменения, которые разработчики считают законченными и достойными вливания в мастер. Что, если часть из них не прошла тестирование/приемку, причем эта часть где-то в середине истории и последующие коммиты уже от неё зависят?
Есть несколько вариантов
— если это небольшие изменения, то они сразу влились после код ревью в дев, и если перед релизом в них обнаружена ошибка, то обычно не составляет труда ее исправить

— если это более масштабные изменения, то тестер проверяет отдельно ветку перед сливанием с девом

В целом по такой схеме мы ни разу не пропустили обновление (обновляемся 1 раз в неделю)
Речь прежде всего именно о масштабных изменениях и о внешнем тестировании (приемке). В общем ситуация, когда заказчик заказал масштабное изменение (может не одно) параллельно с мелкими фиксами/фичами, а потом видя на тестовом сервере говорит, что в ТЗ он имел в виду нечто другое и надо все переделать, но вот эти фиксы давно пора выкатить на продакшен.
В моих проектах часто меняется база данных — добавляются поля в таблицах, меняются типы полей итп.
Есть ли средства для создания похожей версионности с миграциями в БД? Чтобы при переключении на нужную ветвь структура базы данных тоже приходила к той версии?
Скрипты на checkout. Откатываем базу до ближней общей точки в текущей ветке и накатываем до последней в новой ветке. Но удовлетворительно работает только если миграции не разрушающие или перед разрушением делается бэкап.
Рекомендую пометить пост как «tutorial».
Sign up to leave a comment.

Articles