Documentation
Managing Git repositories
This page covers creating repositories, understanding the naming rules, cloning and pushing over SSH, and the distinction between standalone repositories and the site stores that back Markdown sites.
Creating a repository
/git repo create my-project
Expected output:
created repository 'my-project'
owner: admin (*/git/my-project)
Two things happen immediately: the bare repository is created on disk, and the creating user is granted owner access on */git/my-project. That grant covers the repository across every transport — SSH and HTTP alike.
Naming rules
Repository names must be:
- lowercase letters, digits, and hyphens only
- not starting or ending with a hyphen
Valid examples: my-docs, api-reference, project1, config
Invalid examples: My-Docs (uppercase), api_reference (underscore), -project (leading hyphen), project.git (dot)
The rule exists because names appear in SSH URLs and are used as filesystem paths. Keeping them lowercase and hyphen-separated avoids case-sensitivity issues across operating systems and makes URLs predictable.
Listing repositories
/git repo list
Shows all repositories the current user can access, with their clone URLs:
my-project ssh://admin@localhost:2222/my-project.git
config ssh://admin@localhost:2222/config.git
This only shows repositories the user has at least reader access to. A repository that exists but has no grant for the current user does not appear here.
Cloning and pushing over SSH
Cloning
The clone produces a normal local Git repository. Every standard Git operation works against it.
The SSH URL explained
ssh://admin@localhost:2222/my-project.git
───── ───────── ──── ────────── ────
user host port repo name suffix
| Component | Meaning |
|---|---|
admin | The Everlock user authenticating over SSH. Use the actual username, not always admin. |
localhost | The hostname of the Everlock instance. Replace with a real hostname for remote instances. |
2222 | The SSH port. Everlock's default is 2222. Standard SSH port 22 needs no port in the URL. |
my-project | The repository name, exactly as created with /git create. |
.git | The bare-repository suffix — the same convention GitHub and GitLab use. Everlock advertises it and stores each repo on disk as <name>.git, but the server accepts the URL with or without it: …/my-project and …/my-project.git are equivalent. |
On a remote public instance with a real hostname and the default port:
If the Everlock SSH frontend is configured on port 22 (standard):
# or in SCP-style shorthand:
Pushing
Everlock stores the incoming pack bundle directly — it does not unpack to loose objects. The push output follows standard Git protocol:
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (5/5), 412 bytes | 412.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0), pack-reused 0
To ssh://admin@localhost:2222/my-project.git
* [new branch] main -> main
If the repository backs a site, the updated content is served immediately on the next HTTP request — there is no separate deploy step.
Standalone repositories vs site stores
Everlock has two kinds of repositories:
Site stores are created implicitly when you run /site create. Their name defaults to the site name. The site backend reads content directly from the repository's HEAD and serves it over HTTP. You do not create these with /git create.
Standalone repositories are created with /git create. They are plain bare Git repositories with no automatic connection to the HTTP site backend. Use them for anything that needs version control but is not a public-facing site: configuration files, shared scripts, documentation drafts, data exports, or anything else you want to manage through Git.
Both types behave identically from Git's perspective. The difference is solely whether a site backend entry exists that reads from that store.
Example: a config repository
/git create server-config
Grant a colleague read access so they can clone it:
/users grant bob */git/server-config reader
Grant another colleague write access:
/users grant carol */git/server-config writer
See Access control for the full grant model.
Inspecting the repository on disk
Everlock stores repositories as standard bare Git repositories. Once you have a local clone, you can inspect the server-side state with normal tools:
# List refs on the remote
# Show log of what's on the server
The repository on disk is also directly readable with git or gix if you have shell access to the server's data directory — Everlock uses no custom format.
Maintenance: pruning unreachable objects
Everlock stores every object loose. A crash mid-write — for example an out-of-memory kill during a push — or a rewound branch can leave unreachable objects behind: objects no ref points at, which nothing can ever read but which still take up space.
Nothing needs doing about it. The git.gc job sweeps every repository once a
day and prunes them, with no configuration and nothing to enable:
/jobs list
kind schedule next run
─────────────────────────────────────────────
git.gc daily 2026-08-20 05:42
git.retention daily 2026-08-20 03:00
/jobs run git.gc sweeps now if you would rather not wait.
The prune is conservative by design. An object is removed only when both are true:
- it is unreachable from every ref (branches, tags, and pull-request refs), and
- it is older than a one-hour grace window — so an in-flight push or commit that has written objects but not yet moved its ref cannot lose them.
If a repository is already damaged — missing an object a ref still needs — its
prune aborts and deletes nothing rather than risk making it worse; the job
names that repository, sweeps the others, and fails, so the damage shows up in
/jobs list instead of passing unnoticed. Pruning never rewrites reachable
history and never touches refs, so it is safe against a live repository.
/git repo size my-project reports how much of a repository is unreachable at
any time, so you never have to run a prune to find out. A repository whose
history is the cost — a large file committed once and deleted later is still
held by the commit that added it — is the subject of
history retention.