[Update 9/16/2010]

After looking into this last night, I realized that my original question was really asking 2 separate things:

1) Is it possible to set the post-update hook for all remote repositories created by gitosis (i.e. not have to manually perform mv hooks/post-update.sample hooks/post-update for after creating a repository in gitosis). This is necessary for cloning via HTTP to work (dumb HTTP clients rely on the fact that git update-server-info is called from within the post-update hook).

2) Once the repository is accessible via HTTP, is it possible to turn access on and off using an option in gitosis.conf (something similar to daemon = no or gitweb = yes)

--- Solution to question 1 ---

It turns out that Git uses templates to create new repositories with the git init command. By performing mv hooks/post-update.sample hooks/post-update within the template directory, all future calls to git init on my server will have the post-update hook configured correctly. (On OSX the template directory is /opt/local/share/git-core/templates/ for those that care)

The other requirement for this to work is turning on Apache rewrite rules so that the HTTP clone URL for the repository looks like http//git.example.com/repo.git

My rewrite rules in /etc/apache2/extra/httpd-vhosts.conf look like this:

# turning on mod rewrite
RewriteEngine on

# make the front page an internal rewrite to the gitweb script
RewriteRule ^/$ /cgi-bin/gitweb.cgi [L,PT]

# make access for "dumb clients" work
RewriteRule ^/(.*\.git/(?!/?(HEAD|info|objects|refs)).*)?$ /cgi-bin/gitweb.cgi%{REQUEST_URI} [L,PT]

--- Still looking for a solution to question 2...HELP! :) ---

Now that HTTP cloning works for all my repositories, I'm wondering if there is a way to manage HTTP access control using gitosis. Setting daemon = no and gitweb = no turns off git-daemon and gitweb access for the repository, but since the Apache rewrite rules are still on, the repo is still clone-able at http://git.example.com/repo.git. Any ideas on how to use gitosis to manage this?

[The question I originally posted]

Is it possible to manage http access to git repositories using gitosis? For example, in gitosis.conf I can manage access for gitweb and git-demon using:

# Allow gitweb to show this repository.
gitweb = yes

# Allow git-daemon to publish this repository.
daemon = no

I'm currently able to clone my repository by issuing the following command:

$ git clone git://git.example.com/repo.git

However, when I issue the following command:

$ git clone http://git.example.com/repo.git

I get the following error message:

fatal: http://git.example.com/repo.git/info/refs not found: did you run git update-server-info on the server?

However, if I log into my server and run the following from within repo.git:

# From http://progit.org/book/ch4-5.html
$ cd project.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update
$ git update-server-info

then cloning via http works fine.

Is there any way to manage http access to the repository from within gitosis?

  • Please provide more informations: apache.conf/your git config part in apache, your gitweb.conf... – Andreas Rehm Sep 15 '10 at 22:46

Gitosis uses gitweb for http publishing of repositories.

You need to have gitweb running.

Please ensure that gitweb is installed. Your gitweb.conf should look like:

# Location of the git binary
$GIT = "/usr/bin/git";

# Project root for gitweb
$projectroot = "/srv/git/repositories";

$stylesheet = "/gitweb.css";
$logo = "/git-logo.png";
$favicon = "/git-favicon.png";

# Site name
$site_name = "My site";

# URL formatting
#$my_uri = "http://git.somewhere.net/";
#$home_link = $my_uri;

# Base URL for project trees
@git_base_url_list = ("ssh://git\@somewhere.net");

# Length of the project description column in the webpage.
$projects_list_description_width = 50;

# Which repos are allowed to export
$export_ok = "git-daemon-export-ok";

# Enable PATH_INFO so the server can produce URLs of the
# form: http://git.hokietux.net/project.git/xxx/xxx
$feature{'pathinfo'}{'default'} = [1];

# Enable blame, pickaxe search, snapshop, search, and grep
$feature{'blame'}{'default'} = [1];
$feature{'blame'}{'override'} = [1];

$feature{'pickaxe'}{'default'} = [1];
$feature{'pickaxe'}{'override'} = [1];

$feature{'snapshot'}{'default'} = [1];
$feature{'snapshot'}{'override'} = [1];

$feature{'search'}{'default'} = [1];

$feature{'grep'}{'default'} = [1];
$feature{'grep'}{'override'} = [1];

Example gitweb config in apache:

Alias /gitweb/gitweb.css /usr/share/gitweb/gitweb.css
Alias /gitweb/git-logo.png /usr/share/gitweb/git-logo.png
Alias /gitweb/git-favicon.png /usr/share/gitweb/git-favicon.png
ScriptAlias /gitweb /usr/lib/cgi-bin/gitweb.cgi
<Directory /usr/share/gitweb>
  Options FollowSymLinks +ExecCGI
  AddHandler cgi-script .cgi
<Location /gitweb>
    Order allow,deny
    Allow from all
    #AuthType Basic
    #AuthName "GITOLITE"
    #AuthUserFile /etc/apache2/gitweb.htpasswd
    #Require valid-user
# Securing with users example
<Location /gitweb/SomethingToHide.git>
        Require user myusername

I've switched to gitolite because...

  • it is easier to use
  • it has more options (security, grouping etc.)
  • My apache config is essentially the same (i'm running this on OSX so some paths are different). The question I'm asking is regarding cloning of the repositories over HTTP (not just viewing them in gitweb). I don't want to have to manually perform the post-update steps I mentioned in my question above. Since gitosis automatically manages read access for git-daemon and gitweb viewing, I'm wondering if there is a way for it to manage HTTP cloning access in a similar fashion. Am I missing something obvious? Is this possible using gitolite? – cdwilson Sep 16 '10 at 5:11
  • post-update is a server side hook - so it will not run on the server side when you clone (git push would run it). – Andreas Rehm Sep 16 '10 at 13:50
  • I updated my question after looking into this last night, should be more clear what I'm asking – cdwilson Sep 16 '10 at 17:13

The problem is that you can't limit access to cloning from http:// because Apache handles those requests directly. I've developed a solution using git hooks and file permissions.

I have a Redmine/Gitosis/Gitweb server set up in a shared hosting environment in which the Apache user is not the gitosis user. By default, Apache does not have access to my repositories, because gitosis creates them with 750 permissions. I have gitosis successfully populating its projects.list for gitweb at /home/xdgit/gitosis/projects.list, which contains the names of all repositories which should be considered publicly accessible. I have modified my gitosis-admin.git/hooks/post-update hook to contain the following:

set -e
gitosis-run-hook post-update

# Find repo root from ENV or current dir
GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
if [ -z "$GIT_DIR" ]; then
    echo >&2 "fatal: post-receive: GIT_DIR not set"
    exit 1

# Process permissions for each repo
for f in $GIT_DIR/../*.git
    # Look for the repo name in projects.list
    if grep -q `basename $f` /home/xdgit/gitosis/projects.list
        then chmod o+rx $f
        else chmod o-rx $f

Now whenever I push anything to gitosis-admin.git (such as a change to the gitosis.conf to allow public access for a repository) the post-update hook will automatically change the repository's permissions to allow or deny public access, depending on whether the repo's name appears in projects.list. Since dummy clients require the actual repositories to be accessible by Apache directly, this permission-based access control is the ideal solution - not even Apache can access repositories which are not public.

I also developed a mod_rewrite/mod_setenvif solution that detected the presence of the git-daemon-export-ok file in the repository, allowing access if appropriate. It worked, but extra precautions would be needed to explicitly disallow access to non-public repos if they are readable by Apache (which they must be). It turned out to be a huge headache and in my case (since file permissions would have to be changed anyway) it was extreme overkill. Hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.