7

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.

Jakub Narębski
  • 309,089
  • 65
  • 217
  • 230
  • You can write (or use) a hook that checks credentials (environment variables) and reject unwanted pushes. You can also limit things per-ref this way (E.g. allow pushes to "devel", but only certain users to "master") – Vi. Dec 10 '12 at 01:00
  • @Vi.: I know, that is what I do in my _"fallback"_ solution... but my fallback solution requires `valid-user`, so it is not really anonymous read (fetch). – Jakub Narębski Dec 10 '12 at 08:58
  • @JakubNarębski oh... my solution also requires `valid-user`, as currently configured. You could set `REMOTE_USER` to a dummy value in your anonymous access section though. Since `@all` would be set inthe gitolite config, it wouldn't matter. – VonC Dec 10 '12 at 09:00
  • 1
    Why not try making the LocationMatch cover _also_ what you see is requested? For example with `LocationMatch "^/git/.*git-receive-pack$"` (without the last slash). It has all the looks of a simple bug (missing update?) in the documentation. – Michał Politowski Dec 10 '12 at 21:44
  • The suggested change will (obviously?) not work as is, but [this discussion](http://thread.gmane.org/gmane.comp.version-control.git/204286) confirms the problem and provides likely working solutions. – Michał Politowski Dec 10 '12 at 22:05
  • @MichałPolitowski: `LocationMatch` does matching only on the path_info part of URL and does not take into account the query part, which is important here. – Jakub Narębski Dec 11 '12 at 10:49
  • @JakubNarębski: yes, I know it now (from the linked thread). There are other configuration changes suggested there, that seem to work for the posters. – Michał Politowski Dec 11 '12 at 11:09

2 Answers2

1

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.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
1

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

[http]
    receivepack = true
Jakub Narębski
  • 309,089
  • 65
  • 217
  • 230
arch
  • 11
  • 1