Введение
Git может запускать пользовательские сценарии, когда происходят определенные важные действия, наиболее часто используемые из них:pre-commit
,commit-msg
,pre-push
Дождитесь крючков. мы можемpre-commit
Проверка формата кода при запуске,commit-msg
Чтобы проверить триггер для фиксации и отправки пользователю сообщения вpre-push
Выполняйте модульное тестирование, e2e-тестирование и т. д. при срабатывании.
Git выполняетgit init
При инициализации будет.git/hooks
Каталог генерирует серию скриптов хуков:
Как видно из рисунка выше, суффикс каждой письменности равен.sample
В конце, в это время, скрипт не будет выполняться автоматически. Нам нужно удалить суффикс, прежде чем он вступит в силу.pre-commit.sample
сталиpre-commit
буду работать.
В этой статье в основном рассказывается о том, как писать скрипты git hooks, и мы напишем дваpre-commit
,commit-msg
Сценарий используется в качестве примера, чтобы помочь вам лучше понять сценарий git hooks. Конечно, в работе рекомендуется использовать готовые решения с открытым исходным кодом.husky.
текст
Нет ограничений на язык сценариев, используемый для написания git-хуков, вы можете использоватьnodejs
,shell
,python
,ruby
И другие скриптовые языки, очень гибкие и удобные.
Ниже я буду использовать язык оболочки, чтобы продемонстрировать, как написатьpre-commit
а такжеcommit-msg
сценарий. Также обратите внимание, что при выполнении этих сценариев, если вы выйдете из программы с ненулевым значением, процесс отправки / отправки Git будет прерван. Поэтому при проверке сообщений/кода в скрипте хуков можно использовать ненулевое значение для выхода, прерывания процесса GIT.
exit 1
pre-commit
существуетpre-commit
Что делать в хуке очень просто, проверяется только формат отправляемого кода, поэтому код скрипта относительно небольшой:
#!/bin/sh
npm run lint
# 获取上面脚本的退出码
exitCode="$?"
exit $exitCode
Поскольку я уже настроил соответствующую конфигурацию eslint и скрипты npm в проекте, вpre-commit
Достаточно выполнить соответствующую команду lint в , и оценить, нормально ли она завершается.
// 在 package.json 文件中已配置好 lint 命令
"scripts": {
"lint": "eslint --ext .js src/"
},
Давайте посмотрим на движущуюся картинку, при неправильном формате кода будет сообщено об ошибке при фиксации:
Отправьте после изменения формата кода, тогда об ошибке не будет сообщено:
Загнанный рисунок мы можем видеть, что это был правильно представленный коммит.
commit-msg
существуетcommit-msg
В хуках нам нужно проверить сообщение коммита и пользователя.
#!/bin/sh
# 用 `` 可以将命令的输出结果赋值给变量
# 获取当前提交的 commit msg
commit_msg=`cat $1`
# 获取用户 email
email=`git config user.email`
msg_re="^(feat|fix|docs|style|refactor|perf|test|workflow|build|ci|chore|release|workflow)(\(.+\))?: .{1,100}"
if [[ ! $commit_msg =~ $msg_re ]]
then
echo "\n不合法的 commit 消息提交格式,请使用正确的格式:\
\nfeat: add comments\
\nfix: handle events on blur (close #28)\
\n详情请查看 git commit 提交规范:https://github.com/woai3c/Front-end-articles/blob/master/git%20commit%20style.md"
# 异常退出
exit 1
fi
существуетcommit-msg
Когда хук сработает, соответствующий скрипт получит параметр, который является сообщением фиксации.cat $1
получить и назначитьcommit_msg
Переменная.
Относительно просто проверить регулярность сообщения коммита, просто взгляните на код. Если вас интересует спецификация отправки коммита, вы можете прочитать другую мою статьюстатья.
Относительно просто судить о правах пользователя, просто проверьте почтовый ящик или имя пользователя (при условии, что только сотрудники компании abc имеют разрешение на отправку кода).
email_re="@abc\.com"
if [[ ! $email =~ $email_re ]]
then
echo "此用户没有权限,具有权限的用户为: xxx@abc.com"
# 异常退出
exit 1
fi
Следующие две анимации используются для демонстрации процесса проверки сообщений фиксации и оценки разрешений пользователей:
Установить местоположение git по умолчанию
Это только первый шаг, чтобы скрипт мог выполняться нормально, есть еще одна проблема, которую необходимо решить, а именно, как поделиться конфигурацией git hooks с другими разработчиками того же проекта. потому что.git/hooks
Каталоги не отправляются в удаленные репозитории с коммитами. Есть два решения этой проблемы: первое — имитировать хаски, чтобы сделать npm-плагин, который автоматически устанавливается в момент установки..git/hooks
Каталог Добавить скрипт HOOKS; второй — написать скрипт хуков отдельно в определенном каталоге в проекте, а затем автоматически установить этот каталог в каталог git hooks при установке проекта.
Далее подробно описан процесс реализации второго способа:
- существует
npm install
После завершения выполнения автоматически выполнитьgit config core.hooksPath hooks
Заказ. -
git config core.hooksPath hooks
Команда устанавливает каталог git hooks в каталог hooks в корне проекта.
"scripts": {
"lint": "eslint --ext .js src/",
"postinstall": "git config core.hooksPath hooks"
},
Ступай на яму
Исходный код демо-версии может нормально работать в Windows, но после перехода на Mac он не будет работать, и при отправке будет сообщено об ошибке:
hint: The 'hooks/pre-commit' hook was ignored because it's not set as executable.
Причина в том, что скрипт ловушек не является исполняемым по умолчанию, поэтому его необходимо сделать исполняемым:
chmod 700 hooks/*
Чтобы не изменять проект каждый раз, когда вы клонируете проект, лучше добавить эту команду в скрипт npm:
"scripts": {
"lint": "eslint --ext .js src/",
"postinstall": "git config core.hooksPath hooks && chmod 700 hooks/*"
},
Конечно, если это окна, вторую половину кода добавлять не нужно.
скрипт хуков nodejs
Чтобы помочь студентам, изучающим интерфейс, лучше понять скрипт git hooks, я переписал версию с nodejs.
pre-commit
#!/usr/bin/env node
const childProcess = require('child_process');
try {
childProcess.execSync('npm run lint');
} catch (error) {
console.log(error.stdout.toString());
process.exit(1);
}
commit-msg
#!/usr/bin/env node
const childProcess = require('child_process');
const fs = require('fs');
const email = childProcess.execSync('git config user.email').toString().trim();
const msg = fs.readFileSync(process.argv[2], 'utf-8').trim(); // 索引 2 对应的 commit 消息文件
const commitRE = /^(feat|fix|docs|style|refactor|perf|test|workflow|build|ci|chore|release|workflow)(\(.+\))?: .{1,100}/;
if (!commitRE.test(msg)) {
console.log();
console.error('不合法的 commit 消息格式,请使用正确的提交格式:');
console.error('feat: add \'comments\' option');
console.error('fix: handle events on blur (close #28)');
console.error('详情请查看 git commit 提交规范:https://github.com/woai3c/Front-end-articles/blob/master/git%20commit%20style.md。');
process.exit(1);
}
if (!/@qq\.com$/.test(email)) {
console.error('此用户没有权限,具有权限的用户为: xxx@qq.com');
process.exit(1);
}
Суммировать
На самом деле тема этой статьи не ограничивается интерфейсом, а распространяется на все проекты, использующие git в качестве контроля версий. Такие как Android, ios, Java и т. д. Просто в этой статье в качестве примера был выбран фронтенд-проект.
Недавно прикрепленный исходный код проекта:GitHub.com/ilove3from/git-…