Ответы:
Я в целом согласен со 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
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
.
Нет, помещать их в хранилище - это хорошо, я бы даже предложил сделать это (если они полезны и для других). Пользователь должен явно включить их (как вы сказали, например, с помощью символических ссылок), что, с одной стороны, немного болезненно, но, с другой стороны, защищает пользователей от запуска произвольного кода без их согласия.
В настоящее время вы можете сделать следующее, чтобы установить каталог, который находится под контролем версии, в качестве вашего каталога git hooks, например, MY_REPO_DIR/.githooks
будет
git config --local core.hooksPath .githooks/
По-прежнему не применяется напрямую, но, если вы добавляете примечание в README (или что-то еще), это требует минимальных усилий со стороны каждого разработчика.
На http://git-scm.com/docs/git-init#_template_directory вы можете использовать один из этих механизмов для обновления каталога .git / hooks каждого вновь созданного git-репо:
Каталог шаблона содержит файлы и каталоги, которые будут скопированы в $ GIT_DIR после его создания.
Каталог шаблонов будет одним из следующих (по порядку):
аргумент, заданный параметром --template;
содержимое переменной среды $ GIT_TEMPLATE_DIR;
переменная конфигурации init.templateDir; или
каталог шаблонов по умолчанию: / usr / share / git-core / templates.
Как утверждают другие в своем ответе, если ваши хуки специфичны для ваших конкретных проектов, включите их в сам проект, управляемый git. Я хотел бы пойти еще дальше и сказать, что, учитывая, что рекомендуется собирать проект с использованием одного скрипта или команды, ваши хуки должны быть установлены во время сборки.
Я написал статью об управлении git-хуками , если вам интересно почитать об этом чуть подробнее.
Полный отказ от ответственности; Я написал плагин Maven, описанный ниже.
Если вы управляете сборкой с помощью Maven для своих проектов Java, следующий плагин Maven обрабатывает установку хуков из местоположения в вашем проекте.
https://github.com/rudikershaw/git-build-hook
Поместите все свои ловушки Git в каталог вашего проекта, затем настройте его так, pom.xml
чтобы он включал следующее объявление плагина, цель и конфигурацию.
<build>
<plugins>
<plugin>
<groupId>com.rudikershaw.gitbuildhook</groupId>
<artifactId>git-build-hook-maven-plugin</artifactId>
<configuration>
<gitConfig>
<!-- The location of the directory you are using to store the Git hooks in your project. -->
<core.hooksPath>hooks-directory/</core.hooksPath>
</gitConfig>
</configuration>
<executions>
<execution>
<goals>
<!-- Sets git config specified under configuration > gitConfig. -->
<goal>configure</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- ... etc ... -->
</plugins>
</build>
Когда вы запустите сборку вашего проекта, плагин настроит git для запуска хуков из указанного каталога. Это эффективно настроит хуки в этом каталоге для всех, кто работает над вашим проектом.
Для NPM существует зависимость, называемая Husky, которая позволяет устанавливать хуки, в том числе написанные на JavaScript.
// package.json
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"pre-push": "npm test",
"...": "..."
}
}
}
Кроме того, есть предварительная фиксация для проектов Python, Overcommit для проектов Ruby и Lefthook для проектов Ruby или Node.
В https://www.npmjs.com/package/pre-commit НОГО пакета ручек это элегантно позволяет вам указать зафиксироваться крючками в вашем package.json.
Вот скрипт add-git-hook.sh, который вы можете отправить как обычный файл в хранилище и который может быть выполнен для добавления ловушки git к файлу скрипта. Отрегулируйте, какой хук использовать (pre-commit, post-commit, pre-push и т. Д.) И определение хука в cat heredoc.
#!/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.
# Note: CWD must be inside target repository
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 на других машинах после фиксации.
РЕДАКТИРОВАТЬ - Я ответил на более простой вопрос, который был не тем, что задавали, и не тем, что искал ОП. В комментариях ниже я остановился на сценариях использования и аргументах для доставки скриптов ловушек в репо, а не на внешнем управлении ими. Надеюсь, это было больше, что вы ищете.
Для проектов 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
на регулярной основе.
Вы можете использовать управляемое решение для управления хуками перед фиксацией, например, pre-commit . Или централизованное решение для серверных git-хуков, таких как Datree.io . Он имеет встроенные политики, такие как:
Он не заменит все ваши хуки, но может помочь вашим разработчикам с наиболее очевидными из них без адской конфигурации, устанавливающей хуки на каждом компьютере / репозитории разработчиков.
Отказ от ответственности: я один из основателей Datrees
chmod +x .git/hooks/*
чтобы выbin/create-hook-symlinks
работали.