Почему сообщения важны?

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

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

 – Pro Git Book

Сообщения фиксации используются по-разному, в том числе:

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

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

Сообщения Easy Commit с Commitizen

Целью этого инструмента является определение стандартного способа фиксации правил и их передачи. Причина этого в том, что его легче читать, и он требует написания описательных коммитов. Снятие неоднозначности вариантов и умственной нагрузки от следования стандарту вручную.

Commitizen предложит вам ряд вопросов, которые сгенерируют окончательное сообщение коммита. Он имеет несколько адаптеров, в моем случае я предпочитаю контролировать вопросы, поэтому использую cz-format-extension.

Вы можете добавить коммит в свой проект с помощью следующей командной строки

npm install commitizen --save-dev # npm
yarn add commitizen -D  # Yarn

Добавляем любой из доступных адаптеров, в моем случае cz-format-extension:

npm install cz-format-extension --save-dev # npm
yarn add cz-format-extension -D  # Yarn

В вашем package.json вам нужно будет добавить следующий раздел:

...
  "config": {
    ...
    "commitizen": {
      "path": "cz-format-extension"
    }
  }
  ...

Адаптер cz-format-extension обеспечивает большую гибкость, поскольку вопросы могут быть определены в файле .czfrec.js. Пример:

const { contributors } = require('./package.json')

module.exports = {
  questions({inquirer}) {
    return [
      {
        type: "list",
        name: "type",
        message: "'What is the type of this change:",
        choices: [
           {
              type: "list",
              name: "type",
              message: "'What is the type of this change:",
              choices: [
          {
            "name": "feat: A new feature",
            "value": "feat"
          },
          {
            "name": "fix: A bug fix",
            "value": "fix"
          },
          {
            "name": "docs: Documentation only changes",
            "value": "docs"
          },
          ...
        ]
      },
      {
        type: 'list',
        name: 'scope',
        message: 'What is the scope of this change:',
        choices: [
            {
              "name": "core: base system of the application",
              "value": "core"
            },
            {
              "name": "extensions: systems that are observed",
              "value": "extensions"
            },
            {
              "name": "tools: other things in the project",
              "value": "tools"
            },
        ]
      },
      {
        type: 'input',
        name: 'message',
        message: "Write a short, imperative tense description of the change\n",
        validate: (message) => message.length === 0 ? 'message is required' : true
      },
      {
        type: 'input',
        name: 'body',
        message: 'Provide a longer description of the change: (press enter to skip)\n',
      },
      {
        type: 'confirm',
        name: 'isBreaking',
        message: 'Are there any breaking changes?',
        default: false
      },
      {
        type: 'input',
        name: 'breaking',
        message: 'Describe the breaking changes:\n',
        when: answers => answers.isBreaking
      },
      {
        type: 'confirm',
        name: 'isIssueAffected',
        message: 'Does this change affect any open issues?',
        default: false
      },
      {
        type: 'input',
        name: 'issues',
        message: 'Add issue references:\n',
        when: answers => answers.isIssueAffected,
        default: undefined,
        validate: (issues) => issues.length === 0 ? 'issues is required' : true
      },
      {
        type: 'checkbox',
        name: 'coauthors',
        message: 'Select Co-Authors if any:',
        choices: contributors.map(contributor => ({
            name: contributor.name,
            value: `Co-authored-by: ${contributor.name} <${contributor.email}>`,
        }))
      },
    ]
  },
  commitMessage({answers}) {
    const scope = answers.scope ? `(${answers.scope})` : '';
    const head = `${answers.type}${scope}: ${answers.message}`;
    const body = answers.body ? answers.body : '';
    const breaking = answers.breaking ? `BREAKING CHANGE: ${answers.breaking}` : '';
    const issues = answers.issues ? answers.issues : '';
    const coauthors = answers.coauthors.join('\n');

    return [head, body, breaking, issues, coauthors].join('\n\n').trim()
  }
}

Файл создает процесс вопросов для:

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

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

Затем вы можете добавить в свой файл package.json несколько хороших npm-скриптов, указывающих на локальную версию Commitizen:

...
  "scripts": {
    "commit": "cz"
  }

Это будет более удобно для ваших пользователей, потому что тогда, если они захотят сделать фиксацию, все, что им нужно сделать, это запустить npm run commit, и они получат подсказки, необходимые для начала фиксации!

ПРИМЕЧАНИЕ. Если вы используете перехватчики precommit благодаря чему-то вроде , вам нужно будет назвать свой скрипт не "commit" (например, "cm": "cz"). Причина в том, что в скриптах npm есть «функция», позволяющая автоматически запускать скрипты с именемprexxx, гдеxxx— это имя другого скрипта. По сути, npm и husky будут дважды запускать сценарии "precommit", если вы назовете сценарий "commit", а обходным путем является предотвращение запуска сценарияprecommit, запускаемого npm.

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

Первоначально опубликовано на https://dev.to 9 августа 2022 г.