如何将预提交挂钩添加到现有 git 存储库

How can I add my pre-commit hook to an existing git repository

我有一个预提交挂钩,我想将它添加到存储库中,以便我的同事通过检查立即将它安装到位。
但是,如果我尝试添加它(在我的项目的根目录中),我会得到以下结果:

$ git add  .git/hooks/pre-commit
error: Invalid path '.git/hooks/pre-commit'
error: unable to add .git/hooks/pre-commit to index

知道这是否有效以及如何实现我的目标吗?

checking it out my colleagues have it instantly in place

9 月2015:那是不可能的:可以在源代码管理中放置一个挂钩(您只需将脚本复制到 git 存储库中),但它不能 "automatically in place"(活动)在 clone/checkout:这太危险了,具体取决于钩子的实际作用。
另见“Git remote/shared pre-commit hook

您仍然需要通过向 git 存储库中存在的预提交挂钩添加符号链接(甚至在 Windows 上)来激活它。

2016 年 12 月更新OP Calamity Jane mentions

I solved it by now in symfony2 projects (and with others, it also should work) to have it as part of the composer.json.
So if a colleague is doing a composer install or composer update, it is automatically placed in the correct place.

"scripts": { "dev-install": [ "bash setup_phpcs.sh" ] }, 

So on dev, setup_phpcs.sh is automatically called and that copies the hook from a folder in the repository to the right place.
And since the hook is part of the repository it can be easily updated and distributed.

正如 Hi-Angel in 所述:

I figured that out: Emacs has build-aux dir with hooks, and, upon running autogen.sh, all hooks are copied from there.

对于PHP和PHP Composer

仅供参考,在 2019 年,还有这个选项:

需要这个包:“brainmaestro/composer-git-hooks”

并将以下行添加到您的 composer.yaml 文件中:

"extra": {
    "hooks": {
        "commit-msg": [
            "regex=\"^([A-Z]{2,4}-[0-9]{1,4}|(no-ticket|NO-TICKET)):[\s]*.{10,}\"",
            "file=`cat `",
            "if ! [[ $file =~ $regex ]]; then",
            "  echo \"ERROR - Commit message is wrong or too short. E.g. XXX-33: Description or no-ticket : Description\"",
            "  exit 1",
            "fi"
        ],
        "pre-commit": [
            "git status --porcelain | grep -e '^ [AM]\(.*\).php$' | cut -c 3- | while read line; do",
            "ROOT=`php -r \"echo __DIR__;\"`",
            "bin/php-cs-fixer fix -nq --config=$ROOT/.php_cs \"$line\";",
            "bin/phpcbf --standard=PSR2 --encoding=utf-8 -n -p \"$line\";",
            "git add \"$line\";",
            "done",
            "echo committing on branch $(git rev-parse --abbrev-ref HEAD)"
        ]
    }
}

这是对我有用的示例。它基本上做的是:

每次 运行“composer install”或“c​​omposer update”时,都会检查文件夹 .git/hooks 中的挂钩。如果挂钩已经就位,则什么也不会发生。如果它们丢失了,那么上面的行将被解析为开头带有 shebang 的钩子。然后在每次有人触发钩子时执行它们。

如果您没有大脚本,在我看来,这是比四处复制脚本更好的解决方案。

注意:如果您更改 composer.json 中的钩子行​​,您必须先删除相应的钩子,然后再 运行 "composer安装”,否则什么都不会改变。

如果您的存储库是 npm application, you can add this nice library as a dependency: Husky

文件package.json

...
"devDependencies": {
    ...
    "husky": ">=4"
},
"husky": {
    "hooks": {
        "pre-commit": "npm test"
    }
}

pre-commit 基本上可以是任何命令:如果它以退出代码 0 结束,则提交通过,否则提交被中断。