将 git hooks 放入存储库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3462955/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Putting git hooks into repository
提问by shabunc
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?
是否被认为是一种不好的做法 - 将 .git/hooks 放入项目存储库(例如,使用符号链接)。如果是,向不同的 git 用户提供相同钩子的最佳方法是什么?
回答by Cascabel
I generally agree with Scytale, with a couple additional suggestions, enough that it's worth a separate answer.
我大体上同意 Scytale,还有一些额外的建议,足以值得单独回答。
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.
首先,您应该编写一个脚本来创建适当的符号链接,尤其是当这些钩子是关于执行策略或创建有用的通知时。bin/create-hook-symlinks
与必须自己打字相比,如果人们可以直接打字,他们将更有可能使用钩子。
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 allof 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:
其次,直接符号链接挂钩可防止用户添加自己的个人挂钩。例如,我更喜欢示例 pre-commit 钩子,它确保我没有任何空格错误。解决此问题的一个好方法是在您的存储库中放入一个钩子包装脚本,并将所有钩子符号链接到它。然后包装器可以检查$0
(假设它是一个 bash 脚本;与argv[0]
其他类似的等价物)以确定它被调用的钩子,然后在你的 repo 中调用适当的钩子,以及适当的用户的钩子,它必须被重命名,将所有参数传递给每个。记忆中的快速示例:
#!/bin/bash
if [ -x #!/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
.local ]; then
git config --local core.hooksPath .githooks/
.local "$@" || exit $?
fi
if [ -x tracked_hooks/$(basename <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>
) ]; then
tracked_hooks/$(basename // package.json
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"pre-push": "npm test",
"...": "..."
}
}
}
) "$@" || exit $?
fi
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:
安装脚本会将所有预先存在的钩子移到一边(附加.local
到它们的名称),并将所有已知的钩子名称符号链接到上述脚本:
},
"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);\"",
],
回答by scy
No, putting them into the repository is fine, I'd even suggest doing so (if they are useful for others as well). The user has to explicitly enable them (as you said, for example by symlinking), which is on one hand a bit of a pain, but protects users on the other hand from running arbitrary code without their consent.
不,将它们放入存储库很好,我什至建议这样做(如果它们对其他人也有用)。用户必须明确启用它们(如您所说,例如通过符号链接),这一方面有点痛苦,但另一方面可以保护用户在未经他们同意的情况下运行任意代码。
回答by bbarker
Nowadays you can do the following to set a directory that is under version control to be your git hooks directory, e.g., MY_REPO_DIR/.githooks
would be
现在,您可以执行以下操作将受版本控制的目录设置为您的 git hooks 目录,例如,MY_REPO_DIR/.githooks
将是
#!/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
Still not directly enforceable but, if you add a note in your README (or whatever), this requires a minimum of effort on each developer's part.
仍然不能直接强制执行,但是,如果您在自述文件(或其他任何内容)中添加注释,则每个开发人员都需要付出最少的努力。
回答by DavidN
From http://git-scm.com/docs/git-init#_template_directory, you could use one of these mechanisms to update the .git/hooks dir of each newly created git repo:
从http://git-scm.com/docs/git-init#_template_directory,您可以使用以下机制之一来更新每个新创建的 git 存储库的 .git/hooks 目录:
The template directory contains files and directories that will be copied to the $GIT_DIR after it is created.
The template directory will be one of the following (in order):
the argument given with the --template option;
the contents of the $GIT_TEMPLATE_DIR environment variable;
the init.templateDir configuration variable; or
the default template directory: /usr/share/git-core/templates.
模板目录包含创建后将复制到 $GIT_DIR 的文件和目录。
模板目录将是以下之一(按顺序):
使用 --template 选项给出的参数;
$GIT_TEMPLATE_DIR 环境变量的内容;
init.templateDir 配置变量;或者
默认模板目录:/usr/share/git-core/templates。
回答by Rudi Kershaw
Store in the project and install in the build
存储在项目中并安装在构建中
As others state in their answer, If your hooks are specific for your particular projects then include them in the project itself, managed by git. I would take this even further and say that, given that it is good practice to have your project build using a single script or command, your hooks should be installed during the build.
正如其他人在他们的回答中所述,如果您的挂钩特定于您的特定项目,则将它们包含在由 git 管理的项目本身中。我会更进一步说,鉴于使用单个脚本或命令构建项目是一种很好的做法,因此应该在构建过程中安装钩子。
I wrote an article about managing git hooks, if you are interested in reading about this in a little more depth.
我写了一篇关于管理 git hooks的文章,如果你有兴趣更深入地阅读这篇文章。
Java & Maven
Java & Maven
Full disclaimer; I wrote the Maven plugin described below.
完全免责声明;我编写了下面描述的 Maven 插件。
If you are handling build management with Maven for your Java projects, the following Maven plugin handles installing hooks from a location in your project.
如果您使用 Maven 为您的 Java 项目处理构建管理,以下 Maven 插件处理从您项目中的某个位置安装钩子。
https://github.com/rudikershaw/git-build-hook
https://github.com/rudikershaw/git-build-hook
Put all your Git hooks in a directory in your project, then configure your pom.xml
to include the following plugin declaration, goal, and configuration.
将所有 Git 挂钩放在项目中的一个目录中,然后配置您pom.xml
以包含以下插件声明、目标和配置。
When you run your project build the plugin will configure git to run hooks out of the directory specified. This will effectively set up the hooks in that directory for everyone working on your project.
当您运行项目构建时,插件将配置 git 以在指定目录外运行钩子。这将有效地在该目录中为从事项目的每个人设置挂钩。
JavaScript & NPM
JavaScript 和 NPM
For NPM there is a dependency called Huskywhich allows you to install hooks including ones written in JavaScript.
对于 NPM,有一个名为Husky的依赖项,它允许您安装钩子,包括用 JavaScript 编写的钩子。
##代码##Others
其他
Additionally, there is pre-commitfor Python projects, Overcommitfor Ruby projects, and Lefthookfor Ruby orNode projects.
回答by Greg Magolan
The https://www.npmjs.com/package/pre-commitnpm package handles this elegantly allowing you to specify pre-commit hooks in your package.json.
该https://www.npmjs.com/package/pre-commitNPM包处理此典雅允许你指定预先承诺钩子钩住你的package.json。
回答by Elijah Lynn
For Composer based PHP projects you can automatically distribute to engineers. Here is an example for pre-commit and commit-msg hooks.
对于基于 Composer 的 PHP 项目,您可以自动分发给工程师。这是 pre-commit 和 commit-msg 挂钩的示例。
Create a hooks
folder, then in your composer.json:
创建一个hooks
文件夹,然后在您的 composer.json 中:
Then you can even update them as the project continues as everyone is running composer install
on a regular basis.
然后您甚至可以在项目继续时更新它们,因为每个人都composer install
在定期运行。
回答by mathewguest
Here's a script, add-git-hook.sh, which you can ship as a regular file in the repository and can be executed to append the git hook to the script file. Adjust which hook to use (pre-commit, post-commit, pre-push, etc.) and the definition of the hook in the cat heredoc.
这是一个脚本 add-git-hook.sh,您可以将其作为存储库中的常规文件发送,并且可以执行该脚本以将 git 钩子附加到脚本文件中。调整使用哪个钩子(pre-commit、post-commit、pre-push等)以及cat heredoc中钩子的定义。
##代码##This script might make sense to have executable permissions or the user can run it directly. I used this to automatically git-pull on other machines after I committed.
该脚本可能具有可执行权限,或者用户可以直接运行它。提交后,我用它在其他机器上自动 git-pull 。
EDIT-- I answered the easier question which wasn't what was asked and wasn't what the OP was looking for. I opined on the use-cases and arguments for shipping hook scripts in the repo versus managing them externally in the comments below. Hope that was more what you're looking for.
编辑 - 我回答了更简单的问题,这不是问的问题,也不是 OP 正在寻找的问题。在下面的评论中,我对在 repo 中传送钩子脚本与在外部管理它们的用例和参数发表了意见。希望这更符合您的要求。
回答by Shimon Tolts
You could use a managed solution for pre-commit hook management like pre-commit. Or a centralized solution for server-side git-hooks like Datree.io. It has built-in policies like:
您可以使用托管解决方案进行预提交挂钩管理,例如pre-commit。或者像Datree.io这样的服务器端 git-hooks 的集中式解决方案。它具有内置策略,例如:
- Detect and prevent merging of secrets.
- Enforce proper Git user configuration.
- Enforce Jira ticket integration- mention ticket number in pull request name / commit message.
It won't replace all of your hooks, but it might help your developers with the most obvious ones without the configuration hell of installing the hooks on every developers computer/repo.
它不会替换您所有的钩子,但它可能会帮助您的开发人员使用最明显的钩子,而无需在每个开发人员的计算机/存储库上安装钩子的配置地狱。
Disclaimer: I am one of Datrees founders
免责声明:我是 Datrees 的创始人之一