Командная работа в Git

Git даёт ряд преимуществ разработчику, но по настоящему он раскрывается в работе командой.

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

Как говорится, эта статья не была бы руководством, если бы не предлагала вам на рассмотрение готовый, удобный инструмент для организации рабочего процесса с Git. Данная статья основывается на очень популярном рабочем процессе, созданном Vincent Driessen, который называется Git-Flow, и обладает несколькими важными отличиями по отношению к обычному Git. Существует несколько популярных рабочих процессов, основанных на Git, упоминание о которых можно повсеместно встретить в сети Интернет, и я бы рекомендовал ознакомиться с некоторыми из них, прежде чем вы с вашей командой выберите тот, который подходит именно вам.

Давайте начнём ваше исследование с ознакомления с Git-Flow.

Основное правило

Ветку master всегда можно развернуть. Всегда.

Развёртываемая (стабильная) ветка master важна по нескольким причинам. Первым делом, это позволяет любому новичку на проекте выкачать и собрать проект без ошибок. Ничто так не разочаровывает, как невозможность собрать проект, с которым не знаком.

Во-вторых, master показывает текущее состояние проекта в производстве. Если нужно сделать правки - всегда ясно, от чего надо ответвляться.

И, наконец, разворачиваемый master - это страховочная сеть. Если master развёртываем - то мы в любой момент можем развернуть проект из ветки без опасений, что что-то отвалится. Беспокойство ведёт к стрессу, а стресс, в свою очередь, ведёт к расстройству пищеварения. Это не нужно никому.

Стратегии ветвления

Ветка develop должна быть основной веткой, в которой ведётся разработка. Ветки для внедрения новых возможностей должны ответвляться от этой ветки, и вливаться обратно в ветку develop, а ветка develop представляет состояние кодовой базы проекта на текущий момент.

Так как обе ветки - master и develop - являются постоянными, и постоянно затрагиваемыми, то работа с ними никогда не должна вестись напрямую. Вместо этого, вся работа должна вестись в отдельных ветках. При разработке новой функциональности необходимо ответвиться от ветки develop, и разработку вести во вновь созданной ветке.

Как именовать?

Не существует жёстких правил именования веток, особенно веток, в которых ведётся доработка или разработка нового функционала. Если ветка создана для правки, то, возможно, неплохо дать ей приставку “fix-”. Если ветка является релизной, то обычно так её и называют: “release-X.X.X”.

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

Вы говорите “объединить”, я говорю - “переместить”

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

Все конфликты должны быть решены в вашей ветке под доработку. Если вы создали ветку для того, чтобы сделать небольшое изменение/правку, и если вы не отправили ветку в удалённый репозиторий, сделайте перемещение (rebase) ветки develop в вашу ветку с разработкой, а после залейте вашу ветку разработки в ветку develop. Отправьте изменения, и можете спокойно удалять вашу локальную ветку с разработкой.

Если вы уже отправляли вашу ветку в удалённый репозиторий, первым делом залейте (merge) ветку develop в вашу ветку разработки (решите конфликты), а после слейте вашу ветку в develop. Отправьте изменение, и можете удалять как локальную ветку, так и ветку в удалённом репозитории.

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

Вот несколько правил, которые помогут вам обезопасить себя при перемещении:

  • Никогда не перемещайте что-либо, что уже было отправлено в удалённый репозиторий. Ваша ветка только локальная? Тогда можете перемещать. Иначе не перемещаем.
  • Перемещайте общие ветки в локальные. develop - общая ветка. my?awesome-feature - локальная ветка. И вот я готов отправить изменения из my?awesome?feature в develop, но я хочу быть уверен, что все изменения, которые были произведены в ветке develop за время разработки, попали ко мне в ветку:
git checkout my-awesome-feature
git rebase develop
git checkout develop
git merge my-awesome-feature
 
 

Проследите за изменениями

Скажем, мы сделали ветку, понаписали кода, объединили/переместили изменения из develop, и вот мы готовы к заливке кода обратно в develop. Но должны ли? Может, кто-то для начала должен просмотреть наши изменения?

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

Вот где на помощь приходят запросы на включение (pull-request) и интерфейс Bitbucket. Запросы на включение могут быть гораздо большим, чем просто просьбой сделать обзор изменённого кода. Так как запросы на включение относятся к брендам, они могут стать темой обсуждения и принятия совместных решений по отдельным разработкам. Вы можете встраивать фотографии, чтобы продемонстрировать дизайн, комментировать строки кода напрямую, и даже использовать анимированные изображения и смайлы для развлечения.

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

Стабилизация изменений

Как только ветка develop готова к релизу, слейте её в master:

git checkout master
git merge --no-ff develop
 
 

Обратили внимание на флаг --no-ff? Он говорит о том, что в том случае сохранится история ветвления, и будет создан дополнительный коммит слияния. Зачем нам это нужно? А чтобы создать тег! Пометим этот коммит как новую версию:

git tag -a vX.X.X -m 'Version X.X.X'
 

А потом зальём master обратно в develop, чтобы в develop был коммит с новой версией.

Говоря о версиях, стоит использовать семантическое версионирование. Оно сводится к следующей схеме: MAJOR.MINOR.PATCH. Говоря в общем, MAJOR - это номер целой версии - используется для маркирования больших изменений или этапов разработки. Разрешается нарушение обратной совместимости. MINORиспользуется для новых возможностей. Обратная совместимость ломаться не должна. PATCH - для небольших изменений и правок, обратная совместимость ломаться не должна. До запуска приложения в продакшен мы должны работать в рамках предрелизной версии (0.x.x).

Поправь, пока не остыло

Мы не должны выпускать ошибки.

…но уж если это произошло, то лучше их поправить как можно быстрее. Так как ветка develop может содержать незаконченные изменения, ветки критических правок надо создавать от текущего релиза, который находится в master (так как master всегда служит для разворачивания для конечных пользователей).

Чтобы сделать правку, создайте ветку от master, сделайте правку, потом сделайте неперематываемое слияние (non-fast-forward merge) в master. Создайте тег, слейте master в develop (так как мы хотим, чтобы правка попала и в develop). Теперь можно удалить ветку с правкой.

Время поговорить о коммитах

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

  • Сообщение коммита должно быть написано в настоящем времени: “Исправляет баг…” вместо “Был исправлен баг..” или “Исправился баг…”
  • Первая строка (или строка заголовка) должна содержать краткую суть коммита (желательно до 50 символов), с заглавной буквы.
  • Если заглавная строка требует пояснения, можно, пропустив одну строку, написать дополнительное описание. Описание должно быть оформлено в виде параграфа, с правильным озаглавливанием и пунктуацией.
  • Сообщения коммита необходимо разбивать на строки длиной до 72 символов, чтобы журнал коммитов нормально отображался в терминалах.

Сделайте его своим

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

Что гораздо важнее - чтобы ваша команда согласилась с предложенным рабочим процессом, и влилась в него. За этим последует более тесное сотрудничество, и вы начнёте получать преимущества, которые даёт Git при работе в команде.

Посмотрите на некоторые альтернативы рабочему процессу Git-Flow в руководстве по рабочим процессам Git от Atlassian

По материалам http://ruseller.com/lessons.php?rub=28&id=2207

Теги: