Skip to content
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.

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

Clone, bundle, checksum, upload create-only, sign the run-manifest.

Terminal window
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.

Fetch a bundle, re-check its checksum, git bundle verify, clone it out.

Terminal window
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.

Check the manifest signature, then re-download every artifact and recompute its SHA-256.

Terminal window
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.

Terminal window
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.

Terminal window
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.

Preflight. Checks tooling (git on PATH), validates config, checks source auth, checks the WORM lock. Writes nothing.

Terminal window
gitdr doctor --config config.yaml

Run it before the first backup and after any credential or bucket change.

Terminal window
gitdr version
Code Meaning
0 success
1 run failed (config, auth, network, any repo, any artifact)
2 usage error (bad flags, missing required flag)