Jakub Narębski
Jakub Narębski

Reputation: 323524

How can I enable anonymous read access (pull) but authenticated write access (push) to a git repository over http?

I want to have git repository available via "smart" HTTP to which only I can push, but which anybody (or anybody with account) can clone / fetch from.

In the git-http-backend(1) manpage one can find the following example configuration for Apache web server:

Ensure mod_cgi, mod_alias, and mod_env are enabled, set GIT_PROJECT_ROOT (or DocumentRoot) appropriately, and create a ScriptAlias to the CGI:

SetEnv GIT_PROJECT_ROOT /var/www/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/

To enable anonymous read access but authenticated write access, require authorization with a LocationMatch directive:

<LocationMatch "^/git/.*/git-receive-pack$">
        AuthType Basic
        AuthName "Git Access"
        Require group committers
        #...
</LocationMatch>

Unfortunately this configuration doesn't work. I can fetch / clone repository without any problems, without requiring authenthication, but pushing fails:

$ git push origin master
error: Cannot access URL http://localhost/git/test.git/, return code 22
fatal: git-http-push failed

Examining error.log of Apache web server doesn't help:

[...] Service not enabled: 'receive-pack'
[...] Request not supported: '/var/www/git/test.git/'

The access.log tells us that git push first uses GET method on /git/test.git/info/refs?service=git-receive-pack query-based URL, which is not covered by LocationMatch directive:

[...] "GET /git/test.git/info/refs?service=git-receive-pack HTTP/1.1" 403 304 "-" "git/1.7.10.4"
[...] "GET /git/test.git/info/refs HTTP/1.1" 200 267 "-" "git/1.7.10.4"
[...] "GET /git/test.git/HEAD HTTP/1.1" 200 337 "-" "git/1.7.10.4"
[...] "PROPFIND /git/test.git/ HTTP/1.1" 404 250 "-" "git/1.7.10.4"

(the following lines are about fallback to "dumb" WebDAV based HTTP push - is it possible to disable this fallback?).


For now I use the following workaround: I require valid user for both fetch and push (using modified configuration from "authentication for both reads and writes" example in git-http-backend(1) manpage), and restrict push to single user via pre-receive hook by examining REMOTE_USER environment variable.

Upvotes: 7

Views: 3168

Answers (2)

arch
arch

Reputation: 11

You have to update your repo .git/config file with the following value:

[http]
    receivepack = true

Upvotes: 1

VonC
VonC

Reputation: 1324737

One not so complex alternative is to use gitolite in addition of your Apache-git setup.
You can plug gitolite to Apache easily enough (no ssh config required).

See as an example: httpd.conf, combined with this local gitolite installation script.

You can then easily declare Apache logins for Write access, and @all for read access.

Upvotes: 1

Related Questions