Git 智能 HTTP 协议无法在推送时执行服务器端挂钩
Git Smart HTTP protocol fails to execute server side hooks on push
我正在尝试使用 git-http-backend 设置智能 HTTP。我试图在网上关注大量 documentation/guides 如何做到这一点。我在 Windows 7 上 运行ning Apache 2.4。在我的 httpd.conf 我有
SetEnv GIT_PROJECT_ROOT c:/repos
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ "c:/program files/git/mingw64/libexec/git-core/git-http-backend.exe/"
<LocationMatch "^/git/.*/git.*$">
Require all granted
</LocationMatch>
<Directory "c:/program files/git/mingw64/libexec/git-core/">
<Files "git-http-backend.exe">
Require all granted
</Files>
</Directory>
对于 C:\repos
,我确保每个人都有完全访问权限。我在我的用户帐户下 运行ning httpd.exe 所以对服务器的请求应该在 PATH 上看到 git 2.12.2 就好了。
在 C:\repos
中,我有一个名为 foo.git
的裸仓库。在那个回购协议中,我做 git config http.receivepack true
。我能够用 http://localhost/git/foo.git 克隆得很好。 在没有启用服务器端挂钩的情况下,我能够很好地推送提交。
现在是烦人的部分 -- 我创建了一个 C:\repos\foo.git\hooks\update
的更新挂钩,其中包含以下内容:
#!/bin/bash
echo foo
exit 0
我尝试从本地仓库推送并获取
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 315 bytes | 315.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://localhost/git/foo.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'http://localhost/git/foo.git'
好的,所以我尝试使用 git 协议来推动同样的事情——我 运行 git daemon --reuseaddr --base-path=C:\repos C:\repos
。然后我在foo.git
里面放了一个git-daemon-export-ok
。我回到本地仓库并推送到 git:///foo.git
:
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 315 bytes | 35.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: foo
To git:///foo.git
3b33593..6af841c master -> master
一切顺利。我使用文件协议推送 -- file:///c/repos/foo.git
并且它也可以正常工作。
我试过
<Directory c:/>
Require all granted
</Directory>
在我的 httpd.conf 中以确保它与访问问题无关。当然,我将其切换回 Require all denied
。
基于冗长的推送,似乎 git-receive-pack 无法在服务器端启动 bash 解释器,但我不确定为什么。同样,它是从我的用户帐户下 运行ning 的 httpd.exe 产生的,我可以手动执行 git 就好了。同样,可以在 PATH 上找到 git 就好了。我在这里缺少什么样的明显解决方案?
问题出在我的 httpd.conf 文件中。另外我必须做
SetEnv PATH "C:\Program Files\Git\bin;C:\Program Files\Git\usr\bin;${PATH}"
PassEnv USERNAME
首先,SetEnv
是必要的 b.c。没有调用解释器。在我的一个钩子中,我有一条 #!/usr/bin/env bash
的 shebang 行,因此添加了 C:\Program Files\Git\usr\bin
。在另一个钩子中,我可以有 #!/bin/bash
,所以 C:\Program Files\Git\bin
是必要的。
其次,PassEnv USERNAME
的原因是因为其中一个挂钩正在利用 httpd 在将环境传递给 CGI 脚本时排除的环境变量。在 the Apache docs here
中讨论过
我正在尝试使用 git-http-backend 设置智能 HTTP。我试图在网上关注大量 documentation/guides 如何做到这一点。我在 Windows 7 上 运行ning Apache 2.4。在我的 httpd.conf 我有
SetEnv GIT_PROJECT_ROOT c:/repos
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ "c:/program files/git/mingw64/libexec/git-core/git-http-backend.exe/"
<LocationMatch "^/git/.*/git.*$">
Require all granted
</LocationMatch>
<Directory "c:/program files/git/mingw64/libexec/git-core/">
<Files "git-http-backend.exe">
Require all granted
</Files>
</Directory>
对于 C:\repos
,我确保每个人都有完全访问权限。我在我的用户帐户下 运行ning httpd.exe 所以对服务器的请求应该在 PATH 上看到 git 2.12.2 就好了。
在 C:\repos
中,我有一个名为 foo.git
的裸仓库。在那个回购协议中,我做 git config http.receivepack true
。我能够用 http://localhost/git/foo.git 克隆得很好。 在没有启用服务器端挂钩的情况下,我能够很好地推送提交。
现在是烦人的部分 -- 我创建了一个 C:\repos\foo.git\hooks\update
的更新挂钩,其中包含以下内容:
#!/bin/bash
echo foo
exit 0
我尝试从本地仓库推送并获取
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 315 bytes | 315.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://localhost/git/foo.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'http://localhost/git/foo.git'
好的,所以我尝试使用 git 协议来推动同样的事情——我 运行 git daemon --reuseaddr --base-path=C:\repos C:\repos
。然后我在foo.git
里面放了一个git-daemon-export-ok
。我回到本地仓库并推送到 git:///foo.git
:
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 315 bytes | 35.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: foo
To git:///foo.git
3b33593..6af841c master -> master
一切顺利。我使用文件协议推送 -- file:///c/repos/foo.git
并且它也可以正常工作。
我试过
<Directory c:/>
Require all granted
</Directory>
在我的 httpd.conf 中以确保它与访问问题无关。当然,我将其切换回 Require all denied
。
基于冗长的推送,似乎 git-receive-pack 无法在服务器端启动 bash 解释器,但我不确定为什么。同样,它是从我的用户帐户下 运行ning 的 httpd.exe 产生的,我可以手动执行 git 就好了。同样,可以在 PATH 上找到 git 就好了。我在这里缺少什么样的明显解决方案?
问题出在我的 httpd.conf 文件中。另外我必须做
SetEnv PATH "C:\Program Files\Git\bin;C:\Program Files\Git\usr\bin;${PATH}"
PassEnv USERNAME
首先,SetEnv
是必要的 b.c。没有调用解释器。在我的一个钩子中,我有一条 #!/usr/bin/env bash
的 shebang 行,因此添加了 C:\Program Files\Git\usr\bin
。在另一个钩子中,我可以有 #!/bin/bash
,所以 C:\Program Files\Git\bin
是必要的。
其次,PassEnv USERNAME
的原因是因为其中一个挂钩正在利用 httpd 在将环境传递给 CGI 脚本时排除的环境变量。在 the Apache docs here