Setting up gitwebEdit
Overview
Once the initial set-up is done, adding new projects to an existing Gitweb installation is very easy. Notes on the initial set-up appear below. To add an additional project, all that is required is:
cd path_to_repo
echo "Description of this repository" | sudo -u git tee description
echo "repository.git owner@example.com" | sudo -u git tee -a /pub/git/conf/gitweb-projects
Preparation
Prerequisites
Check that the required Perl modules are available:
# should run without errors (exit code 0):
perl -mCGI -mEncode -mFcntl -mFile::Find -mFile::Basename -e ""
echo $?
Note that as of Git 1.5.3.1 a newer version of the Encode module is required than that which ships with Red Hat Enterprise Linux 3 (see "Fixing gitweb breakage on Red Hat Enterprise Linux 3" for more information).
Repository set-up
Edit repository.git/description for each repository that you want to be managed by gitweb.
Filesystem set-up
Assuming your git user (the owner of the Git repositories) has its home directory at /pub/git/:
cd /pub/git
sudo -u git mkdir conf
sudo -u git mkdir logs
For security we’ll run the gitweb.cgi script using suEXEC; in order for it to work we must install the script under the Apache docroot. A symbolic link is created back to the git user’s home directory as well.
sudo -u git mkdir path_to_apache_doc_root/git.example.com
sudo ln -s path_to_apache_doc_root/git.example.com public_html
Apache set-up
A VirtualHost block similar to the following needs to be added to the Apache httpd.conf:
<VirtualHost *:80>
DocumentRoot "/pub/git/public_html"
ServerName git.example.com
SuexecUserGroup git git
<Directory "/pub/git/public_html">
Options Indexes FollowSymlinks ExecCGI
AllowOverride None
Order allow,deny
Allow from all
DirectoryIndex gitweb.cgi
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.* /gitweb.cgi/$0 [L,PT]
</Directory>
# for debugging rewrite rules
[/tags/RewriteLog #RewriteLog] /pub/git/logs/rewrite_log
[/tags/RewriteLogLevel #RewriteLogLevel] 9
ErrorLog /pub/git/logs/error_log
LogLevel warn
CustomLog /pub/git/logs/access_log "combined"
</VirtualHost>
These were the directives that I arrived at via trial and error. For some reason on my system the SetEnv directive did not work (perhaps due to an interaction with suEXEC?) and neither did the RewriteRule in the gitweb README file; this is why I temporarily added in the RewriteLog and RewriteLogLevel directives in order to troubleshoot (it turns out that the leading slash had to be removed).
Building gitweb
This make invocation worked on my local system:
# from top-level of Git source tree
make prefix=/usr/local \
GITWEB_PROJECTROOT=/pub/git/path_to_public_repos \
GITWEB_LIST=/pub/git/conf/gitweb-projects \
GITWEB_STRICT_EXPORT=1 \
GITWEB_CSS="/gitweb.css" \
GITWEB_LOGO="/git-logo.png" \
GITWEB_FAVICON="/git-favicon.png" \
GITWEB_CONFIG="/pub/git/conf/gitweb.conf" \
gitweb/gitweb.cgi
sudo -u git cp gitweb/gitweb.{cgi,css} \
gitweb/git-*.png \
/pub/git/public_html
Configuring gitweb
Although some configuration is passed in during the make it is still necessary to perform some additional configuration that will be used at runtime.
For each repository that will be visible in gitweb we add an entry to the gitweb-projects list indicating the owner:
echo "repository.git owner@example.com" | sudo -u git tee -a /pub/git/conf/gitweb-projects
We also prepare our gitweb.conf file:
sudo -u git tee /pub/git/conf/gitweb.conf <<\EOF
# turn off potentially CPU-intensive features
$feature{'search'}{'default'} = [undef];
$feature{'blame'}{'default'} = [undef];
$feature{'pickaxe'}{'default'} = [undef];
$feature{'grep'}{'default'} = [undef];
$feature{'snapshot'}{'default'} = [undef];
# nicer-looking URLs (requires Apache rewrite rules to be set up)
$feature{'pathinfo'}{'default'} = [1];
$my_uri = "http://git.example.com";
$home_link = "http://git.example.com/";
$site_name = "git.example.com";
EOF
Note that seeing as this is my first gitweb installation I want to trial things conservatively at first and so turn off some of the more CPU-intensive features. Also note that in order to turn on the nicer-looking URLs (the pathinfo feature) it is necessary to set up my_uri as well. These URLs work because of the RewriteRule in the httpd.conf. I also found that the pathinfo feature required me to explicitly set my $home_link, because otherwise the "projects" link didn’t point to the true root (ie. it pointed to URLs like http://git.example.com/repo.git instead of http://git.example.com/).
Troubleshooting
suEXEC problems
One of the problems I encountered when trying to set this up was that in the web browser I was getting an internal server error and this in the error_log:
Premature end of script headers: gitweb.cgi
But when running from the command line everything was working:
./gitweb.cgi
I temporarily set up Apache LogLevel to debug but no additional output was produced, so this lead me to check the suEXEC log (location may vary depending on your system; try locate suexec.log):
[2007-07-15 11:26:28]: uid: (647/git) gid: (650/650) cmd: gitweb.cgi
[2007-07-15 11:26:28]: command not in docroot (/pub/git/cgi-bin/gitweb.cgi)
This was what lead me to move the public HTML folder for the git user under Apache’s docroot, and then put a public_html symlink in the git user’s home directory.
MIME types
I also found that Gitweb was serving .sh files stored in repositories using a MIME type that led browsers to download them rather than displaying them. This was due to the following line in /etc/mime.types:
application/x-sh sh
This line causes these HTTP headers to be sent when trying to view an .sh file:
Transfer-Encoding: chunked
Content-Type: application/x-sh
Compare that to the headers sent trying to view an .rb file:
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Commenting out the line in /etc/mime.types causes these headers to be sent instead:
Transfer-Encoding: chunked
Content-Type: text/plain; charset=ISO-8859-1
And the browser displays the file rather than downloading it.