Friday, December 17, 2010

Sharing several Git repositories among authorized users through Apache on Windows

(Yes, on Windows).

Installing Apache and Git should not be a problem, try this article if you think a few screenshots may come handly.

After installing Apache, uncomment the following lines in conf/httpd.conf if you are planning to enable SSL:


LoadModule ssl_module modules/mod_ssl.so
Include conf/extra/httpd-ssl.conf


Certificates creation is another story, but note that self-signed certificates will be rejected by Git, so if you are planning to enable SSL, prepare to deal with commercial CAs.

Git communicates via HTTP using libexec/git-core/git-http-backend.exe. It will complain about libiconv2.dll if Git's bin/ is not in the PATH. Copy this .DLL from bin/ to libexec/git-core/ or modify the PATH.

Now we need to tell Apache to treat some URLs as Git's CGI scripts (so they will be processed by Git modules, not Apache). There are several ways to do this, but first it worth meditating for a few minutes on a official man.

Down from meditation to dirty Windows world, here is the absolute minimal alias you need to introduce in conf/httpd.conf:


ScriptAlias /git/ "C:/Git/libexec/git-core/git-http-backend.exe/"


Notice the / at the end. Try to omit it and prepare for several nights full of reading access.log, error.log and other sources of internal wisdom.

Feel free to play with ScriptAliasMatch, it may work sometimes too. Also note, that all that regexp zoo is to get gitweb.cgi separated from Git requests, and gitweb.cgi will most likely refuse to live under Windows.

Don't forget to tell Apache it may execute scripts there:

<Directory "C:/Git/libexec/git-core">
AllowOverride None
Options None
Order allow,deny
Allow from all
</Directory>


(How this intended to be in any sane way connected with execution is beyond the scope of this Universe).

When alias is ready, we need to tell Git where our repositories are located:


SetEnv GIT_PROJECT_ROOT "C:/repo/"
SetEnv GIT_HTTP_EXPORT_ALL



(Last one actually tells Git to expose all repositories, not only marked explicitly for such activity).

Finally, we are getting to the most exiting part: authorization. Since Git has no authorization, we have to cooperate with Apache. It has plenty (and even much more) methods for this, but we stick to password files based authorization for the sake of simplicity.

Assume we have two repositories, located in C:/repo/foo.git and C:/repo/boo.git folders. Each repository should be share between different sets of users.

Below are the magic lines which will organize all for you:


<Location /git/foo.git/>
AuthType Basic
AuthName "Foo repository"
AuthBasicProvider file
AuthUserFile C:\Apache\conf\pw_foo
Require valid-user
</Location>


<Location /git/boo.git/>
AuthType Basic
AuthName "Boo repository"
AuthBasicProvider file
AuthUserFile C:\Apache\conf\pw_boo
Require valid-user
</Location>



The rest should be oblivious now:



> htpasswd -c -b ../conf/pw_foo FOOUSER_1 PASS_1
> htpasswd -b ../conf/pw_foo FOOUSER_2 PASS_2
...
> htpasswd -c -b ../conf/pw_boo BOOUSER_1 PASS_1
> htpasswd -b ../conf/pw_boo BOOUSER_2 PASS_2



And the final test:


> git clone http://FOOUSER_1@myserver.com/git/foo.git .


Enough of administration, time to write some code to fill those repositories with.

No comments:

Post a Comment