git pull/fetch/checkout 在 git 挂钩中无法找到正确的存储库目录

git pull/fetch/checkout in git hook is unable to locate correct repository directory

我正在试验 git 挂钩,并试图获取我用来托管我的代码的 git 服务器,以便在每次推送提交后执行构建。我已经从我托管的服务器存储库中克隆了一个本地(在服务器上)git 存储库。服务器存储库和服务器的 repo 本地实例都在同一台机器上,即服务器。我使用这个本地实例化来执行构建。

目前我正在使用 post-update git 挂钩到 运行 每次新推送到存储库后的以下脚本:

#!/bin/sh

#get the branch name that was pushed
branch=$(git rev-parse --symbolic --abbrev-ref )

echo performing a build on branch:   $branch

cd /path/to/server/local/repodir
git checkout -f $branch
git pull origin $branch

make

echo "Build Done"

我能够 运行 git 挂钩,它实际上构建一切正常。但是,git checkout 和 pull 命令失败,并给出以下异常:

fatal: not a git repository: '.'

我不确定为什么会这样,因为我 cd 进入 git 目录之前的命令。 运行 服务器终端中的相同脚本 运行 没问题,git 会像往常一样执行操作。我已经通过在挂钩中输入 pwdls -la 进行了检查,并且 shell 在正确的文件夹中并且有一个 . git里面的版本库项目,意思是git在这个文件夹中执行应该没有问题。

关于 git 钩子有什么特别之处阻止 git 检出和拉取刚刚从另一个设备推送的这些回购协议吗?我不这么认为,但我不明白为什么 git 似乎找不到 git 存储库,而且似乎只在看 '.'

在 git 钩子中 git checkout/pull 的正确方法是什么?

当您操作挂钩时,某些环境变量,例如 GIT_DIR 和可能的 GIT_WORK_TREE,会在存储库中设置,以便挂钩正常工作。如果您在不同的存储库中工作,则需要取消设置这些变量,因为它们将不再反映正确的存储库。

因此,例如,您可以这样做:

#!/bin/sh

#get the branch name that was pushed
branch=$(git rev-parse --symbolic --abbrev-ref )

echo performing a build on branch:   $branch

(
    unset $(env | sed -ne 's/^\(GIT_.*\)=.*//p')
    cd /path/to/server/local/repodir
    git checkout -f $branch
    git pull origin $branch

    make
)

echo "Build Done"

注意 unset 命令和子 shell。