git

Руководство по работе с системой контроля версий git в организации Le, а также облачными сервисами GitHub и GitLab.

Зачем нам GIT?

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

Благодаря удалённым репозиториям, таким как GitLab, мы обеспечиваем совместную работу с минимальным шансом возникновения конфликтов. Помимо этого, мы также обеспечиваем работу проекта в формате CI\CD.

Соглашение о ветках, коммитах и PR

Простое соглашение о том, как нужно создавать ветки и писать сообщения коммитов/PR.

Ветки

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

Основные ветки в репозиториях:

  • master - основная ветка рабочего проекта, настроенная на тестовый стенд

  • develop - ветка для разработки (опционально)

  • prod - основная ветка рабочего проекта, настроенная на prod-сервер (опционально)

  • feat/*new_feature* - ветки для внесения новых фич

  • fix/*fix_name_or_issue_id* - ветки для исправления багов

  • ...другие ветки смотрите ниже в таблице

Другие ветки, отличные от fix и feat разрешены. Например, nuxt3-configuration. В этом случае, вы не добавляете функционал и не фиксите баги, а работаете над окружением проекта.

Основные префиксы для типов веток:

build

Сборка проекта или изменения внешних зависимостей

ci

Настройка CI и работа со скриптами

docs

Обновление документации

feat

Добавление нового функционала

fix

Исправление ошибок

perf

Изменения направленные на улучшение производительности

refactor

Правки кода без исправления ошибок или добавления новых функций

revert

Откат на предыдущие коммиты

style

Правки по кодстайлу (табы, отступы, точки, запятые и т.д.)

test

Добавление тестов

Коммиты

Open Source проекты ведутся на английском языке, а приватные проекты на русском языке (кроме имён веток, версий и тегов). Это относится также к комментированию кода.

У каждой фиксации есть связанное сообщение, являющееся объяснением, почему было сделано то или иное изменение. Также каждая фиксация считается отдельной единицей изменения. Это позволяет откатить изменения, если обнаружилась ошибка, или если ты решишь пойти в другом направлении.

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

Вливай изменения в свою ветвь как можно чаще, чтобы она всегда оставалась актуальной и готовой к обратному слиянию. Разрешение возможных конфликтов слияния — право и обязанность разработчика ветви, так как именно он лучше всего знает зафиксированные в ней изменения. Но выполнять слияние имеет право ТОЛЬКО TeamLead.

Область изменений (scope)

Работая над новым функционалом или исправлением багов, вы можете добавлять scope к описанию коммита, который укажет на область изменений (см. примеры).

Спецификации

  1. Коммиты ДОЛЖНЫ начинаться с префикса, который содержит существительное feat, fix и др., за которым следует двоеточие и пробел

  2. Тип feat ДОЛЖЕН использоваться для коммитов, которые добавляют новую функциональность

  3. Тип fix ДОЛЖЕН использоваться для коммитов, которые исправляют баги

  4. НЕ ОБЯЗАТЕЛЬНАЯ область (scope) МОЖЕТ быть указана после типа. Область - это фраза, описывающая контекст кодовой базы, измененной коммитом, заключенная в круглые скобки. Например, fix(parser):

  5. Краткое описания ДОЛЖНО следовать сразу же после указания префикса типа/области. Краткое описание - это сжатое описание изменения кода, которое несет в себе коммит, например, fix: исправлена проблема с undefined при получении статей в рекомендациях

  6. Тело коммита содержит в себе дополнительное, полное описание о изменении кодовой базы. Оно МОЖЕТ следовать после краткого описания. Тело МОЖЕТ идти после краткого описания, через одну пустую строку

  7. Типы отличные от feat и fix ДОЛЖНЫ использоваться в сообщениях коммитов

Примеры

Коммит, добавляющий новую функциональность

Ветка feat/name_new_feature

Описание коммита: feat: добавлен функционал *название нового функционала*

Коммит с указанной областью (scope)

Ветка feat/add_polish_lang

Описание коммита: feat(lang): добавлен польский язык

Коммит, исправляющий баги и содержащий (необязательный) номер в баг-трекере (issues)

Ветка fix/fix_name_or_issue_id

Описание коммита:

fix: исправил типизацию сообщений в чате
issue #123

Коммит, не содержащий функционала или фиксов

Ветка init-nuxt-project

Описание коммита: init-nuxt-project: инициализировал nuxt 3

Почему нужно использовать Общепринятые Коммиты

  • Автоматически создаваемые CHANGELOG’и

  • Коммуникация о характере изменения между товарищами по команде, общественностью и другими заинтересованными сторонами

  • Автоматически срабатываемый процесс сборки и публикации (ci/cd)

  • Людям проще участвовать в вашем проекте, потому что им доступна более структурированная история коммитов

FAQ

Как я должен писать сообщения коммитов на начальной стадии разработки?

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

В каком регистре я должен писать заголовки коммитов?

Любой регистр можно использовать, но лучше во всей истории использовать один стиль.

Что мне делать, если коммит должен содержать больше одного типа?

Вернитесь назад и сделайте несколько коммитов, если это возможно. Часть из преимуществ использования Общепринятых Коммитов - это его способность побуждать делать более организованные коммиты и PR’ы.

Разве это не препятствует быстрому развитию и быстрой интеграции?

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

Могут ли Общепринятые Коммиты заставить разработчиков ограничивать их типы коммитов, потому что им придется думать об этих типах?

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

Как мне эффективнее внести новый функционал?

Можно сделать что-то вроде:

  1. git clone *remote repo* - клонируем проект, если ещё не клонировали

  2. git checkout -b feat/*new_feature* - создаём ветку и сразу переключаемся

  3. git commit -m "feat: *что сделали?*" - делаем коммиты по каждым основным изменениям (предварительно не забываем добавить файлы git add *file or directory* c изменениями)

  4. git push origin HEAD - пушим коммиты в свою ветку (если ты хочешь отправить ветку, отличную от текущей, команда не будет работать)

Что, если пришлось на этапе работы над функцией заняться, например, исправлением бага, а изменения совсем не готовы для коммита?

  1. git stash - сохраняем изменения (подробнее*)

  2. git checkout -b fix/*fix_name_or_issue_id* - создаём ветку и сразу переключаемся

  3. git commit -m "fix: *что сделали?*" - делаем коммит(-ы), предварительно не забыв добавить файлы git add *file or directory* c изменениями)

  4. git push origin HEAD - пушим коммиты в свою ветку (если ты хочешь отправить ветку, отличную от текущей, команда не будет работать)

  5. git checkout feat/*new_feature* - возвращаемся на ветку

  6. git stash apply - возвращаем незавершенный код

Настроим утилиту commitizen

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

1. Установим утилиту commitizen глобально (вам могут потребоваться права администратора).

npm i -g commitizen

2. Следом установим адаптер cz-customizable. Он нужен для настройки шаблона с вопросами, которым пользуется утилита commitizen.

npm i -D cz-customizable

3. Создадим файл commitizen.js, он нужен для настройки cz-customizable. Поместим созданный файл в директорию ./config/git. Рекомендую не захламлять корень проекта конфигурационными файлами и стараться группировать файлы в подготовленной для этого папке. Содержимое:

Показать commitizen.js
"use strict";

module.exports = {
  // Добавим описание на русском языке ко всем типам
  types: [
    {
      value: "build",
      name: "build:     Сборка проекта или изменения внешних зависимостей"
    },
    { value: "ci", name: "ci:        Настройка CI и работа со скриптами" 
},
    { value: "docs", name: "docs:      Обновление документации" },
    { value: "feat", name: "feat:      Добавление нового функционала" },
    { value: "fix", name: "fix:       Исправление ошибок" },
    {
      value: "perf",
      name: "perf:      Изменения направленные на улучшение производительности"
    },
    {
      value: "refactor",
      name:
        "refactor:  Правки кода без исправления ошибок или добавления новых функций"
    },
    { value: "revert", name: "revert:    Откат на предыдущие коммиты" },
    {
      value: "style",
      name:
        "style:     Правки по кодстайлу (табы, отступы, точки, запятые и т.д.)"
    },
    { value: "test", name: "test:      Добавление тестов" }
  ],

  // Область. Она характеризует фрагмент кода, которую затронули изменения
  scopes: [
    { name: "components" },
    { name: "tutorial" },
    { name: "catalog" },
    { name: "product" }
  ],

  // Возможность задать спец ОБЛАСТЬ для определенного типа коммита (пример для 'fix')
  /*
  scopeOverrides: {
    fix: [
      {name: 'style'},
      {name: 'e2eTest'},
      {name: 'unitTest'}
    ]
  },
  */

  // Поменяем дефолтные вопросы
  messages: {
    type: "Какие изменения вы вносите?",
    scope: "\nВыберите ОБЛАСТЬ, которую вы изменили (опционально):",
    // Спросим если allowCustomScopes в true
    customScope: "Укажите свою ОБЛАСТЬ:",
    subject: "Напишите КОРОТКОЕ описание в ПОВЕЛИТЕЛЬНОМ наклонении:\n",
    body:
      'Напишите ПОДРОБНОЕ описание (опционально). Используйте "|" для новой строки:\n',
    breaking: "Список BREAKING CHANGES (опционально):\n",
    footer:
      "Место для мета данных (тикетов, ссылок и остального). Например: SECRETMRKT-700, SECRETMRKT-800:\n",
    confirmCommit: "Вас устраивает получившийся коммит?"
  },

  // Разрешим собственную ОБЛАСТЬ
  allowCustomScopes: true,

  // Запрет на Breaking Changes
  allowBreakingChanges: false,

  // Префикс для нижнего колонтитула
  footerPrefix: "МЕТА ДАННЫЕ:",

  // limit subject length
  subjectLimit: 72
};

4. Добавим в package.json ссылки на cz-customizable и созданный ранее конфигурационный файл:

Показать часть package.json
{
  "config": {
    "commitizen": {
      "path": "node_modules/cz-customizable"
    },
    "cz-customizable": {
      "config": "config/git/commitizen.js"
    }
  },
}

5. Давайте проверим получившийся результат. Наберите в терминале следующую команду:

git cz

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

Обязательно посмотрите на пример работы настроенной утилиты commitizen и подключенного к нему адаптера cz-cusomizable

Дополнительно

Если ты не чувствуешь себя уверенно в отношении с git, то обязательно:

Last updated