mrjbq7/zig-gitweb
Git repository web interface
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.
brew install libgit2
sudo apt-get install libgit2-dev zlib1g-dev
git clone https://github.com/mrjbq7/zig-gitweb.git
cd zig-gitweb
zig build
This 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.cgi
r
- 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 archiveid
- 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 tarballzig-gitweb uses a configuration file (gitweb.conf) to specify repository locations and settings. The configuration file is read from:
GITWEB_CONFIG
environment 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/git
All 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.txt
Where 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
EOF
Static files are located in the static/
directory:
gitweb.css
- Stylesheet customizationgitweb.js
- JavaScript enhancementszig build # Build the project
zig build test # Run tests
zig build --release=fast # Build optimized version
zig-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.