A fast web frontend for git repositories, implemented in Zig. This is implemented as a lightweight CGI application for browsing git repositories through a web interface.
- 📊 Repository summary with recent commits, branches, and tags
- 📜 Commit log with pagination
- 🌳 Tree/file browser with syntax highlighting
- 🔍 Commit diff viewer
- 📦 Snapshot downloads (tar.gz, zip)
- 🏷️ Tag and branch browsing
- ⚡ Fast and lightweight CGI application
- 🔧 Written in Zig for performance and safety
- Zig 0.15.1 or later
- libgit2
- zlib
brew install libgit2sudo apt-get install libgit2-dev zlib1g-devgit clone https://github.com/mrjbq7/zig-gitweb.git
cd zig-gitweb
zig buildThis will create gitweb.cgi in zig-out/bin/.
Configure your web server to execute gitweb.cgi as a CGI script. The
application reads repository locations from a configuration file.
ScriptAlias /git "/path/to/gitweb.cgi"
<Directory "/path/to">
Options ExecCGI
AddHandler cgi-script .cgi
Require all granted
</Directory>server {
listen 80;
server_name zig-gitweb;
root /zig-gitweb;
# Index redirects to cgi
location = / { rewrite ^ /cgi-bin/gitweb.cgi last; }
# Try and load static files
location / { try_files $uri $uri/ @gitweb; }
# Otherwise forward to the cgi
location @gitweb { rewrite ^ /cgi-bin/gitweb.cgi?url=$uri&$args last; }
# Allow only *.cgi to execute
location ~ ^/cgi-bin/(.+\.cgi)$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/cgi-bin/$1;
fastcgi_param SCRIPT_NAME /cgi-bin/$1;
fastcgi_param PATH_INFO "";
fastcgi_pass unix:/run/fcgiwrap.socket;
}
# Everything else under /cgi-bin is blocked (prefix location has lower prio than regex)
location /cgi-bin/ { return 404; }
}You can use Factor to serve this also:
TUPLE: zig-gitweb < file-responder ;
: <zig-gitweb> ( root -- responder )
zig-gitweb new
swap >>root
[ (serve-static) ] >>hook
H{ } clone >>special
enable-cgi ;
M: zig-gitweb call-responder*
dup file-responder set
over [ f ] [ "/" join serving-path file-exists? ] if-empty [
url get
rot "/" join "url" set-query-param
"gitweb.cgi" >>path drop { "gitweb.cgi" } swap
] unless call-next-method ;# Create a test repository
mkdir -p /tmp/git
git init --bare /tmp/git/myproject.git
# Create a minimal configuration
echo "scan-path=/tmp/git" > /tmp/gitweb.conf
# Test the CGI directly
GITWEB_CONFIG=/tmp/gitweb.conf QUERY_STRING="r=myproject" REQUEST_METHOD=GET ./zig-out/bin/gitweb.cgir- Repository name (e.g.,?r=myproject)cmd- Command/page to display:summary- Repository overview (default)log- Commit historytree- File browsercommit- Commit detailsdiff- Commit differencesrefs- Branches and tagssnapshot- Download archive
id- Commit/tree/tag IDpath- File or directory pathh- Branch/tag reference
/git?r=myproject- Repository summary/git?r=myproject&cmd=log- Commit log/git?r=myproject&cmd=tree- Browse files/git?r=myproject&cmd=commit&id=abc123- View specific commit/git?r=myproject&cmd=snapshot&h=main&fmt=tar.gz- Download tarball
zig-gitweb uses a configuration file (gitweb.conf) to specify repository locations and settings. The configuration file is read from:
- The path specified in the
GITWEB_CONFIGenvironment variable /etc/gitweb.conf(default location)
See gitweb.conf.example for a complete example configuration.
There are several ways to configure repositories:
# In gitweb.conf:
scan-path=/srv/gitAll bare git repositories under /srv/git will be automatically discovered.
# In gitweb.conf:
repo.url=myproject
repo.path=/path/to/myproject.git
repo.desc=My Project Description
repo.owner=John Doe# In gitweb.conf:
project-list=/etc/gitweb-projects.txtWhere the project list file contains repository paths, one per line.
# Create a directory for git repositories
sudo mkdir -p /srv/git
sudo chown $USER:$USER /srv/git
# Create a bare repository
git init --bare /srv/git/myproject.git
# Push an existing project
cd /path/to/existing/project
git remote add web /srv/git/myproject.git
git push web main
# Configure gitweb.conf
sudo tee /etc/gitweb.conf <<EOF
scan-path=/srv/git
root-title=My Git Repositories
root-desc=Source code repository browser
EOFStatic files are located in the static/ directory:
gitweb.css- Stylesheet customizationgitweb.js- JavaScript enhancements
zig build # Build the project
zig build test # Run tests
zig build --release=fast # Build optimized versionzig-gitweb/
├── src/
│ ├── main.zig # CGI entry point
│ ├── gitweb.zig # Core types and configuration
│ ├── git.zig # libgit2 wrapper
│ ├── cmd.zig # Command dispatcher
│ ├── html.zig # HTML generation utilities
│ └── ui/ # UI handlers for each command
│ ├── log.zig
│ ├── commit.zig
│ ├── tree.zig
│ └── ...
├── static/ # CSS, JS, and other static files
├── build.zig # Build configuration
└── build.zig.zon # Package manifest
Contributions are welcome! Please feel free to submit issues and pull requests.
This project is inspired by cgit, but freshly implemented in Zig. It currently uses libgit2 for git repository access, and zlib for compression.