Contextator
ENTR

Sources

Git Repository Source

Indexing documentation straight from a git repository — private repos, provider tokens, how syncing and push-triggered re-indexing work.

Updated:

Index documentation straight from a git repository. Contextator keeps a shallow, single-branch checkout on the server and fetches the branch tip at the start of every index run — or the moment someone pushes, if you add a webhook.

Works with any HTTPS git server: GitHub, GitLab, Bitbucket, Gitea, Forgejo, Codeberg and self-hosted instances.

Adding one

Add source → Git repository

Field Example Notes
Name api-docs The mount prefix. Immutable
Repository URL https://github.com/org/repo.git HTTPS only — SSH remotes are not supported
Branch main The single branch that is checked out
Subdirectory docs Optional. Index only this folder of the repository
Access token – Only for private repositories. Stored encrypted, never shown again
Username – Only needed for a GitLab deploy token (gitlab+deploy-token-N) or a Bitbucket Cloud API token (your Bitbucket username or x-bitbucket-api-token-auth)
File types .md, .mdx .txt, .html/.htm, .csv, .docx and .pdf can be selected too

Press Test connection before saving: it lists the remote’s refs without cloning and answers with the branch’s current commit, so a wrong URL, branch or token is obvious immediately.

With a subdirectory set, a file at docs/guides/install.md in the repository is indexed as api-docs/guides/install.md — the subdirectory itself does not appear in the path.

Private repositories

Paste an access token into Access token. It is encrypted with SECRET_KEY (AES-256-GCM) before it is stored, is never returned by the API and is never shown again — the dialog only says that a token exists. To replace it, paste a new one; to remove it, tick Remove the stored token.

SECRET_KEY must be set (32+ characters, e.g. openssl rand -hex 32) before a source can store a token. See Configuration.

The username sent with the token depends on the provider and is detected from the URL:

Provider Username used Token types
GitHub x-access-token Classic PAT, fine-grained PAT, App installation token
GitLab oauth2 OAuth tokens, personal and project access tokens
Bitbucket Cloud x-token-auth Repository and workspace access tokens
Bitbucket Cloud (API token) your Bitbucket username, or x-bitbucket-api-token-auth Put it in the Username field — the default x-token-auth is for repository/workspace access tokens only
Gitea / Forgejo / Codeberg / other token, or whatever you type in Username

Credentials pasted into the URL itself (https://user:token@host/…) are stripped before the URL is stored — use the token field instead.

Read access to the repository’s contents is enough — the narrowest credential each provider offers:

Provider Narrowest token Username
GitHub A fine-grained PAT limited to the repository with Contents: read, or a GitHub App installation token leave empty (x-access-token)
GitLab A project deploy token with read_repository the token’s generated username, e.g. gitlab+deploy-token-42 — the default oauth2 is refused for a deploy token
Bitbucket Cloud A repository access token with Repositories: read leave empty (x-token-auth)
Gitea / Forgejo An access token with read scope on the repository your username, or leave empty (token)

Reaching a repository only available over SSH

Git is read over HTTPS only. SSH remotes (ssh://…, git@host:path) are not accepted and no SSH key can be stored (ADR-0086). For a repository reachable only over SSH, mirror it yourself: clone or mirror it on the host, inside ALLOWED_DOC_ROOTS, keep it current on your own schedule (a cron job running git pull, or your CI), and add that directory as a Local Directory Source instead. It is then a folder like any other — no push webhook, no branch or subdirectory setting, no Test connection — and exactly as fresh as your schedule keeps it.

How syncing works

At the start of every index run:

  1. If there is no checkout yet, clone it: shallow (depth=1), single branch, no tags.
  2. Otherwise fetch the branch tip. If it moved, point the local branch at it and check out.
  3. If anything goes wrong, fall back to a fresh clone.
  4. Verify the subdirectory still exists on that branch.

The commit currently checked out is shown on the source row (main @ a1b2c3d). Checkouts live under DATA_DIR, so they survive restarts and are deleted with the source.

Automatic re-indexing on push

Every git source gets its own webhook URL and secret, shown while editing the source:

POST http://<your-host>/api/webhooks/git/<source-id>

Add it as a push webhook in the repository settings with that secret, and every push to the branch queues a re-index. Full instructions and provider-by-provider screenshots of the fields: Push Webhooks.

Common problems

Symptom Cause and fix
Authentication failed on Test connection Token missing, expired, or lacking read access. Leave Username empty for a Bitbucket repository or workspace access token (the default x-token-auth is for those only); a Bitbucket Cloud API token needs your Bitbucket username or x-bitbucket-api-token-auth, and a GitLab deploy token its generated gitlab+deploy-token-N username
Branch “…” was not found on the remote The branch name is wrong, or the default branch is master rather than main
Subdirectory “…” does not exist in the repository The path is relative to the repository root and is checked against the branch you configured
Documents disappeared after a failed sync They do not — a source that cannot be read keeps its documents. Fix the cause and press Sync
SSH URL rejected Only HTTPS is supported. Use the HTTPS URL with a token

Notes and limits

  • Only one branch per source. To index two branches, add two sources with different names.
  • Very large repositories clone more slowly than the native git binary would; depth=1, a single branch and a subdirectory keep it comfortable for documentation.
  • Submodules are not fetched.
  • The repository is never written to; Contextator only ever fetches.

Arrow keys to move, Enter to open.