像许多其他版本控制系统一样,Git 提供了一种在某些重要操作发生时触发自定义脚本的方式。这些钩子分为两类:客户端钩子和服务器端钩子。客户端钩子会在执行提交和合并等操作时触发,而服务器端钩子则会在推送提交等网络操作时运行。你可以用这些钩子来实现各种各样的功能。

第56.1节:Git 预推送钩子(pre-push hook)

预推送脚本在 git push 检查远程状态后,但在推送任何内容之前被调用。如果该脚本以非零状态退出,则不会推送任何内容。

预推送钩子的参数

该钩子会接收以下参数:

  • $1 —— 要推送的远程仓库名称(例如:origin)
  • $2 —— 推送的目标 URL(例如:https://://.git)

推送的提交信息以标准输入的形式提供,格式如下:

<local_ref> <local_sha1> <remote_ref> <remote_sha1>

示例值:

  • local_ref = refs/heads/master
  • local_sha1 = 68a07ee4f6af8271dc40caae6cc23f283122ed11
  • remote_ref = refs/heads/master
  • remote_sha1 = efd4d512f34b11e3cf5c12433bbedd4b1532716f

示例预推送脚本

以下示例预推送脚本是从默认的 pre-push.sample 文件中提取的,该文件在使用 git init 初始化新仓库时自动生成。

bash复制

# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).

remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000

while read local_ref local_sha remote_ref remote_sha
do
    if [ "$local_sha" = $z40 ]
    then
        # Handle delete
        :
    else
        if [ "$remote_sha" = $z40 ]
        then
            # New branch, examine all commits
            range="$local_sha"
        else
            # Update to existing branch, examine new commits
            range="$remote_sha..$local_sha"
        fi

        # Check for WIP commit
        commit=$(git rev-list -n 1 --grep '^WIP' "$range")
        if [ -n "$commit" ]
        then
            echo >&2 "Found WIP commit in $local_ref, not pushing"
            exit 1
        fi
    fi
done
exit 0

钩子的作用

这个脚本的作用是防止推送包含以“WIP”(进行中)开头的日志信息的提交。它通过检查推送的提交范围,查找是否存在以“WIP”开头的提交,并在发现此类提交时阻止推送。

第56.2节:安装钩子

钩子存储位置

钩子都存储在 Git 目录的 hooks 子目录中。在大多数项目中,这是 .git/hooks。

启用钩子脚本

要启用一个钩子脚本,只需在 .git/hooks 子目录中放置一个命名恰当(无扩展名)且可执行的文件即可。