Manage hosted projects
Create a repository
scan follows no symbolic links, recognizes both .git directories and
worktree .git files, and never writes to a discovered repository. Server
repository creation never overwrites an existing path and enables Git's
non-fast-forward and delete protection. ck-git-shell is intended only as an
OpenSSH forced command: it consumes SSH_ORIGINAL_COMMAND, rejects shell
syntax and traversal, and can invoke only git-upload-pack,
git-receive-pack, or the documented local control RPC.
Change the default branch
A project's default branch is the branch its bare repository's HEAD names.
New clones check it out, CI workflows without on: build it, and ck-git Pages
publishes only from its builds. It is chosen at creation and changed later
from any paired device:
ckgit default-branch # show it for this repository's project
ckgit default-branch develop --dry-run # preview the change
ckgit default-branch develop # confirm on a terminal, or add --yes
--project NAME selects a project other than the one paired with the current
repository. The branch must already exist on the server; push it first. On the
server, run the same change as the service account that owns the repositories:
sudo -u ckgit ckgit-admin default-branch NAME BRANCH --config /etc/ck-git-hosting/server.ini
Without BRANCH, ckgit-admin default-branch NAME prints the current one.
Both commands refuse a missing branch, record a default-branch-changed event,
and refresh the dashboard (ckgit-admin through the configured control
socket). Branches, commits, and checkouts are not changed, and the change starts
no CI run: the next push to the new default branch builds and publishes it.
Checkout registration and metadata
ckgit register records the current paired checkout in the private local
inventory and on the server, using the path privacy mode in client.ini for
the server report. Registration requires a daemon started with
--state-root: this pre-created directory must be owned by the daemon user and
mode 0700. It stores a strict, atomic metadata record separately from Git
repositories. Registration requires an existing, non-symlink hosted repository.
--http-port serves the dashboard on 127.0.0.1 only; its pages accept only
bounded, bodyless HTTP/1.1 GET and HEAD
requests.
Successful confirmed publishing refreshes that registration after its Git push.
A non-dry-run ckgit sync refreshes registration after its atomic preflight and
before pushing refs; if registration fails, it skips the push. --dry-run does
not alter registration metadata or Git refs.
The same private state root keeps event logs for server project creation,
checkout registrations, pushes, CI cancellations, and default-branch changes. The active log rotates before exceeding
64 KiB; repeated rotations in one month receive distinct archive names.
Project pages read the newest two logs and show those
events without writing a path or remote URL into the event log. Set
--hook-directory to an administrator-provisioned, non-symlink directory that
contains the compiled executable post-receive hook. New repositories then use
that directory as Git's hooks path. When ck-git-shell is also given the same
private --state-root, it passes the authenticated client ID, validated
project name, repository/state-root paths, and control socket to git-receive-pack; the
hook records a bounded git-push event after successful ref updates and asks
the daemon to refresh that project. The refresh transport has a two-second
deadline and a failure does not fail the push.
Remove a hosted project
Run ckgit-admin remove-project NAME --config SERVER-CONFIG --dry-run (or
--repo-root ROOT --state-root ROOT instead of --config) as the account
that owns the private metadata to inspect the operation. Omitting --dry-run
prints the same plan and then asks for confirmation on a terminal ("Execute
this plan? Type yes:"), or requires --yes for unattended use; redirected
input without --yes only previews. Removal renames NAME.git into
ROOT/.trash/NAME.git.<epoch> with a unique suffix when needed. It clears the
project's checkout registrations, derived metadata, and entries in every event
archive. Existing trash is preserved; this command does not permanently erase
the retained repository.
Provide --control-socket PATH to notify a running daemon immediately. The
periodic sweep also drops deleted projects and removes orphan metadata for
repositories deleted by hand. Creation, registered-checkout writes, removal,
event writes, and orphan cleanup share a repository lifecycle lock. Late push
events for a project removed administratively are discarded. There is no HTTP
delete route or automatic trash purge.