Помещение git hooks в хранилище
Считается ли это плохой практикой - помещать.git/hooks в репозиторий проектов (например, используя символические ссылки). Если да, каков наилучший способ доставки одинаковых хуков разным пользователям git?
10 ответов
Нет, помещать их в хранилище - это хорошо, я бы даже предложил сделать это (если они полезны и для других). Пользователь должен явно включить их (как вы сказали, например, с помощью символических ссылок), что, с одной стороны, немного болезненно, но, с другой стороны, защищает пользователей от запуска произвольного кода без их согласия.
В настоящее время вы можете сделать следующее, чтобы установить каталог, который находится под управлением версией, в каталог git hooks, например: MY_REPO_DIR/.githooks
было бы
git config --local core.hooksPath .githooks/
По-прежнему не применяется напрямую, но, если вы добавляете примечание в README (или что-то еще), это требует минимум усилий со стороны каждого разработчика.
Я в целом согласен со Scytale, с парой дополнительных предложений, достаточно того, что стоит отдельного ответа.
Во-первых, вы должны написать скрипт, который создает соответствующие символические ссылки, особенно если эти ловушки связаны с применением политики или созданием полезных уведомлений. Люди будут гораздо чаще использовать крючки, если они могут просто напечатать bin/create-hook-symlinks
чем если бы они сделали это сами.
Во-вторых, прямые символьные хуки не позволяют пользователям добавлять свои личные хуки. Например, мне скорее нравится пример ловушки перед фиксацией, который гарантирует, что у меня нет ошибок пробелов. Отличный способ обойти это - добавить скрипт репозитория ловушек в репозиторий и вставить в него все ссылки. Обертка может затем изучить $0
(при условии, что это скрипт bash; эквивалентный argv[0]
в противном случае, чтобы выяснить, к какому хуку он был вызван, затем вызовите соответствующий хук в вашем репо, а также хук соответствующего пользователя, который нужно будет переименовать, передавая все аргументы каждому. Быстрый пример из памяти:
#!/bin/bash
if [ -x $0.local ]; then
$0.local "$@" || exit $?
fi
if [ -x tracked_hooks/$(basename $0) ]; then
tracked_hooks/$(basename $0) "$@" || exit $?
fi
Сценарий установки переместит все существующие ранее хуки в сторону (добавить .local
к их именам), и символическую ссылку на все известные имена хуков к приведенному выше сценарию:
#!/bin/bash
HOOK_NAMES="applypatch-msg pre-applypatch post-applypatch pre-commit prepare-commit-msg commit-msg post-commit pre-rebase post-checkout post-merge pre-receive update post-receive post-update pre-auto-gc"
# assuming the script is in a bin directory, one level into the repo
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
for hook in $HOOK_NAMES; do
# If the hook already exists, is executable, and is not a symlink
if [ ! -h $HOOK_DIR/$hook -a -x $HOOK_DIR/$hook ]; then
mv $HOOK_DIR/$hook $HOOK_DIR/$hook.local
fi
# create the symlink, overwriting the file if it exists
# probably the only way this would happen is if you're using an old version of git
# -- back when the sample hooks were not executable, instead of being named ____.sample
ln -s -f ../../bin/hooks-wrapper $HOOK_DIR/$hook
done
Хранить в проекте и устанавливать в сборке
Как говорит Scy в своем ответе, если ваши хуки специфичны для ваших конкретных проектов, я бы включил их в сам проект, управляемый git. Я хотел бы пойти еще дальше и сказать, что, учитывая, что рекомендуется собирать проект с помощью одного скрипта или команды, ваши хуки должны быть установлены во время сборки.
Java и Maven
Полный отказ от ответственности; Я написал плагин Maven, описанный ниже.
Если вы управляете сборкой с помощью Maven для своих проектов Java, следующий плагин Maven обрабатывает установку хуков из местоположения в вашем проекте.
https://github.com/rudikershaw/git-build-hook
<build>
<plugins>
<plugin>
<groupId>com.rudikershaw.gitbuildhook</groupId>
<artifactId>git-build-hook-maven-plugin</artifactId>
<version>2.0.1</version>
<configuration>
<!-- The locations of a variety of different hooks to install in the local project. -->
<preCommit>path/to/hook.sh</preCommit>
</configuration>
<executions>
<execution>
<goals>
<!-- Inititalise a Git repository if one does not already exist. -->
<goal>initialize</goal>
<!-- Install Git hooks. -->
<goal>install</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- ... etc ... -->
</plugins>
</build>
JavaScript и NPM
Для NPM существует зависимость, называемая Husky, которая позволяет устанавливать хуки, в том числе написанные на JavaScript.
// package.json
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"pre-push": "npm test",
"...": "..."
}
}
}
Из http://git-scm.com/docs/git-init вы можете использовать один из этих механизмов для обновления каталога.git/hooks каждого вновь созданного git-репо:
Каталог шаблона содержит файлы и каталоги, которые будут скопированы в $GIT_DIR после его создания.
Каталог шаблонов будет одним из следующих (по порядку):
аргумент, заданный параметром --template;
содержимое переменной среды $GIT_TEMPLATE_DIR;
переменная конфигурации init.templateDir; или же
каталог шаблонов по умолчанию: /usr/share/git-core/templates.
Для проектов PHP на основе Composer вы можете автоматически распространять их среди инженеров. Вот пример для хуков pre-commit и commit-msg.
Создать hooks
папку, затем в вашем composer.json:
},
"scripts": {
"post-install-cmd": [
"cp -r 'hooks/' '.git/hooks/'",
"php -r \"copy('hooks/pre-commit', '.git/hooks/pre-commit');\"",
"php -r \"copy('hooks/commit-msg', '.git/hooks/commit-msg');\"",
"php -r \"chmod('.git/hooks/pre-commit', 0777);\"",
"php -r \"chmod('.git/hooks/commit-msg', 0777);\"",
],
Затем вы можете даже обновить их, поскольку проект продолжается, поскольку все работают composer install
на регулярной основе.
https://www.npmjs.com/package/pre-commit npm package обрабатывает это элегантно, позволяя вам указать хуки pre-commit в вашем package.json.
Похоже, что многие сообщения устарели, по крайней мере, если вы используете предварительную фиксацию в экосистеме python (+ я обнаружил, что изменение пути к крючку git не работает с немного более старыми версиями git, например 2.3). С .pre-commit-config.yaml в каталоге hooks в корне вашего репозитория самым простым решением является запуск:
pre-commit install -f --config hooks/.pre-commit-config.yaml
Вот скрипт add-git-hook.sh, который вы можете отправить как обычный файл в хранилище и который может быть выполнен для добавления ловушки git к файлу скрипта. Отрегулируйте, какой хук использовать (pre-commit, post-commit, pre-push и т. Д.) И определение хука в heredoc cat.
#!/usr/bin/bash
# Adds the git-hook described below. Appends to the hook file
# if it already exists or creates the file if it does not.
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
HOOK_FILE="$HOOK_DIR"/post-commit
# Create script file if doesn't exist
if [ ! -e "$HOOK_FILE" ] ; then
echo '#!/usr/bin/bash' >> "$HOOK_FILE"
chmod 700 "$HOOK_FILE"
fi
# Append hook code into script
cat >> "$HOOK_FILE" <<EOF
########################################
# ... post-commit hook script here ... #
########################################
EOF
Этот сценарий может иметь смысл иметь разрешения на выполнение или пользователь может запустить его напрямую. Я использовал это для автоматического git-pull на других машинах после фиксации.
РЕДАКТИРОВАТЬ - Я ответил на более простой вопрос, который был не тем, что задавали, и не тем, что искал ОП. В комментариях ниже я остановился на сценариях использования и аргументах для доставки скриптов ловушек в репо, а не на внешнем управлении ими. Надеюсь, это было больше, что вы ищете.
Вы можете использовать управляемое решение для управления хуками перед фиксацией, например, https://pre-commit.com/. Или централизованное решение для серверных git-хуков, таких как Datree.io. Он имеет встроенные политики, такие как:
- Обнаруживать и предотвращать слияние секретов.
- Обеспечить правильную настройку пользователя Git.
- Обеспечить интеграцию билета Jira - укажите номер билета в имени запроса на получение / сообщении о коммите.
Он не заменит все ваши хуки, но может помочь вашим разработчикам с наиболее очевидными из них без адской настройки установки хуков на каждом компьютере / репозитории разработчиков.
Отказ от ответственности: я один из основателей Datrees