Gitility.Fetch (Gitility v0.4.0)

Copy Markdown View Source

Fetches remote Git objects and refs into a local bare repository over smart HTTP. This is Gitility's only write path into a real Git directory; the snapshot and query APIs remain read-only.

Production callers should use https://. The http:// scheme exists for trusted local fixtures. Authorization values go straight to the in-process rustls HTTP client, are never stored or logged, and Git's credential-helper cascade is explicitly disabled. A 401 can therefore never invoke a subprocess. Redirects are not followed, so an authorization header cannot be replayed to a moved host. The underlying transport has a fixed 20-second connection timeout; :timeout_ms is the absolute deadline for the whole call, including credential providers, queue residence, HTTP requests, and a single authentication retry.

:credentials accepts a one-argument function or {module, function, args}. It receives %{url: url, host: host, attempt: 1 | 2} and must return {:ok, %{authorization: value}}. Provider failures are sanitized as :credentials_unavailable; neither provider error terms nor returned secrets are copied into the error. retry_unauthorized: true invokes a provider once more after the first 401 and never loops. The static :authorization option is mutually exclusive with a provider.

Fetches are single-flight per Path.expand/1 destination within one VM. Symlink aliases are not resolved and can defeat that key; cross-process races are outside this contract. A lease remains held until every attached native job is terminal, even if its caller dies or times out. If the Locks process itself restarts, its in-memory leases are lost and new fetches can be admitted.

Pruning is limited to destination spaces of wildcard fetch refspecs and uses reverse refspec matching. Exact destinations and symbolic refs are never pruned. Tags are fetched only when an explicit tag refspec is supplied; implicit tag auto-following is disabled.

Transport, negotiation, and pack-verification failures precede gix's ref transaction and leave refs untouched. Cancellation is cooperative, so a :timeout or :cancelled result may race with the internal commit point; rerunning the idempotent fetch converges. :cleanup_failed means the fetch committed and only post-fetch cleanup failed. Prune failures are retryable. Keep-file failures are not: the message names the leftover .keep, which is safe to delete manually.

By default fetches use the isolated two-worker Gitility.FetchRuntime. Passing an explicit runtime: may intentionally share a query runtime and its queue.

Summary

Types

credential_provider()

@type credential_provider() ::
  (map() -> {:ok, %{authorization: binary()}} | {:error, term()})
  | {module(), atom(), [term()]}

Functions

fetch(dest, url, refspecs, opts \\ [])

@spec fetch(Path.t(), String.t(), [String.t()], keyword()) ::
  {:ok, Gitility.Fetch.Result.t()} | {:error, Gitility.Error.t()}