Считается ли это плохой практикой - помещать .git / hooks в репозиторий проектов (например, используя символические ссылки). Если да, каков наилучший способ доставки одинаковых перехватчиков различным пользователям git?
Нет, их можно поместить в репозиторий , Я бы даже предложил это сделать (если они будут полезны и для других). Пользователь должен явно включить их (как вы сказали, например, путем создания символических ссылок), что, с одной стороны, немного неудобно, но защищает пользователей, с другой стороны, от запуска произвольного кода без их согласия.
Я в целом согласен со 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