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.