简体   繁体   中英

Git Smart HTTP protocol fails to execute server side hooks on push

I'm trying to set up smart HTTP using git-http-backend. I tried to follow plenty of documentation/guides online on how to do this. I'm running Apache 2.4 on Windows 7. In my httpd.conf I have

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>

For C:\\repos , I made sure that Everyone has full access. I'm running httpd.exe under my user account so requests made to the server should see git 2.12.2 just fine on the PATH.

In C:\\repos , I have a bare repo called foo.git . Inside that repo I do git config http.receivepack true . I was able to clone just fine with http://localhost/git/foo.git . With no server side hooks enabled , I was able to push a commit just fine.

Now the annoying part -- I create an update hook which is just C:\\repos\\foo.git\\hooks\\update that contains the following:

#!/bin/bash
echo foo
exit 0

I try pushing from the local repo and get

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'

Ok, so I try pushing the same thing with the git protocol -- I run git daemon --reuseaddr --base-path=C:\\repos C:\\repos . Then I put a git-daemon-export-ok inside foo.git . I go back to the local repo and push to 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

Everything goes okay. I push with the file protocol -- file:///c/repos/foo.git and that works okay too.

I tried doing a

<Directory c:/>
    Require all granted
</Directory>

in my httpd.conf to make sure it had nothing to do with access issues. I switched this back to Require all denied of course.

Based on a verbose push, seems like git-receive-pack can't start the bash interpreter on the server-side, but I'm not sure why. Again, it's spawning from an httpd.exe that's running under my user account and I can execute git just fine manually. And again, git can be found on the PATH just fine. What kind of obvious solution am I missing here?

The problem was in my httpd.conf file. Additionally I had to do

SetEnv PATH "C:\\Program Files\\Git\\bin;C:\\Program Files\\Git\\usr\\bin;${PATH}"
PassEnv USERNAME

First, the SetEnv was necessary bc the interpreter wasn't being invoked. In one of my hooks, I have a shebang line of #!/usr/bin/env bash , thus the addition of C:\\Program Files\\Git\\usr\\bin . In another hook, I could have #!/bin/bash , so C:\\Program Files\\Git\\bin would be necessary.

Secondly, the reason for PassEnv USERNAME was because one of the hooks was utilizing that environment variable which httpd excludes out when passing an environment to the CGI script. It's talked about in the Apache docs here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM