# Pygitweb

Gitweb reimplementation using **Python**, **FastAPI**, and **Pygit2**, ported from `git/gitweb/gitweb.perl`.

## Setup

Pygitweb is part of the repo-root **uv** workspace (with `distgit`). From the repository root:

```bash
uv sync --package pygitweb
```

Or install everything in the workspace (all members + dev tools):

```bash
uv sync --all-packages --group dev
```

## Run

From the repository root (after `uv sync`), with the workspace `.venv` activated:

```bash
uvicorn pygitweb.main:app --reload --host 0.0.0.0 --port 8000
```

Or:

```bash
python -m pygitweb.main
```

## Config

Set environment variables (or use a Python config file via `GITWEB_CONFIG`):

- `GITWEB_PROJECTROOT` — absolute path to directory containing git repositories (default: `/pub/scm`)
- `GITWEB_LIST` — same path or path to a project-list file
- `GITWEB_EXPORT_OK` — filename that must exist to allow export (e.g. `git-daemon-export-ok`); empty = no check
- `GITWEB_SITENAME` — site name in titles

## Routes

Load the `/docs` page for a detailed view of routes (below the readme) if in debug mode. 

**No-project routes**

- `GET /`: project list
- `GET /index`: plain text project index (path, owner)
- `GET /opml`: OPML feed list
- `GET /project/{name}`: Project dispatch (See actions table)

**Actions**

| Action | Query parameters | URL | Description |
|--------|------------------|-----|-------------|
| summary | *(default)* or `a` | `GET /project/{project}` | Project summary (description, owner, HEAD, tree link). |
| tree | `h`, `f` | `GET /project/{project}?a=tree&h=...&f=...` | Directory listing (tree). |
| blob | `h`, `f` | `GET /project/{project}?a=blob&h=...&f=...` | File view (HTML). |
| blob_plain | `h`, `f` | `GET /project/{project}?a=blob_plain&h=...&f=...` | Raw file download. |
| log | `h` | `GET /project/{project}?a=log&h=...` | Commit log. |
| shortlog | `h` | `GET /project/{project}?a=shortlog&h=...` | Shortlog. |
| history | `h`, `f` | `GET /project/{project}?a=history&h=...&f=...` | History of a file or path. |
| heads | — | `GET /project/{project}?a=heads` | List branch heads. |
| tags | — | `GET /project/{project}?a=tags` | List all tags. |
| tag | `h` | `GET /project/{project}?a=tag&h=...` | Single tag view (tag ref or hash). |
| commit | — | `GET /project/{project}?a=commit` | Commit information. |
| commitdiff | — | `GET /project/{project}?a=commitdiff` | Commit diff (unified diff rendered with [diff2html](https://github.com/rtfpessoa/diff2html)). |
| patch | `h` | `GET /project/{project}?a=patch&h=...` | Single-commit patch (plain text). |
| patches | `h`, `hb` | `GET /project/{project}?a=patches&h=...&hb=...` | Multi-commit patches for range `hb..h` (plain text). |
| blobdiff | `h`, `hb`, `f`, `fp` | `GET /project/{project}?a=blobdiff&h=...&hb=...&f=...&fp=...` | Blob diff (two versions of a file) rendered with diff2html. |
| blobpatch | `h`, `hb`, `f`, `fp` | `GET /project/{project}?a=blobpatch&h=...&hb=...&f=...&fp=...` | Blob diff as plain unified diff. |
| remotes | — | `GET /project/{project}?a=remotes` | List repo remotes. |
| object | `h` | `GET /project/{project}?a=object&h=...` | Show object by type (commit, tree, tag, or blob). |
| blame | — | | TODO |
| blame_incremental | — | | TODO |
| blame_data | — | | TODO |
| rss | — | | TODO |
| atom | — | | TODO |
| search | — | | TODO |
| search_help | — | | TODO |

## Query parameter short names (CGI mapping)

- `p` → project
- `a` → action
- `f` → file_name
- `fp` → file_parent
- `h` → hash
- `hp` → hash_parent
- `hb` → hash_base
- `hpb` → hash_parent_base
- `pg` → page
- `o` → order
- `s` → searchtext
- `st` → searchtype
- `sf` → snapshot_format
- `opt` → extra_options
- `sr` → search_use_regexp
- `by_tag` → ctag
- `ds` → diff_style
- `pf` → project_filter