After some years of working with (and fighting against) Subversion I decided to setup a Git repository for our company. Every developer should decide on their own what Version Control System he wants to use.

Jeremy Skinner wrote an excellent article about hosting a Git repository on Windows which was really helpful. Nevertheless I had to do some customizing.

Using ScriptAliasMatch

This drove me crazy: ScriptAliasMatch seemed to work, but the parameter (the repository argument) was not passed to git-http-backend.exe. Instead of this, I saw that Apache/httpd.exe tried to open c:/program files/git/libexec/git-core/git-http-backend.exe/repositoryname.

Solution: You must enable mod_cgi, otherwise the path argument “…exe/$1” can not be resolved.

Using Apache 2.4 TLS

The git client failed to connect with the virtual host which was secured with SSLv3. I received the error message “error:140920DF:SSL routines:SSL3_GET_SERVER_HELLO:parse tlsext“. Anders Brownworth had this problem too, but I fixed it by disabling SSLv3 – which was at least acceptable in our environment. Use this line in your ssl.conf:

SSLProtocol +SSLv2 +SSLv3

Using a network share as repository

Our Subversion and Git repositories are stored on a network share, primarily for backup reasons. The path of the network share must be entered as “\\srv\share” – the doublequotes are important!
We are using the direct network share path and not a network drive, because after a restart of the machine containing the network share, the network drive will be unavailable. Windows marks it as offline and you can not use it longer until you restart the machine or reconnect the network drive manually. Accessing the network share via full UNC path will work as soon as the share is available again.

Running Apache on Windows 7 / 10 / Windows Server 2016 / 2019

I tested the Git environment on Windows 7 (German) machine, and ran into the problem that the git-http-backend.exe could not be found. My fault was that I used “c:/Programme/Git/libexec/git-core/git-http-backend.exe” and notc:/Program Files“. Apache seems not be able to access the junction “c:/Programme“.

If you are running a x64 operating system, you must use c:/Program Files (x86)/Git/libexec/git-core/git-http-backend.exe.

Error “Client denied by server configuration”

Receiving the error “Client denied by server configuration” while setting up Git means in most cases that the access to the Git directory is denied. Take a look at the Apache Wiki and change your Order directives.

Running Apache under a special service account

If you want to run Apache under a special network service account (e.g. webserver@yourdomain.local), you have to keep this in mind.
The service account must have full access to your network share (\srvshare) and the repositories inside of it. Otherwise you will receive errors inside your Apache log like “error: insufficient permission for adding an object to repository database ./objects“.

Using Active Directory authentication/authorization for your Git repository

Authentication and authorization against the Active Directory/LDAP can be easily done with mod_authnz_ldap (mod_ldap prior to Apache 2.2.x):


	SetEnv GIT_PROJECT_ROOT "\\srv\git_repos"
	SetEnv GIT_HTTP_EXPORT_ALL
	ScriptAliasMatch "(?x)^/git/(.*/(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"

	AuthType Basic
	AuthName "LDAP"
	AuthBasicProvider "ldap"
	AuthzLDAPAuthoritative Off
	require valid-user
	require ldap-group CN=security group,OU=your security group container,DC=domain,DC=local

All bare Git repositories inside of \srvgit_repos are available to http://webserver/git/. Every repository access will be authenticated and authorized against the given ldap-group. Authenticated read-only access can be done with LimitExcept directives.
Please note, that the centryl Git repository on your share must have the “sharedRepository = true” option. The option http.receive-pack is not needed, because every access is already authenticated through mod_authnz_ldap.

A working example without Active Directory authentication

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

<Directory "C:/srv/document_root">
    Options Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

<Directory "c:/Program Files (x86)/git/libexec/git-core/">
    Order allow,deny
    Allow from all
</Directory>

SetEnv GIT_PROJECT_ROOT "C:/repos_git"
SetEnv GIT_HTTP_EXPORT_ALL

# Using x64 operating system
ScriptAliasMatch "(?x)^/git/(.*/(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"

I am asking you for a donation.

You liked the content or this article has helped and reduced the amount of time you have struggled with this issue? Please donate a few bucks so I can keep going with solving challenges.