为什么 GIT 钩子不在 Windows 上执行?

Why aren't GIT hooks executed on a Windows?

我在 Windows 2008 R2 服务器机器上安装了 Bonobo Git 服务器。我创建了一个存储库并将 post-receive.bat 文件放在 D:\Inetpub\Bonobo.Git.Server\App_Data\Repositories\REPO\hooks 目录中。

这是文件的内容:

#!/D/Inetpub/Bonobo.Git.Server/App_Data/Git/sh.exe

BINPATH="/D/Inetpub/Bonobo.Git.Server/App_Data/Git/"
REPOPATH="/D/Inetpub/Bonobo.Git.Server/App_Data/Repositories/REPO/"
GIT="${BINPATH}git"

# Change working directory to the repo root
cd $REPOPATH

read oldrev
read newrev
read refname

branch=$($GIT rev-parse --symbolic --abbrev-ref $refname)

if [ "master" == "$branch" ]; then
    echo "receive $branch $refname" >> "${REPOPATH}hookstest.log"
fi

如果我从 shell 执行此文件并键入 "whatever whatever master",则文件 "receive master master" 将添加到 hookstest.log。但是,当我将更改推送到 REPO 时,文件没有更新,就好像它没有被执行一样。

我不知道去哪里查找发生的错误。大多数 linux 教程都提到文件必须有 +x 标志。这显然在 Windows 上不存在,但我检查过并且在 IIS 中运行 Bonobo Git 服务器的用户对批处理文件具有执行权限。

我也在犹豫文件名,所以我复制了它并删除了.bat扩展名。那也无济于事。知道如何让钩子在 Windows 服务器上工作吗?

编辑

按照@crashmstr 的建议,我创建了一个批处理文件(一个有扩展名,一个没有),其中包含:

date /t >> D:\Inetpub\Bonobo.Git.Server\App_Data\Repositories\REPO\testhooks.txt

即使文件已创建,当我手动执行文件时,这也不起作用。

使用最新版本的 Bonobo(比 6.1 晚一点,但是这方面没有任何变化),我刚刚在 repo 的 hooks 目录中创建了一个名为 'pre-receive' 的文件。

此文件没有文件扩展名,仅包含以下内容:

#!/bin/sh
echo "xx" > here.txt

当我提交到这个 repo 时,文件 "here.txt" 被写入 repo 文件夹的顶部。

如果这个 没有 工作,那么我会从 SysInternals 获得 运行 ProcMon,并将路径过滤器设置为包括 "here.txt"(也许"pre-receive") 并检查了为什么这些文件没有被写入/读取。

观察 "here.txt" 正在使用 ProcMon 编写,表明它是由 \App_Data\Git\sh.exe 中的 sh.exe 的副本编写的。我不太确定从“#!/bin/sh”到 \App_Data\Git\sh.exe 的是谁和什么,但它似乎有效。

我不确定是什么问题。最后,我通过创建一个包含以下内容的文件 D:\Inetpub\Bonobo.Git.Server\App_Data\Repositories\REPO\hooks\post-receive(无扩展名)使其正常工作:

#!/D/Inetpub/Bonobo.Git.Server/App_Data/Git/sh.exe

echo "BEGIN post-receive script"

APPPATH="/D/Inetpub/Bonobo.Git.Server/App_Data"
SVN="/D/csvn/bin/svn"

REPOPATH="$APPPATH/Repositories/REPO"
SVNSYNCPATH="$APPPATH/SVN-sync"
GIT="$APPPATH/Git/git"

mapping["master"]="trunk"
mapping["develop"]="development"

# Change working directory to the repo root
cd $REPOPATH

read oldrev newrev refname    

echo "oldrev - $oldrev"
echo "newrev - $newrev"
echo "refname - $refname"

branch=$($GIT rev-parse --symbolic --abbrev-ref $refname)
echo "branch - $branch"
echo ""

if [ "master" == "$branch" ]; then
    result=($($GIT diff $oldrev $newrev --name-status))
    echo "Detected $((${#result[@]}/2)) changes:"

    idx=0
    while [ $idx -lt ${#result[@]} ]
    do      
        status=${result[$idx]}
        filename=${result[$(($idx+1))]}
        echo -n "$status - $filename "

        case $status in
            "A")
                echo "added"
                ;;
            "M")
                echo "updated"
                ;;
            "D")
                echo "deleted"
                ;;
            "R")
                echo "renamed"
                ;;
            "C")
                echo "copied"
                ;;
            *)
                echo "unknown status"
                ;;
        esac

        idx=$(($idx+2))
    done
fi
echo ""

echo "END post-receive script"