CLI reference
gitdr <command> [flags]Four commands. Structured logs go to stderr, machine-readable results go to stdout, and the exit code is the contract: 0 means the whole run succeeded, anything else means treat it as a failed backup. No partial success reported as success, ever.
Common flags (every command)
Section titled “Common flags (every command)”| Flag | Default | What |
|---|---|---|
--config |
$GITDR_CONFIG |
path to the config YAML |
--output |
text |
result format on stdout, text or json |
--log-level |
from config | debug info warn error |
--log-format |
from config | json or text |
backup
Section titled “backup”Clone, bundle, checksum, upload create-only, sign the run-manifest.
gitdr backup --config config.yaml [--repo owner/name] [--require-worm]| Flag | What |
|---|---|
--repo |
back up one repo, overrides source.repo |
--require-worm |
fail closed if the destination isn’t confirmed immutable |
Prints the manifest key on success. With --output json, stdout is the full signed
run-manifest.
restore
Section titled “restore”Fetch a bundle, re-check its checksum, git bundle verify, clone it out.
gitdr restore --config config.yaml \ --repo acme/api --host github.com --date 2026-06-01 --out ./restore/api| Flag | What |
|---|---|
--repo |
owner/name, required |
--host |
source host, default github.com |
--date |
backup date, YYYY-MM-DD, required |
--out |
output directory, required |
Needs only read access to the bucket. If backups were encrypted, set
GITDR_ENCRYPTION_KEY.
verify
Section titled “verify”Check the manifest signature, then re-download every artifact and recompute its SHA-256.
gitdr verify --config config.yaml --manifest <manifest-object-key>| Flag | What |
|---|---|
--manifest |
manifest object key |
--drill |
drill report object key, instead of --manifest |
Give exactly one of the two. Needs manifest.publicKeyPath and read access. Doesn’t need the
encryption key, checksums cover the stored ciphertext. Non-zero exit on any signature or
checksum mismatch.
gitdr verify --config config.yaml --drill <drill-report-object-key>--drill checks a drill report’s signature and prints what the document says: which manifest
it tested, whether that manifest’s own signature was checked, and how many repositories came
back. It reads nothing out of the bucket beyond the report and its .sig, so it has no
artifact count, and it does not re-run the drill. It answers the question somebody holding a
printed evidence pack has, which is whether the document is authentic and what it claims.
The two forms refuse each other’s documents. A drill report parses as a manifest with no
artifacts, so without that refusal --manifest on a drill report would print a valid signature
over nothing and exit zero.
Restore the backups and prove they carry the history they claim. verify re-reads the
artifacts and rechecks their checksums, which answers whether the copy is intact. drill
actually restores it and compares what came back. Two different claims, reported separately.
gitdr drill --config config.yaml --manifest <manifest-object-key> --output json| Flag | What |
|---|---|
--manifest |
manifest object key to drill; defaults to the most recent |
--host |
source host, e.g. github.com; needed when --manifest is not given |
--owner |
organisation; needed when --manifest is not given |
--sample |
restore at most this many repositories, in slug order; 0 means all |
--workdir |
where to restore; defaults to the system temp directory |
Each repository is compared twice: against the bundle’s own header, and against the ref map
the manifest signed when the copy was made. sourceMatch is absent, not false, when a copy
predates source-ref recording, because missing is not passing.
Refs a clone creates nothing for, refs/merge-requests/* and the like, are counted apart and
named rather than folded into the total.
Needs both halves of the signing key: manifest.publicKeyPath to verify the manifest it is
about to drill, and manifest.signingKeyPath to sign the report it writes. A drill of a manifest
whose signature nobody checked proves those artifacts restore rather than that gitdr wrote them,
and an unsigned report is a text file anybody can write. Also read access to the bucket and
enough disk in --workdir for the repositories it restores.
It writes two objects to the destination: the signed drill report, {ts}.drill.json, and its
detached signature, beside the manifest it drilled. They go through the same create-only path as
everything else, so the evidence is as immutable as the thing it proves — and, like every other
write, cannot be removed afterwards. This is the operator’s command, not something to hand to a
reader who only needs to check a report; for that, see verify --drill, which needs the public
half only and writes nothing.
Exit 1 if any repository fails to restore or comes back at a different commit. Exit 3 if every repository restored and only storing the report failed: the restores passed and the evidence was not filed, which is a different fact and gets a different code.
doctor
Section titled “doctor”Preflight. Checks tooling (git on PATH), validates config, checks source auth, checks
the WORM lock. Writes nothing.
gitdr doctor --config config.yamlRun it before the first backup and after any credential or bucket change.
version
Section titled “version”gitdr versionExit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
| 0 | success |
| 1 | run failed (config, auth, network, any repo, any artifact) |
| 2 | usage error (bad flags, missing required flag) |