anvilsign in

collin/anvil

RenderedSource

anvil

A minimal, self-hosted git forge in Rust, built on gix (gitoxide).

Design rules

  • Pure gitoxide — never the git binary. The product (server, CI broker, mirroring, deploy image) must not invoke or depend on a git executable. When gix lacks a capability, implement the protocol on gix plumbing instead of shelling out — e.g. gix can't push yet, so anvil-git/src/push.rs speaks the send-pack wire format itself (with gitserver-core covering the server side). Tests may use the git CLI, but only as a fixture/interop check, never on the code path under test.

Dev setup: git config core.hooksPath .githooks — the pre-commit hook runs cargo +nightly fmt (nightly, for the unstable options in rustfmt.toml), cargo sort-derives (cargo install cargo-sort-derives), and cargo clippy --workspace --all-targets -- -D warnings.

Viewing attachments referenced in tasks

TODO items and tickets may embed an uploaded image as ![...](/{owner}/{repo}/-/attachments/{hash}). These bytes live outside git on the anvil instance, so to actually see one, fetch it from the instance and Read the file. With ANVIL_BASE_URL (the instance URL) and ANVIL_TOKEN (a read-only PAT — mint one with anvild user token create <user>) set:

curl -fsS -H "Authorization: Bearer $ANVIL_TOKEN" \
  "$ANVIL_BASE_URL/{owner}/{repo}/-/attachments/{hash}" -o /tmp/att.png

Then Read /tmp/att.png to view it. The PAT is read-only (it authenticates GET/HEAD only), so it's safe to hold; public-repo attachments need no token. If those env vars aren't set, ask the user for the instance URL and a token rather than guessing.

Current status, resume notes, the agreed next steps (a/b/c), and the roadmap live in the TODO. Read it first:

@TODO.md