将 git hooks 放入存储库 [英] Putting git hooks into repository
问题描述
是否被认为是一种不好的做法 - 将 .git/hooks
放入项目存储库(例如,使用符号链接).如果是,向不同的 git 用户提供相同钩子的最佳方式是什么?
Is it considered to be a bad practice - to put .git/hooks
into the projects repository (using symlinks, for example). If yes, what is the best way to deliver same hooks to different git users?
推荐答案
我大体上同意 Scytale,还有一些额外的建议,足以值得单独回答.
I generally agree with Scytale, with a couple additional suggestions, enough that it's worth a separate answer.
首先,您应该编写一个脚本来创建适当的符号链接,特别是如果这些钩子是关于执行策略或创建有用的通知的.如果人们可以直接输入 bin/create-hook-symlinks
,他们将更有可能使用钩子,而不是他们必须自己做.
First, you should write a script which creates the appropriate symlinks, especially if these hooks are about enforcing policy or creating useful notifications. People will be much more likely to use the hooks if they can just type bin/create-hook-symlinks
than if they have to do it themselves.
其次,直接符号链接挂钩可防止用户添加自己的个人挂钩.例如,我更喜欢示例 pre-commit 钩子,它确保我没有任何空格错误.解决此问题的一个好方法是在您的存储库中放入一个钩子包装脚本,并将 所有 的钩子符号链接到它.然后包装器可以检查 $0
(假设它是一个 bash 脚本;否则相当于 argv[0]
)以确定它被调用的钩子,然后调用适当的存储库中的钩子,以及适当的用户钩子,必须重命名,将所有参数传递给每个.记忆中的快速示例:
Second, directly symlinking hooks prevents users from adding in their own personal hooks. For example, I rather like the sample pre-commit hook which makes sure I don't have any whitespace errors. A great way around this is to drop in a hook wrapper script in your repo, and symlink all of the hooks to it. The wrapper can then examine $0
(assuming it's a bash script; an equivalent like argv[0]
otherwise) to figure out which hook it was invoked as, then invoke the appropriate hook within your repo, as well as the appropriate user's hook, which will have to be renamed, passing all the arguments to each. Quick example from memory:
#!/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
附加到它们的名称),并将所有已知的钩子名称符号链接到上述脚本:
The installation script would move all pre-existing hooks to the side (append .local
to their names), and symlink all known hook names to the above script:
#!/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
这篇关于将 git hooks 放入存储库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!