在Windows上使用git-http-backend.exe设置Git服务器

23

我正在搭建一个Git服务器(1.7.2.3),在WS 2008机器上使用Apache和git-http-backend.exe。我一直在遵循一个好的教程这里。我的GUI已经可以正常工作,我可以匿名克隆,如果我将以下内容放入存储库的配置中,我也可以匿名推送:

[http]
 receivepack = true

我已经在httpd.conf文件中添加了以下内容:

SetEnv GIT_PROJECT_ROOT C:/GIT/Repositories
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAliasMatch \
        "(?x)^/(.*/(HEAD | \
                    info/refs | \
                    objects/(info/[^/]+ | \
                             [0-9a-f]{2}/[0-9a-f]{38} | \
                             pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
                    git-(upload|receive)-pack))$" \
                    "C:/Program Files (x86)/git/libexec/git-core/git-http-backend.exe/$1"

<Directory />
  Allow from all
</Directory>

<LocationMatch "^/git/.*/git-receive-pack$">
        AuthType Basic
        AuthName "Git Access"
  AuthUserFile C:/GIT/ApacheConfig/users
  AuthGroupFile  C:/GIT/ApacheConfig/groups
        Require group repogeneral        
</LocationMatch>

当我添加“LocationMatch”时,我仍然可以匿名克隆或通过在URL中指定名称进行克隆,git clone http://jon@myserver.com
它会提示输入密码并进行克隆。
但是,当我尝试将更改推送回仓库时,我会收到以下错误:
错误:无法访问URL http://jon@myserver.com/newtestrepo.git/,返回代码22 致命错误:git-http-push失败
我一直在查看http-backend.exe man page的示例,但无法使它们正常工作。
这是我的组文件(这只是测试示例,因此不会在生产中使用):
admin: jon steve admin
webview: jon steve web
repogeneral: jon steve
testrepo: jon admin
testrepo2: jon steve web

这是用户文件:

jon:$apr1$kEKVExYx$guIF9oYV8buGhFLZr16XN0
steve:$apr1$jvgjF9nv$PvWsHH.cSOBN5ymk6NT1B0
admin:$apr1$vzXgDskN$oszCei3tkHNUgtLj2HkHF/
web:$apr1$wS0do7hb$VA9tsc9c9LwY5PcjfhdwK0

我知道用户名jon可以使用,如果我在GUI部分加入目录要求,就可以毫无问题地使用用户名jon登录(指向与locationmatch相同的用户和组文件)。
我不确定此时我错过了哪些配置(假设这是一个配置问题)。
如果能提供克服这个最后障碍的任何建议将非常棒。
编辑
我已经进行了一些尝试,并获得以下信息:
如果我使用以下命令克隆repo:
git clone http://jon@myserver.com/remotetest.git

我能取出存储库,但当我尝试使用以下命令推送回去时:

git push origin master

它会要求我的密码,我输入后,它再次要求输入密码,之后我会得到以下错误:

C:\temp\remotetest\remotetest>git push origin master Password: Password: error: Cannot access URL http://jon@myserver.com/remotetest.git/, return code 22 fatal: git-http-push failed

在我的Apache访问日志中,我得到了以下内容:

192.168.1.2 - - [29/Sep/2010:21:58:19 +0100] "GET /remotetest.git/info/refs?service=git-upload-pack HTTP/1.1" 200 38
192.168.1.2 - - [29/Sep/2010:21:58:51 +0100] "GET /remotetest.git/info/refs?service=git-receive-pack HTTP/1.1" 403 -
192.168.1.2 - - [29/Sep/2010:21:58:51 +0100] "GET /remotetest.git/info/refs HTTP/1.1" 200 -
192.168.1.2 - - [29/Sep/2010:21:58:51 +0100] "GET /remotetest.git/HEAD HTTP/1.1" 200 23

有趣的是,当我使用URL中的用户名克隆时,无论我输入什么密码,它都能正常工作。我想这是因为我应该能够匿名拉取。不确定为什么此时还要求输入密码。
我在日志中也看到了这个错误:
[Wed Sep 29 22:33:00 2010] [error] [client 192.168.1.2] client denied by server configuration: C:/Program Files (x86)/Git/libexec/git-core/git-http-backend.exe
[Wed Sep 29 22:33:00 2010] [error] [client 192.168.1.2] client denied by server configuration: C:/Program Files (x86)/Git/libexec/git-core/git-http-backend.exe

编辑2

我尝试通过以下方式重新创建密码文件:

htpasswd -c -m C:/git/apacheconfig/users jon

但这并没有帮助。

编辑3

在httpd.conf中的PHP配置,它使用相同的用户文件进行基本身份验证:

<Directory "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/htdocs">
    AuthName "GitUsers"
    AuthType Basic
    AuthUserFile C:/GIT/ApacheConfig/users
AuthGroupFile  C:/GIT/ApacheConfig/groups

    require group webview
</Directory>

编辑4

好的,我可以愉快地在匿名模式下克隆和推送,但推送时身份验证失败。

C:\temp\test2\temp\test>git push origin master
Password:
Password:
error: Cannot access URL http://jon@192.168.10.97:8000/repositories/test.git/, return code 22
fatal: git-http-push failed

我把httpd.conf更改为以下内容:
<VirtualHost *:80>
    SetEnv GIT_PROJECT_ROOT "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/htdocs/repositories"
    SetEnv GIT_HTTP_EXPORT_ALL

    <Directory "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/htdocs/repositories">
       Options Indexes FollowSymLinks MultiViews Includes ExecCGI
       AllowOverride None
       Order allow,deny
       Allow from all
    </Directory>

    <LocationMatch "^/repositories/.*/git-receive-pack$">
        AuthType Basic
        AuthName "Git Access"
        AuthUserFile "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/htdocs/repositories/.htpasswd"
        Require valid-user
    </LocationMatch>
    ScriptAliasMatch \
            "(?x)^/repositories/(.*/(HEAD | \
                            info/refs | \
                            objects/(info/[^/]+ | \
                                     [0-9a-f]{2}/[0-9a-f]{38} | \
                                     pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
                            git-(upload|receive)-pack))$" \
            "C:/Program Files (x86)/Git/libexec/git-core/git-http-backend/$1"

    ErrorLog C:/GIT/error_log
    CustomLog C:/GIT/access_log combined
</VirtualHost>

有趣的是,当我创建一个新repo(git init --bare newrepo.git)时,它没有创建info/refs文件。我必须执行“git update-server-info”命令来创建该文件。
Apache访问日志有一些有趣的东西,可能是线索:
192.168.10.97 - - [05/Oct/2010:22:48:26 +0100] "GET /repositories/test.git/info/refs?service=git-receive-pack HTTP/1.1" 200 -
192.168.10.97 - - [05/Oct/2010:22:48:26 +0100] "GET /repositories/test.git/HEAD HTTP/1.1" 200 23
192.168.10.97 - - [05/Oct/2010:22:48:28 +0100] "PROPFIND /repositories/test.git/ HTTP/1.1" 405 248

那时我试图将更改“推送”回仓库,但它们是GET命令而不是POST。 我不确定PROPFIND是什么,还没有找到太多信息。 我认为(阅读周围的内容),可能正在进行某种重写,将POST更改为GET并将其删除或其他操作。 不过我已经到了我的极限了。
谢谢

我不确定为什么“htdocs”会涉及到Directory定义。 - VonC
这是Apache默认用于提供文件的位置。我使用PHP GUI来显示存储库,它使用相同的authuserfile,并提供弹出式登录,与相同的用户名和密码一起工作。将其用作测试以确保Apache可以理解用户密码文件。 - Jon
这个问题应该放在http://serverfault.com/上,因为它更多地涉及设置和配置,而不是编程,对吧? - John K
我确实考虑过这个问题,但我在StackOverflow上找到的Git问题和在ServerFault上找到的一样多。 - Jon
1个回答

25

好的,地狱已经冻结,我终于让这个工作了!

我认为我的设置中有两个根本性问题。

1)用户未通过身份验证,我发现这样有帮助:

SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER

其次,我无法使物理上的“Directory”起作用。

<Directory "C:/GIT/Apache/repositories">
Options +ExecCGI
AuthType Basic
AuthName intranet
AuthUserFile "C:/GIT/Apache/config/users"
Require valid-user
</Directory>
为了解决这个问题,我在拉取和推送的时候都使用了locationMatch。这意味着你需要在拉取和推送时进行身份验证。如果你想要让拉取变得烦人,可以删除“git-upload-pack”部分。
希望这能帮助其他人。
以下是我的最终httpd.conf文件:
DocumentRoot "C:/GIT/Apache/www"

<Directory />
Options +ExecCGI
Allow from all  
</Directory>

<Directory "C:/GIT/Apache/www">
  Allow from all
</Directory>

<Directory "C:/GIT/Apache/www/secure">
AuthType Basic
AuthName intranet
AuthUserFile "C:/GIT/Apache/config/users"
require valid-user
</Directory>

SetEnv GIT_PROJECT_ROOT C:/GIT/Apache/repositories
SetEnv GIT_HTTP_EXPORT_ALL
SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER
ScriptAliasMatch \
    "(?x)^/(.*/(HEAD | \
                    info/refs | \
                    objects/(info/[^/]+ | \
                             [0-9a-f]{2}/[0-9a-f]{38} | \
                             pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
                    git-(upload|receive)-pack))$" \
                    "C:/Program Files/git/libexec/git-core/git-http-backend.exe/$1"


<LocationMatch "^/.*/git-receive-pack$">
Options +ExecCGI
AuthType Basic
AuthName intranet
AuthUserFile "C:/GIT/Apache/config/users"
Require valid-user
</LocationMatch>

<LocationMatch "^/.*/git-upload-pack$">
Options +ExecCGI
AuthType Basic
AuthName intranet
AuthUserFile "C:/GIT/Apache/config/users"
Require valid-user
</LocationMatch>

嗨Jon,你的工作非常棒。你能帮我理解一下你是如何管理用户配置的吗?因为这似乎对你来说不是问题。 - pollux1er
@pollux1er 最终我转移到了GitHub。因为我只是自己在使用,所以没有太多担心用户的问题。现在我已经记不清楚太多细节了,抱歉并祝好运。 - Jon
感谢@Jon提出的问题和您自己的答案,但我在自测中发现了您配置文件中的一些错误。您需要将完整位置添加到AuthUserFile中。如果没有这个,您会一遍又一遍地收到500错误,例如AH01620:无法打开密码文件。我的解决方案是:AuthUserFile“C:/GIT/Apache/config/users/.htaccess” - Dominik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接