Core Concepts
The vocabulary behind every Dodil Git interaction.
Two planes, one host
Everything you do lands on one of two planes:
the git WIRE smart-HTTP: https://git.dodil.io/<repo_id>.git
(clone / fetch / push) SSH: [email protected]:<repo_id>.git
the REST CONTROL PLANE /api/v1/… — repos, PRs, checks, protection,
(console, CLI, API) CI secrets, SSH keysThe wire moves objects; the control plane manages everything around them. Both authenticate through the same identity model — see Auth and Access.
Repositories
A repository has two names:
repo_id— an opaque UUIDv7, the permanent identity. Every API path and every clone URL keys by it (/api/v1/repos/{repo_id},https://git.dodil.io/{repo_id}.git).- An address —
{org_slug}/{name}, the human handle. It is renameable and resolves back to therepo_idviaGET /api/v1/orgs/{org_slug}/repos/{name}. The CLI accepts any of the three forms (repo_id,name,org/name) anywhere a<repo>argument appears.
Repos also carry a default branch (server default main; retarget any time to an existing branch), a state (active / deleted), and size/pack-count quotas.
Visibility
private (the default) or public. A public repo allows anonymous read — clone, code browse, PR reading — with no credential. Writing always requires one. Flipping visibility requires git.admin.
Pull requests
A PR proposes merging a source_branch into a target_branch. It carries a per-repo number, a state (open → merged or closed), the current head_sha, comments, reviews, and a checks_state rollup for the head commit.
- Reviews are sha-pinned. A verdict (
approveorrequest_changes) records the head sha it was cast on — its freshness stamp. Push new commits and the approval no longer matches the head; protection can dismiss stale approvals automatically. - Merging supports three methods:
merge_commit,fast_forward, andsquash. Passexpected_head_shato make the merge fail if someone pushed in between.
CI checks
A check is one job’s report against one commit: a name (namespaced workflow/job), a state (queued → running → passed / failed / errored), an attempt counter, and a log. Per commit the API also returns a worst-of rollup (unspecified means no checks reported).
Runs start from files in the repo: push a workflow under .github/workflows/ or a .dodil/checks.yaml. Jobs declare needs dependencies, which the console renders as a graph. Logs stream live over SSE while a job runs and are flushed to durable storage when it finishes.
CI secrets are write-only values injected into jobs and masked in logs, at three scopes — organization, repository, and per-environment — with fetch-time precedence environment > repo > org. A read never returns a value, only names and timestamps.
Branch protection
A protection rule guards every branch matching a branch_pattern:
| Setting | Effect |
|---|---|
required_approvals | PRs need N fresh approvals to merge |
require_green_checks | the head commit’s rollup must be passed |
block_force_push | non-fast-forward pushes are rejected |
block_deletion | the branch cannot be deleted |
block_self_approval | the PR author’s own approval doesn’t count |
dismiss_stale_approvals | new commits invalidate earlier approvals |
Rules are upserted per pattern (PUT /api/v1/repos/{repo_id}/protection) and enforced on both the wire (force-push, deletion) and the control plane (merge).
Roles
Three IAM-granted tiers scope everything: git.admin (manage settings, visibility, protection, delete), git.editor (read + write — the default), git.viewer (read). Grants are org-wide or conditioned to a single repo — see Auth and Access.
See also
- Quickstart — put the vocabulary to work
- API Reference — the endpoints behind each concept
- Recipes — CI Checks — checks + protection gating a PR end to end