Git 是一个出色的工具。 它不仅允许您通过挂钩跟踪文件中的更改,还可以与其他人无缝协作。 在这方面,Git 是推动 FOSS 发展的工具之一。
但是,Git 的最大问题之一是管理存储库需要时间和精力。 为了 example,提交和同步这些存储库可能需要两到三个 git 命令。 这使得管理它们不仅乏味而且容易出现用户错误。 在这里,我们向您展示一些简单而有效的 Git 挂钩,以更好地管理您的存储库。
笔记: y 你也可以在 Emacs 中管理 Git。 学习怎样!
内容
什么是 Git 钩子?
git-hook 的核心是一个灵活的子命令,您可以使用它来创建自定义脚本,只要 Git 对存储库执行操作,这些脚本就会运行。 为了 example甚至可以在提交之前使用 hook 自动检查存储库中的样式错误。
hook 子命令通过读取存储库“.git”目录下的“hooks”文件夹来工作。 此文件夹包含许多预制文件,这些文件为 Git 中可以自动执行的每个操作提供示例脚本。

大多数情况下,您可以使用任何您喜欢的脚本语言编写 git 钩子。 这使得它对任何软件开发人员来说都非常灵活和平易近人。
提示: 要开始使用 Git,您需要先设置 Git 的用户名和电子邮件。 在本指南中了解怎样操作。
1.防止推送到Master
用户在 Git 中最常犯的错误之一是将提交从开发分支直接推送到主分支。 如果您使用 Github 来跟踪和维护您的项目,这可能会非常令人沮丧。

您可以通过创建一个“预推送”Git 挂钩来防止此问题,该挂钩将在您尝试从 master 分支推送存储库时进行检查和确认。
- 转到要保护的 Git 存储库。

- 使用您的检查脚本创建一个 Git 挂钩文件。 由于这是一个应该在“推送”之前运行的挂钩,因此您需要创建一个“预推送”挂钩文件:
touch .git/hooks/pre-push
- 在文本编辑器中打开新的挂钩文件。
nano .git/hooks/pre-push
- 在里面,写下你新的“预推”钩子。 为了 example,以下是一个脚本,当您从 master 分支推送时会要求您确认:
#!/bin/sh protect='master' current=$(git symbolic-ref HEAD | sed -e 's,.*/(.*),1,') if [ $protect = $current ] then read -p "Confirm push to master? Y/n." -n 1 -r < /dev/tty echo if echo $REPLY | grep -E '^[Yy]$' > /dev/null then exit 0 fi exit 1 else exit 0 fi
- Save 你的新钩子。 在 nano 中,按 Ctrl + O,然后按 Ctrl + X 来执行此操作。

- 运行以下命令以确保 Git 可以运行您的新挂钩。
chmod +x .git/hooks/pre-push
2.拒绝推送到主分支
除了防止自己推送到 master 之外,您还可以创建一个服务器端挂钩,拒绝任何推送到其 master 分支。 如果您与多个开发人员共享一个存储库,这将非常有用。

通过创建一个“预接收”挂钩来解决这个问题,该挂钩将自动阻止任何受限用户推送到主分支。
- 在您的远程存储库中创建“预接收”Git 挂钩文件。
touch .git/hooks/pre-receive
- 打开这个文件。
nano .git/hooks/pre-receive
- 在“预接收”挂钩中添加拒绝脚本。 为了 example,以下代码行应该开箱即用:
#!/bin/sh branch=$(git symbolic-ref HEAD | sed -e 's,.*/(.*),1,') blacklist=(alice bob) if [[ ${blacklist[*]} =~ $USER ]]; then if [ "$branch" == "master" ]; then echo "You are not allowed commit changes in this branch" exit 1 fi fi
- Save 你的新钩子文件。 就我而言,我需要按 Ctrl + O,然后按 Ctrl + X 来保存文件。
- Save 您的钩子脚本并使其可执行。
chmod +x .git/hooks/pre-receive
提示: 您还可以使用 Git 别名来提高 Git 的使用效率。
3. 锁定存储库以防止变基
用户在 Git 中犯的另一个常见错误是变基当前活动的分支。 如果您正在与多个贡献者一起处理存储库,这可能是一个令人沮丧的问题,因为变基将删除其他用户所做的提交。

您可以通过创建一个“pre-rebase”挂钩来防止这个问题,该挂钩将检查当前分支是否被锁定。
- 在“.git/hooks”目录中创建一个“pre-rebase”文件:
touch .git/hooks/pre-rebase
- 打开此文件进行编辑。
nano .git/hooks/pre-rebase
- 在新的挂钩文件中添加 rebase 脚本。
#!/bin/sh branch="$2" [ -n "$branch" ] || branch=$(git rev-parse --abbrev-ref HEAD) lock="branch.${branch}.rebaselock" if [ "$(git config --bool "$lock")" = true ]; then echo "pre-rebase hook: "$lock" is set to true. Refusing to rebase." exit 1 fi
- Save 您的新钩子文件并使其可执行。
chmod +x .git/hooks/pre-rebase
4. 强制对代码进行样式和语法检查
Git 钩子最有用的用途之一是将它与代码 linter 链接起来。 这是一个简单的程序,用于检查您的代码是否遵循项目的样式和格式。

- 要将 linter 链接到您的 Git 存储库,首先制作一个“预提交”挂钩文件。
touch .git/hooks/pre-commit
- 为您的项目语言安装合适的 linter。 在这种情况下,我使用“shellcheck”来分析我的 Bash 代码:
sudo apt install shellcheck
- 打开新的挂钩文件并添加以下脚本。
#!/bin/bash for file in $(git diff --cached --name-only --diff-filter=AM | grep -E '.sh$') do shellcheck "$file" # Run the linter for every new file. if [ $? -ne 0 ]; then exit 1 # Terminate the commit if the linter fails. fi done
- Save 您的新钩子文件并使其可执行:
chmod +x .git/hooks/pre-commit
5. 自动通知用户存储库更改
最后,您还可以创建一个 Git 挂钩,只要您的存储库收到新提交,它就会自动发送电子邮件。 如果您想为您的存储库创建一个简单的通知系统,这将很有帮助。
- 在存储库的 .git/hooks 目录中创建一个“post-receive”挂钩文件:
touch .git/hooks/post-receive
- 打开新的 Git 挂钩文件并输入以下脚本:
#!/bin/sh commit_message=$(git log -1 --pretty=%B) users=("[email protected]" "[email protected]" "[email protected]") for user in "${users[@]}"; do mail -s "New Commit: $commit_message" $user < /dev/null done
- Save 您的新钩子文件并使其可执行。
chmod +x .git/hooks/post-receive
经常问的问题
我可以用编译语言(例如 C)编写 Git 挂钩吗?
Git 钩子的最大限制之一是它要求您使用一种可以直接从终端运行的语言。 这意味着 Git hooks 的脚本不支持任何编译语言。 为了 example,您可以使用 Python 或 Shell 而不是 C 或 C++ 创建一个新的 Git 钩子。
是否可以在同一个 Git 存储库中运行多个挂钩?
是的。 虽然上面的示例将钩子显示为单个、离散的功能,但您可以轻松地将它们混合在一起以创建您自己独特的工作流程,从而使 Git 钩子非常灵活并且适用于任何编码情况。 为了 example,您可以在自己的存储库中同时使用“Prevent Push to Master”预推送挂钩和“语法检查”预提交挂钩。
为什么电子邮件 Git 挂钩不向用户发送电子邮件?
此问题很可能是由于您的远程服务器无法正确发送任何外发电子邮件。 要解决此问题,请确保您的远程服务器是安全的,并且它有一个有效的邮件传递代理和一个 SMTP 域。
图片来源: 不飞溅. 所有更改和屏幕截图 Ramces Red。
订阅我们的新闻!
我们最新的教程直接发送到您的收件箱
注册所有时事通讯。 注册即表示您同意我们的隐私政策,欧洲用户同意数据传输政策。 我们不会共享您的数据,您可以随时取消订阅。 订阅