README.md (view raw)
1<h1 align="center">legit</h1>
2
3<p align="center">
4 <strong>A git web frontend written in Go.</strong>
5 <br>
6 Pronounced however you like; I prefer channeling my inner beret-wearing
7 Frenchman, and saying <em>"Oui, il est le git!"</em>
8</p>
9
10
11
12
13---
14
15## What is legit?
16
17`legit` is a self-hosted git repository browser for the web. Point it at a
18directory full of repos and it'll give you a clean, modern web interface for
19browsing files, viewing commits, exploring branches and tags, and cloning over
20HTTPS.
21
22It's not CGI. It's not Gitea. It's just a single binary that serves your repos.
23
24## Quick start
25
26```bash
27# Build
28go build -o legit
29
30# Run
31./legit --config ./config.yaml
32```
33
34You'll need a `config.yaml` (see [Configuration](#configuration)) and at least
35one bare git repo in your `scanPath`.
36
37## Features
38
39| | |
40|---|--------------------|
41| 🖥️ | Browse repos, files, trees, and commits |
42| 🌲 | File tree view with mode and size |
43| 📜 | Commit log with full diff output |
44| 🏷️ | Tag and branch listing |
45| 📦 | Archive downloads (tar.gz) |
46| 🎨 | Syntax highlighting (chroma) |
47| 🪨 | Markdown readme rendering |
48| 🔗 | Cloning over HTTPS (smart HTTP protocol) |
49| 📄 | Templated HTML (fully customisable) |
50| 🌙 | Dark mode (CSS media query) |
51
52## How do I configure legit?
53
54Configuration is via `config.yaml`. By default it looks in the current
55directory; use `--config <path>` to point elsewhere.
56
57```yaml
58repo:
59 scanPath: /var/www/git
60 readme:
61 - README.md
62 - README
63 mainBranch:
64 - master
65 - main
66 ignore:
67 - foo
68 unlisted:
69 - private-repo
70dirs:
71 templates: ./templates
72 static: ./static
73meta:
74 title: git good
75 description: come get your free software
76 syntaxHighlight: monokailight
77server:
78 name: git.example.com
79 host: 127.0.0.1
80 port: 5555
81```
82
83| Field | Description |
84|-------|-------------|
85| `repo.scanPath` | Directory containing repos (flat — subdirectories are not traversed) |
86| `repo.readme` | Readme filenames to look for (first match wins) |
87| `repo.mainBranch` | Branch names to try as default branch |
88| `repo.ignore` | Repos to exclude entirely (returns 404) |
89| `repo.unlisted` | Repos to hide from the index (still accessible by URL) |
90| `dirs.templates` | Path to custom Go html/template files |
91| `dirs.static` | Path to custom static assets (CSS, images) |
92| `meta.syntaxHighlight` | [Chroma style](https://swapoff.org/chroma/playground/) for syntax highlighting; empty = no highlighting |
93| `server.name` | Used for `go-import` meta tags and clone URLs |
94
95## What about cloning?
96
97Cloning works over HTTPS via git's smart HTTP protocol.
98
99```
100git clone https://git.example.com/my-repo
101```
102
103**Things to know:**
104- Cloning only works with **bare repos** (a limitation of git itself — non-bare
105 repos still display fine in the web UI).
106- Pushing over HTTPS is deliberately **disabled**. Use SSH.
107- Run legit behind a TLS-terminating proxy (nginx, relayd, etc.).
108
109## How does one host it?
110
111```bash
112# Docker
113docker run -p 5555:5555 \
114 -v /var/www/git:/var/www/git \
115 ghcr.io/icyphox/legit:latest
116
117# systemd (see contrib/legit.service)
118systemctl enable --now legit
119```
120
121Pre-built Docker images are available at
122`ghcr.io/icyphox/legit:{master,latest,vX.Y.Z}`.
123
124## Building
125
126```bash
127go build -o legit
128```
129
130No external dependencies beyond the Go toolchain. A Nix flake is also available
131for reproducible builds (`nix build`).
132
133## How does it work?
134
135```
136HTTP request
137 ↓
138 ┌────────────┐
139 │ main.go │ Parse config, unveil(2) on OpenBSD
140 └────────────┘
141 ↓
142 ┌────────────┐
143 │ routes │ Route requests: web UI or git smart protocol
144 │ handler.go │
145 └────────────┘
146 ↓
147 ┌────────────┐
148 │ git/ │ Read repos via go-git, exec git-upload-pack
149 └────────────┘
150 ↓
151 ┌────────────┐
152 │ templates │ Render HTML via Go html/template
153 └────────────┘
154```
155
156The `/{name}` endpoint is a **multiplexer**: it detects git HTTP protocol
157requests (`info/refs?service=git-upload-pack`, `git-upload-pack` POST) and
158routes them to the git backend, or renders the web UI otherwise.
159
160## Licence
161
162Original code (c) Anirudh Oppiliappan — MIT.
163Modifications (c) Maxwell Jensen — [European Union Public Licence 1.2](https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12).
164
165See `license` and `NOTICE` for details.