summaryrefslogtreecommitdiff
path: root/docs/handbook/cgit/configuration.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/handbook/cgit/configuration.md')
-rw-r--r--docs/handbook/cgit/configuration.md351
1 files changed, 351 insertions, 0 deletions
diff --git a/docs/handbook/cgit/configuration.md b/docs/handbook/cgit/configuration.md
new file mode 100644
index 0000000000..afc29fce07
--- /dev/null
+++ b/docs/handbook/cgit/configuration.md
@@ -0,0 +1,351 @@
+# cgit — Configuration Reference
+
+## Configuration File
+
+Default location: `/etc/cgitrc` (compiled in as `CGIT_CONFIG`). Override at
+runtime by setting the `$CGIT_CONFIG` environment variable.
+
+## File Format
+
+The configuration file uses a simple `name=value` format, parsed by
+`parse_configfile()` in `configfile.c`. Key rules:
+
+- Lines starting with `#` or `;` are comments
+- Leading whitespace on lines is skipped
+- No quoting mechanism — the value is everything after the `=` to end of line
+- Empty lines are ignored
+- Nesting depth for `include=` directives is limited to 8 levels
+
+```c
+int parse_configfile(const char *filename, configfile_value_fn fn)
+{
+ static int nesting;
+ /* ... */
+ if (nesting > 8)
+ return -1;
+ /* ... */
+ while (read_config_line(f, &name, &value))
+ fn(name.buf, value.buf);
+ /* ... */
+}
+```
+
+## Global Directives
+
+All global directives are processed by `config_cb()` in `cgit.c`. When a
+directive is encountered, the value is stored in the corresponding
+`ctx.cfg.*` field.
+
+### Site Identity
+
+| Directive | Default | Type | Description |
+|-----------|---------|------|-------------|
+| `root-title` | `"Git repository browser"` | string | HTML page title for the index page |
+| `root-desc` | `"a fast webinterface for the git dscm"` | string | Subtitle text on the index page |
+| `root-readme` | (none) | path | Path to a file rendered on the site about page |
+| `root-coc` | (none) | path | Path to Code of Conduct file |
+| `root-cla` | (none) | path | Path to Contributor License Agreement file |
+| `root-homepage` | (none) | URL | External homepage URL |
+| `root-homepage-title` | (none) | string | Title text for the homepage link |
+| `root-link` | (none) | string | `label\|url` pairs for navigation links (can repeat) |
+| `logo` | `"/cgit.png"` | URL | Path to the site logo image |
+| `logo-link` | (none) | URL | URL the logo links to |
+| `favicon` | `"/favicon.ico"` | URL | Path to the favicon |
+| `css` | (none) | URL | Stylesheet URL (can repeat for multiple stylesheets) |
+| `js` | (none) | URL | JavaScript URL (can repeat) |
+| `header` | (none) | path | File included at the top of every page |
+| `footer` | (none) | path | File included at the bottom of every page |
+| `head-include` | (none) | path | File included in the HTML `<head>` |
+| `robots` | `"index, nofollow"` | string | Content for `<meta name="robots">` |
+
+### URL Configuration
+
+| Directive | Default | Type | Description |
+|-----------|---------|------|-------------|
+| `virtual-root` | (none) | path | Base URL path when using URL rewriting (always ends with `/`) |
+| `script-name` | `CGIT_SCRIPT_NAME` | path | CGI script name (from `$SCRIPT_NAME` env var) |
+| `clone-prefix` | (none) | string | Prefix for clone URLs when auto-generating |
+| `clone-url` | (none) | string | Clone URL template (`$CGIT_REPO_URL` expanded) |
+
+When `virtual-root` is set, URLs use path-based routing:
+`/cgit/repo/log/path`. Without it, query-string routing is used:
+`?url=repo/log/path`.
+
+### Feature Flags
+
+| Directive | Default | Type | Description |
+|-----------|---------|------|-------------|
+| `enable-http-clone` | `1` | int | Allow HTTP clone operations (HEAD, info/refs, objects/) |
+| `enable-index-links` | `0` | int | Show log/tree/commit links on the repo index page |
+| `enable-index-owner` | `1` | int | Show the Owner column on the repo index page |
+| `enable-blame` | `0` | int | Enable blame view for all repos |
+| `enable-commit-graph` | `0` | int | Show ASCII commit graph in log view |
+| `enable-log-filecount` | `0` | int | Show changed-file count in log view |
+| `enable-log-linecount` | `0` | int | Show added/removed line counts in log |
+| `enable-remote-branches` | `0` | int | Display remote tracking branches |
+| `enable-subject-links` | `0` | int | Show parent commit subjects instead of hashes |
+| `enable-html-serving` | `0` | int | Serve HTML files as-is from plain view |
+| `enable-subtree` | `0` | int | Detect and display git-subtree directories |
+| `enable-tree-linenumbers` | `1` | int | Show line numbers in file/blob view |
+| `enable-git-config` | `0` | int | Read `gitweb.*` and `cgit.*` from repo's git config |
+| `enable-filter-overrides` | `0` | int | Allow repos to override global filters |
+| `enable-follow-links` | `0` | int | Show "follow" links in log view for renames |
+| `embedded` | `0` | int | Omit HTML boilerplate for embedding in another page |
+| `noheader` | `0` | int | Suppress the page header |
+| `noplainemail` | `0` | int | Hide email addresses in output |
+| `local-time` | `0` | int | Display times in local timezone instead of UTC |
+
+### Limits
+
+| Directive | Default | Type | Description |
+|-----------|---------|------|-------------|
+| `max-repo-count` | `50` | int | Repos per page on the index (≤0 → unlimited) |
+| `max-commit-count` | `50` | int | Commits per page in log view |
+| `max-message-length` | `80` | int | Truncate commit subject at this length |
+| `max-repodesc-length` | `80` | int | Truncate repo description at this length |
+| `max-blob-size` | `0` | int (KB) | Max blob size to display (0 = unlimited) |
+| `max-stats` | `0` | int | Stats period (0=disabled, 1=week, 2=month, 3=quarter, 4=year) |
+| `max-atom-items` | `10` | int | Number of entries in Atom feeds |
+| `max-subtree-commits` | `2000` | int | Max commits to scan for subtree trailers |
+| `renamelimit` | `-1` | int | Diff rename detection limit (-1 = Git default) |
+
+### Caching
+
+| Directive | Default | Type | Description |
+|-----------|---------|------|-------------|
+| `cache-size` | `0` | int | Number of cache entries (0 = disabled) |
+| `cache-root` | `CGIT_CACHE_ROOT` | path | Directory for cache files |
+| `cache-root-ttl` | `5` | int (min) | TTL for repo-list pages |
+| `cache-repo-ttl` | `5` | int (min) | TTL for repo-specific pages |
+| `cache-dynamic-ttl` | `5` | int (min) | TTL for dynamic content |
+| `cache-static-ttl` | `-1` | int (min) | TTL for static content (-1 = forever) |
+| `cache-about-ttl` | `15` | int (min) | TTL for about/readme pages |
+| `cache-snapshot-ttl` | `5` | int (min) | TTL for snapshot pages |
+| `cache-scanrc-ttl` | `15` | int (min) | TTL for cached scan-path results |
+
+### Sorting
+
+| Directive | Default | Type | Description |
+|-----------|---------|------|-------------|
+| `case-sensitive-sort` | `1` | int | Case-sensitive repo name sorting |
+| `section-sort` | `1` | int | Sort sections alphabetically |
+| `section-from-path` | `0` | int | Derive section name from path depth (>0 = from start, <0 = from end) |
+| `repository-sort` | `"name"` | string | Default sort field for repo list |
+| `branch-sort` | `0` | int | Branch sort: 0=name, 1=age |
+| `commit-sort` | `0` | int | Commit sort: 0=default, 1=date, 2=topo |
+
+### Snapshots
+
+| Directive | Default | Type | Description |
+|-----------|---------|------|-------------|
+| `snapshots` | (none) | string | Space-separated list of enabled formats: `.tar` `.tar.gz` `.tar.bz2` `.tar.lz` `.tar.xz` `.tar.zst` `.zip`. Also accepts `all`. |
+
+### Filters
+
+| Directive | Default | Type | Description |
+|-----------|---------|------|-------------|
+| `about-filter` | (none) | filter | Filter for rendering README/about content |
+| `source-filter` | (none) | filter | Filter for syntax highlighting source code |
+| `commit-filter` | (none) | filter | Filter for commit messages |
+| `email-filter` | (none) | filter | Filter for email display (2 args: email, page) |
+| `owner-filter` | (none) | filter | Filter for owner display |
+| `auth-filter` | (none) | filter | Authentication filter (12 args) |
+
+Filter values use the format `type:command`:
+- `exec:/path/to/script` — external process filter
+- `lua:/path/to/script.lua` — Lua script filter
+- Plain path without prefix defaults to `exec`
+
+### Display
+
+| Directive | Default | Type | Description |
+|-----------|---------|------|-------------|
+| `summary-branches` | `10` | int | Branches shown on summary page |
+| `summary-tags` | `10` | int | Tags shown on summary page |
+| `summary-log` | `10` | int | Log entries shown on summary page |
+| `side-by-side-diffs` | `0` | int | Default to side-by-side diff view |
+| `remove-suffix` | `0` | int | Remove `.git` suffix from repo URLs |
+| `scan-hidden-path` | `0` | int | Include hidden dirs when scanning |
+
+### Miscellaneous
+
+| Directive | Default | Type | Description |
+|-----------|---------|------|-------------|
+| `agefile` | `"info/web/last-modified"` | path | File in repo checked for modification time |
+| `mimetype-file` | (none) | path | Apache-style mime.types file |
+| `mimetype.<ext>` | (none) | string | MIME type for a file extension |
+| `module-link` | (none) | URL | URL template for submodule links |
+| `strict-export` | (none) | path | Only export repos containing this file |
+| `project-list` | (none) | path | File listing project directories for `scan-path` |
+| `scan-path` | (none) | path | Directory to scan for git repositories |
+| `readme` | (none) | string | Default README file spec (can repeat) |
+| `include` | (none) | path | Include another config file |
+
+## Repository Directives
+
+Repository configuration begins with `repo.url=` which creates a new
+repository entry via `cgit_add_repo()`. Subsequent `repo.*` directives
+modify the most recently created repository via `repo_config()` in `cgit.c`.
+
+| Directive | Description |
+|-----------|-------------|
+| `repo.url` | Repository URL path (triggers new repo creation) |
+| `repo.path` | Filesystem path to the git repository |
+| `repo.name` | Display name |
+| `repo.basename` | Override for basename derivation |
+| `repo.desc` | Repository description |
+| `repo.owner` | Repository owner name |
+| `repo.homepage` | Project homepage URL |
+| `repo.defbranch` | Default branch name |
+| `repo.section` | Section heading for grouped display |
+| `repo.clone-url` | Clone URL (overrides global) |
+| `repo.readme` | README file spec (`[ref:]path`, can repeat) |
+| `repo.logo` | Per-repo logo URL |
+| `repo.logo-link` | Per-repo logo link URL |
+| `repo.extra-head-content` | Extra HTML for `<head>` |
+| `repo.snapshots` | Snapshot format mask (space-separated suffixes) |
+| `repo.snapshot-prefix` | Prefix for snapshot filenames |
+| `repo.enable-blame` | Override global enable-blame |
+| `repo.enable-commit-graph` | Override global enable-commit-graph |
+| `repo.enable-log-filecount` | Override global enable-log-filecount |
+| `repo.enable-log-linecount` | Override global enable-log-linecount |
+| `repo.enable-remote-branches` | Override global enable-remote-branches |
+| `repo.enable-subject-links` | Override global enable-subject-links |
+| `repo.enable-html-serving` | Override global enable-html-serving |
+| `repo.enable-subtree` | Override global enable-subtree |
+| `repo.max-stats` | Override global max-stats |
+| `repo.max-subtree-commits` | Override global max-subtree-commits |
+| `repo.branch-sort` | `"age"` or `"name"` |
+| `repo.commit-sort` | `"date"` or `"topo"` |
+| `repo.module-link` | Submodule URL template |
+| `repo.module-link.<submodule>` | Per-submodule URL |
+| `repo.badge` | Badge entry: `url\|imgurl` or just `imgurl` (can repeat) |
+| `repo.hide` | `1` = hide from listing (still accessible by URL) |
+| `repo.ignore` | `1` = completely ignore this repository |
+
+### Filter overrides (require `enable-filter-overrides=1`)
+
+| Directive | Description |
+|-----------|-------------|
+| `repo.about-filter` | Per-repo about filter |
+| `repo.commit-filter` | Per-repo commit filter |
+| `repo.source-filter` | Per-repo source filter |
+| `repo.email-filter` | Per-repo email filter |
+| `repo.owner-filter` | Per-repo owner filter |
+
+## Repository Defaults
+
+When a new repository is created by `cgit_add_repo()`, it inherits all global
+defaults from `ctx.cfg`:
+
+```c
+ret->section = ctx.cfg.section;
+ret->snapshots = ctx.cfg.snapshots;
+ret->enable_blame = ctx.cfg.enable_blame;
+ret->enable_commit_graph = ctx.cfg.enable_commit_graph;
+ret->enable_log_filecount = ctx.cfg.enable_log_filecount;
+ret->enable_log_linecount = ctx.cfg.enable_log_linecount;
+ret->enable_remote_branches = ctx.cfg.enable_remote_branches;
+ret->enable_subject_links = ctx.cfg.enable_subject_links;
+ret->enable_html_serving = ctx.cfg.enable_html_serving;
+ret->enable_subtree = ctx.cfg.enable_subtree;
+ret->max_stats = ctx.cfg.max_stats;
+ret->max_subtree_commits = ctx.cfg.max_subtree_commits;
+ret->branch_sort = ctx.cfg.branch_sort;
+ret->commit_sort = ctx.cfg.commit_sort;
+ret->module_link = ctx.cfg.module_link;
+ret->readme = ctx.cfg.readme;
+ret->about_filter = ctx.cfg.about_filter;
+ret->commit_filter = ctx.cfg.commit_filter;
+ret->source_filter = ctx.cfg.source_filter;
+ret->email_filter = ctx.cfg.email_filter;
+ret->owner_filter = ctx.cfg.owner_filter;
+ret->clone_url = ctx.cfg.clone_url;
+```
+
+This means global directives should appear *before* `repo.url=` entries, since
+they set the defaults for subsequently defined repositories.
+
+## Git Config Integration
+
+When `enable-git-config=1`, the `scan-tree` scanner reads each repository's
+`.git/config` and maps gitweb-compatible directives:
+
+```c
+if (!strcmp(key, "gitweb.owner"))
+ config_fn(repo, "owner", value);
+else if (!strcmp(key, "gitweb.description"))
+ config_fn(repo, "desc", value);
+else if (!strcmp(key, "gitweb.category"))
+ config_fn(repo, "section", value);
+else if (!strcmp(key, "gitweb.homepage"))
+ config_fn(repo, "homepage", value);
+else if (skip_prefix(key, "cgit.", &name))
+ config_fn(repo, name, value);
+```
+
+Any `cgit.*` key in the git config is passed directly to the repo config
+handler, allowing per-repo settings without modifying the global cgitrc.
+
+## README File Spec Format
+
+README directives support three forms:
+
+| Format | Meaning |
+|--------|---------|
+| `path` | File on disk, relative to repo path |
+| `/absolute/path` | File on disk, absolute |
+| `ref:path` | File tracked in the git repository at the given ref |
+| `:path` | File tracked in the default branch or query head |
+
+Multiple `readme` directives can be specified. cgit tries each in order and
+uses the first one found (checked via `cgit_ref_path_exists()` for tracked
+files, or `access(R_OK)` for disk files).
+
+## Macro Expansion
+
+The `expand_macros()` function (in `shared.c`) performs environment variable
+substitution in certain directive values (`cache-root`, `scan-path`,
+`project-list`, `include`). A `$VARNAME` or `${VARNAME}` in the value is
+replaced with the corresponding environment variable.
+
+## Example Configuration
+
+```ini
+# Site settings
+root-title=Project Tick Git
+root-desc=Source code for Project Tick
+logo=/cgit/cgit.png
+css=/cgit/cgit.css
+virtual-root=/cgit/
+
+# Features
+enable-commit-graph=1
+enable-blame=1
+enable-http-clone=1
+enable-index-links=1
+snapshots=tar.gz tar.xz zip
+max-stats=quarter
+
+# Caching
+cache-size=1000
+cache-root=/var/cache/cgit
+
+# Filters
+source-filter=exec:/usr/lib/cgit/filters/syntax-highlighting.py
+about-filter=exec:/usr/lib/cgit/filters/about-formatting.sh
+
+# Scanning
+scan-path=/srv/git/
+section-from-path=1
+
+# Or manual repo definitions:
+repo.url=myproject
+repo.path=/srv/git/myproject.git
+repo.desc=My awesome project
+repo.owner=Alice
+repo.readme=master:README.md
+repo.clone-url=https://git.example.com/myproject.git
+repo.snapshots=tar.gz zip
+repo.badge=https://ci.example.com/badge.svg|https://ci.example.com/
+```