README.md
browsing at commit = 83d9be6f3ed9d9cb365012fe26dc2b2cd733ae64
# Multi Git Frontend
A lightweight read-only web frontend for browsing multiple git repositories,
built with [CppCMS](http://cppcms.com/), libgit2, C++17 and CMake.
It scans a directory for git repositories and serves each one as a sub-path,
showing the file tree, individual files (with syntax highlighting), raw
content, blame, commit log and arbitrary objects. Only the **default branch**
and **committed content** are shown — the working directory is never read.
## Routes
| URL | Shows |
|-----|-------|
| `/` | Front page |
| `/repos` | List of repositories |
| `/repos/<name>` | Repository home (rendered README) |
| `/repos/<name>/tree/` | File tree at the root |
| `/repos/<name>/tree/<path>` | Sub-directory listing, or a file with highlighting |
| `/repos/<name>/raw/<path>` | Raw file content |
| `/repos/<name>/blame/<path>` | Per-line blame |
| `/repos/<name>/log/` | Commit log |
| `/repos/<name>/commit/<hash>` | Commit details: message, changed files and the diff |
| `/repos/<name>/commit/<hash>.patch` | Raw unified patch (`text/plain`) |
| `/repos/<name>/tags/` | List of tags |
| `/repos/<name>/tags/<tag>` | Tag details (target commit, message) |
| `/repos/<name>/tags/<tag>.tar.gz` | Download the tag as a gzipped tarball, submodules included (built on first access, then cached) |
| `/repos/<name>/object/<hash>` | Inspect a blob, tree, commit or tag |
Every page accepts `?id=<hash>` to view at a specific commit instead of the
default branch HEAD.
## Configuration
`config.json` controls the HTTP service and the repository root:
- `service.port` — listening port (default `11000`).
- `git.root` — directory to scan for repositories. Overridden by the
`GIT_ROOT` environment variable; falls back to `$HOME/git`.
- `git.static_root` — directory containing the bundled CSS/JS assets.
- `git.cache_root` — directory where generated tag archives are cached,
created on demand. Overridden by the `GIT_CACHE_ROOT` environment variable;
when neither is set it defaults to `$XDG_CACHE_HOME/sago_web_git` (or
`$HOME/.cache/sago_web_git`, falling back to `/tmp/sago_web_git`).
- `git.github_enterprise_hosts` — comma- or space-separated hostnames to treat
as GitHub (in addition to `github.com`) when showing clone instructions on a
repository's page, e.g. `github.mycompany.com git.example.org`. Overridden by
the `GITHUB_ENTERPRISE_HOSTS` environment variable. `github.com` is always
recognised, so leave this empty unless you run GitHub Enterprise.
- `SHOW_EMAILS` (env) — author/committer email addresses are hidden by default;
set `SHOW_EMAILS=1` to show them.
Syntax highlighting (highlight.js) and markdown (marked.js) are rendered
client-side from vendored assets in `static/`, so the server needs no extra
runtime dependencies. Markdown files (`.md`, `.markdown`) and the repo README
are rendered in the normal file view; `raw` and `blame` always show the source.
## Build from source
Requires CppCMS (with `cppcms_tmpl_cc`), libgit2, zlib, CMake and a C++17 compiler.
```sh
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
./build/sago_web_git -c config.json
```
Then open <http://localhost:11000/>.
## Docker
The image builds CppCMS from source (it is not packaged in Ubuntu) and bundles
everything. Mount a directory of repositories at `/srv/git`:
```sh
docker build -t sago007/sago_web_git .
docker run --rm -p 11000:11000 -v "$HOME/git:/srv/git:ro" sago007/sago_web_git
```
To reveal email addresses, pass the environment variable:
```sh
docker run --rm -p 11000:11000 -e SHOW_EMAILS=1 -v "$HOME/git:/srv/git:ro" sago007/sago_web_git
```
## Layout
```
src/
main.cpp Service bootstrap and repo-root resolution
application.* CppCMS application: URL routing and request handlers
git_repo.* libgit2 wrapper (commits, trees, blobs, blame, log, objects)
repo_scanner.* Discovers repositories under the root
content.h Typed data passed to the templates
util.* Small helpers (oid validation, sizes, time, paths)
templates/skin.tmpl CppCMS template skin (compiled to views.cpp at build time)
static/ style.css, app.js, vendored highlight.js + marked.js
```