docs/users.org
258 lines · 10532 bytes
gitbay user guide
- Installing the CLI
- Getting an account
- SSH keys
- Verified commits
- Repositories
- Organizations
- Issues
- Merge requests
- Notifications
- Scripting
- CLI setup
Everything here works from stock OpenSSH — replace gitbay with
ssh git@<host> in any command and it behaves identically. The CLI adds
convenience (instance profiles, repo inference, $EDITOR), nothing more.
ssh git@<host> help lists every command the server knows.
Installing the CLI
go install gitbay.org/gitbay/cmd/gitbay@latest # any platform with Go
brew install krz/tap/gitbay # Homebrew (macOS/Linux)
Or build from source: go build ./cmd/gitbay in a clone of
https://gitbay.org/krz/gitbay.git.
Getting an account
How you join depends on the instance's registration mode:
- closed
- an admin creates your account on the host and registers your first SSH key. Nothing for you to do but hand over your public key.
- invite
-
you receive a single-use code by email. With the SSH key you want to use:
ssh git@<host> register --username you --invite <code>Your account is active immediately; the invited address is your verified email.
- open
-
ssh git@<host> register --username you --email you@example.orgA verification code arrives by mail. Until you run
ssh git@<host> email verify <code>, the account is pending: you can runwhoamiand the email commands, and nothing else — no git, no repos.
SSH keys
Your key is your identity; there are no passwords anywhere. The SSH
username is always git — the key alone determines who you are.
gitbay auth keys list
gitbay auth keys add --scope git < ~/.ssh/ci_key.pub # key on stdin
gitbay auth keys remove SHA256:...
Scopes: full (default; git plus every control command) or git (git
transport only — right for CI and automation keys, which then cannot
touch issues, settings, or your account).
A key belongs to exactly one account instance-wide. Registering a key someone else already holds is refused without telling you whose it is.
Verified commits
The commit badge is driven by the author email and the signing key:
verified means the signature is valid, the key is registered to an
account, and the author email is a verified address on that account.
For OpenPGP signing (git's default):
gpg --armor --export you@example.org | gitbay auth pgp add
For SSH signing (git config gpg.format ssh): sign with any key
registered on your account; your verified addresses act as the principal
set. No separate registration step.
Add and verify additional addresses with email add <address> /
email verify <code> (requires the instance to have SMTP; otherwise an
admin can assert an address for you).
The states you will see, in decreasing order of trust: verified,
signed_unknown_key (valid signature, key not registered here — register
it and history upgrades retroactively), signed_email_mismatch (real
key, author line claims someone else), signed_key_expired /
signed_key_revoked, bad_signature, unsigned. Server-created commits
(web edits, merge commits) are always unsigned — the server holds no
signing key on principle.
Repositories
gitbay repo create you/project [--private]
gitbay repo clone you/project
gitbay repo list
gitbay repo show you/project
gitbay repo log you/project --limit 20 # commits with signature states
gitbay repo fork other/project [--name mine]
gitbay repo delete you/project --yes
Pushing is SSH-only. Public repositories are anonymously readable over
HTTPS (and git:// where enabled); private repositories exist only over
SSH and answer "not found" to everyone without access.
Access and settings (owner or admin grant):
gitbay repo access grant you/project alice write # read | write | admin
gitbay repo access revoke you/project alice
gitbay repo settings protect you/project main # no force-push, no delete
gitbay repo settings require-signed you/project on # every commit must verify
gitbay repo settings git-daemon you/project on # expose over git://
gitbay repo topics add you/project cli forge # free-form tags, shown on the web
gitbay repo search forge # find repos by name/description/topic
gitbay repo grep you/project "some string" # literal git grep over the default branch
gitbay repo pin you/project # pin to your web dashboard
gitbay repo unpin you/project
gitbay repo archive you/project # read-only: pushes and issue/MR
gitbay repo unarchive you/project # writes refused, browsing intact
Import from another forge (git data only — issues and PRs do not transfer):
gitbay repo import you/mirror --from https://github.com/you/repo.git \
[--private] [--token-stdin] # token on stdin, never in the URL
Organizations
Orgs share the owner namespace with users and own repositories at
org/repo. Members get write on all org repos; org admins get repo
admin, create repos under the org, and manage membership.
gitbay org create krz
gitbay org members add krz alice [--role admin]
gitbay org show krz
gitbay org rename krz newname # clone URLs change
gitbay org delete krz --yes # only when it owns no repositories
Issues
Anyone who can read a repository can file and comment. Closing/reopening is for the author or anyone with write; labels and assignees need write.
gitbay issue create --title "it breaks" [--body "..." | --file -]
gitbay issue list [--state open|closed|all]
gitbay issue show 4
gitbay issue comment 4 --message "same here"
gitbay issue close 4 / reopen 4
gitbay issue label 4 --add bug --remove wontfix
gitbay issue assign 4 --add alice
gitbay issue milestone 4 v1.0 # or "none" to clear
Inside a clone, the repository is inferred from the origin remote —
that is why no owner/name appears above. Anywhere else, pass it as the
first argument. Long text: --body inline, --file - from stdin, or
neither on a terminal and $EDITOR opens.
Commit messages act on issues when the commits land on the default
branch (direct push or MR merge): closes/fixes/resolves #4 closes the
issue with a linking comment, and a bare #4 leaves a reference
comment. Each issue/commit pair acts once, ever. Same repository only.
Milestones group issues and MRs toward a release (write access to
manage, attach with issue milestone / mr milestone; progress shows
on the web at /owner/name/milestones):
gitbay milestone create v1.0 --description "first release" --due 2027-01-01
gitbay milestone list [--state open|closed|all]
gitbay milestone close v1.0 / reopen v1.0
Issue templates: commit .gitbay/issue-template.md (and optional
issue-template-<name>.md variants) to the default branch. gitbay
issue create prefills $EDITOR with the default template, the web
form prefills its textarea, and gitbay issue templates lists them.
Merge requests
gitbay mr create --source feature --target main --title "add thing"
gitbay mr create other/upstream --source you/fork:feature --target main --title "..."
gitbay mr list / show 4 / diff 4
gitbay mr checkout 4 # local branch mr/4 from the MR head
gitbay mr review 4 --approve # or --request-changes / --comment
gitbay mr merge 4 [--strategy ff|merge|squash|rebase]
gitbay mr close 4
Semantics worth knowing:
- the MR head lives in the target repository as
refs/merge-requests/N/head(fetchable by any reader), so an MR survives deletion of its source branch or fork. - force-pushing the source updates the MR and marks existing reviews stale.
- default strategy: fast-forward when possible, else a merge commit. Squash makes one commit authored by the MR author, committed by the merger. Rebase replays a linear range preserving authors; it refuses ranges containing merge commits, and when fast-forward is possible it is one (original commits and signatures land untouched).
- on
require_signed_commitsbranches only fast-forwards of fully verified commits merge; everything server-created is refused with instructions to rebase locally.
Repo admins can gate merges (repo settings ...): require-approvals
<n> (fresh, non-author approvals; each reviewer's latest review is
their stance, and a fresh request-changes blocks), require-resolved
(no open review threads), require-checks (all statuses green). With
approvals required, a CODEOWNERS file on the target branch (root or
.gitbay/) additionally demands an approval from an owner of every
owned changed file — gitignore-style patterns, last match wins.
Review threads anchor to diff lines:
gitbay mr diff-comment 4 --path main.go --line 12 --message "use log here"
gitbay mr diff-comment 4 --reply 7 --message "done" # join thread 7
gitbay mr threads 4 # threads with staleness
gitbay mr resolve 4 7 / unresolve 4 7
Threads render inline on the MR page. A force-push marks them stale
(shown under "threads on earlier revisions") rather than guessing new
anchors; mr show reports the unresolved count. Resolving is for the
thread author, the MR author, or anyone with write.
Notifications
When the instance has SMTP configured, activity mails you: someone opens an issue or MR on your repository, comments where you are a participant (author, commenter, reviewer), reviews, closes, or merges. You are never mailed about your own actions, and only verified primary addresses receive anything. Delivery retries on relay failure.
Scripting
Every read command takes --json and emits one envelope:
{"protocol_version": 1, "data": ...}. stdout is data, stderr is
messages. Exit codes are stable: 0 ok, 1 failure, 2 usage, 3 not found,
4 denied, 5 server/protocol error. Nothing ever prompts; destructive
commands take --yes.
For HTTP automation see docs/api.org.
CLI setup
gitbay remote add myforge forge.example.org [--port n] [--user u] --default
gitbay remote list
gitbay init [name] [--private] # git init + repo create + origin, in one step
Configuration lives at ~/.config/gitbay/config.toml. The CLI shells
out to your real ssh, so ~/.ssh/config, the agent, and hardware keys
all apply. Man pages: gitbay man --dir <dir>; completions:
gitbay completion bash|zsh|fish.