cgit and gitolite

gitolite - cgit integration


On our server we are using gitolite as the git repository server. Now I wanted to add a web based repository browser like gitweb for our public repositories. The repository browser of my choice was cgit.
cgit is a simple caching git repository browser written in C, which makes it super fast.
gitolite has the option to export repositories to gitweb by simply giving the special user gitweb read access. gitolite then creates a projects.list file that gitweb can use to identify public repositories. Luckily cgit also comes with an option to supply a projects.list file. With the configuration options


project-list=/path/to/projects.list
scan-path=/path/to/repository/directory


cgit searches the scan-path directory for repositories but only include the repositories that are listed in the projects-list file.
This two options are enough to list all public repositories on the cgit page.

Because on our server I might not be the only person that wants to publish his git repositories with cgit and I don’t want other people’s repositories to be listed on my cgit page, the simple project-list option does not work for me.

With the right apache configuration it is possible to provide a different cgit configuration file for different directories, but there is still only one projects.list file because all users share the same gitolite installation.
To overcome this problem I wrote a little patch for cgit that let you add a project-list-filter option to your cgit configuration:

project-list-filter=regular-expression

With this option only the repositories that match the given regular expression are included on the cgit page.
You get the patch here.

Adding repository configuration


With the configuration described above it is now possible to list only your own public repositories on your cgit page, but it is not yet possible to apply custom cgit repository based configuration to each repository (e.g. the clone-url option, etc.).
When configured, cgit searches in each repository’s directory for a cgitrc file that may contain repository specific configuration options.
Now one could simply add such a cgitrc file to each repository that needs extra configuration, but to do that you need shell access to the server and write permission to the repository’s base directory which is under gitolite’s control.
A better way to do that would be to add the repository specific configuration to the gitolite configuration file and then let gitolite create the cgitrc file for you.

Luckily gitlote allows you to set repository options using the config keyword. Because all custom config keys are disabled by default (for security reasons), you have to enable it by adding the line


$GL_GITCONFIG_KEYS = "cgit\..* ";


to your .gitolite.rc file. Now you can add custom cgit configuration options to your gitolite configuration file.
Here is a sample:

repo stefan/cgit-project-list-filter

RW+ = stefan

R = gitweb daemon

config cgit.name = "cgit project-list-filter“

config cgit.desc = "Branch of cgit with a project-list-filter option.“

config cgit.owner = "Stefan Reinhold“

config cgit.clone-url = „git://sreinhold.com/stefan/cgit-project-list-filter.git“

config cgit.section = „Software“



As you can see, the lines with config cgit correspond to a repository specific cgit option.
When pushing the changed configuration file to the server, gitolite adds these options to the config file inside the repository’s directory.
Because the config file and the cgitrc file have different formats, one need to extract the cgit relevant options from the config file and write them to the cgitrc file.
By using gitolite’s post-update.secondary hook this can be automated.
The post-update.secondary hook is executed every time a new gitolite configuration is pushed to the server, so I wrote a little shell script to do the necessary work:


#!/bin/bash



for repo in `find ${GL_REPO_BASE_ABS} | grep '.git$'`

do

rel_repo_name=`echo ${repo} | sed 's|.*/\([^/]*\)$|\1|'`



if [ "${rel_repo_name}" = "gitolite-admin.git" ]

then

continue

fi



if [ ! -f ${repo}/config ]

then

continue

fi



cfg_file=${repo}/config



secStart=0



rm -f ${repo}/cgitrc



while read line

do



if [ ! -n "${line}" ]

then

continue

fi



secMatch=`echo ${line} | grep '\[cgit\]'`



if [ -n "${secMatch}" ]

then

secStart=1

continue

fi



if [ ${secStart} -eq 1 ]

then

key=`echo ${line} | sed 's/[ \t]*\([^ \t=]*\)=.*/\1/'`

value=`echo ${line} | sed 's/.*=[ \t]*\(.*\)$/\1/'`



echo "${key}=${value}" >> ${repo}/cgitrc

fi

done < ${cfg_file}

done


When this script is copied to gitolite-admin.git/hooks/post-update.secondary it is added to every newly created repository automatically.
Now, when updating a repository’s configuration, a cgitrc is automatically created in the repository’s directory.

The post-update.secondary script above might be a little quick and dirty, but it works for the moment.

If you know a cleaner way to do this, let me know!


blog comments powered by Disqus