[package]
name = "gunnar-pack"
version = "2.0.0"
edition = "2021"
rust-version = "1.85"
license = "MIT OR Apache-2.0"
repository = "https://git.gunnar.rs/nordisk/edda"
description = "Packfile writing and indexing for gunnar, shared by the server's upload-pack/receive-pack and the client's send-pack. Plumbing only."
[dependencies]
gix-hash = { version = "0.27", features = ["sha1", "sha256"] }
gix-object = "0.65"
gix-pack = { version = "0.75", features = ["streaming-input", "parallel"] }
gix-features = { version = "0.50", features = ["progress"] }
# gix 0.88 reports object-access, pack-generation, hashing and indexing
# failures as `gix_error` exceptions; `Error` wraps them as `gix_error::Error`.
gix-error = "0.4"
flate2 = { version = "1", default-features = false, features = ["zlib-rs"] }
# Trailer checksums only. See `src/checksum.rs`. Object ids keep going through
# `gix-hash`'s collision-detecting hasher.
sha1 = "0.11"
thiserror = "2"
tracing = "0.1"
# The delta ENCODER, optional and off by default. See the `delta` feature.
# Sibling in edda now, referenced by path.
gunnar-delta = { version = "2.0.0", path = "../gunnar-delta", optional = true }
[features]
# Counting oid -> pack-offset resolutions on the serve path, for
# `.nornir/fanout16-reasoning.md`'s "how many, and where" table. OFF by default
# and turned on by NOTHING in this tree except `bench/Cargo.toml`; with it off
# `oidprobe::bump` is an empty inline function and the statics do not exist.
# Same shape as `gunnar-wire/stages`, and for the same reason: a diagnostic must
# not tax the path it diagnoses.
oidprobe = []
default = []
# `write_pack_deltified`: compute deltas for a pack whose objects have none to
# copy, which is every pack a pushing client writes out of loose objects.
#
# Off by default ON PURPOSE. §2 forbids growing the SERVER graph for something
# the server does not use: the server's path is `write_pack_copy` (`P-001`), it
# reuses deltas rather than computing them, and an appliance image has no
# business linking an encoder it never calls. `gunnar-client` turns this on, and
# `gunnar-delta` is now an entry in xtask's FORBIDDEN_IN_SERVER_GRAPH, so the §2
# guard resolves the appliance graph and the bare `-p gunnar-pack` graph and
# fails if the encoder appears in either — while that same table's anti-phantom
# rule requires it to be present in the DEFAULT build, so the entry cannot go
# stale in silence.
delta = ["dep:gunnar-delta"]
[dev-dependencies]
anyhow = "1"
tempfile = "3"
# Fixtures only, never a normal dependency. See TOTAL-PROMPT §0/§2: this crate is on
# the SERVER side of the dependency guard and must stay free of gix porcelain.
# STAYS ON 0.86, and this is the one gix pin in the constellation that must NOT
# move to 0.87. Measured 2026-08-27: this is a DEV-dependency, so it never reaches
# a consumer -- `gunnar-pack 1.1.0` cold-resolves from a virgin CARGO_HOME with
# ZERO gix rows in the lockfile, which is why it is the one crate in this family
# the yanked-`bisync` breakage never killed. Its job here is to be the SAME
# plumbing generation as the crate under test: gix 0.86 carries gix-pack 0.73 and
# gix-object 0.63, which is what `gunnar-pack` itself pins, so
# `tests/common/mod.rs:453` can hand a gix odb handle straight over as
# `Box<dyn gix_pack::Find>`. gix 0.87 carries gix-pack 0.74.2 / gix-object 0.64,
# and bumping it fails 8 test targets on that trait skew (E0277 "there are
# multiple different versions of crate `gix_pack`"), plus E0560/E0061 on
# `odb::at_opts`. Fixing it means migrating the whole plumbing stack
# (gix-object 0.63->0.64, gix-pack 0.73->0.74, gix-odb 0.83->0.84, gix-ref
# 0.66->0.67) across gunnar-store/-wire/-policy/-delta/-bitmap and
# storage-git-gix -- the migration gunnar's own branch measured and refused,
# because it moves the semver break instead of removing it.
gix = { version = "0.88", default-features = false, features = ["max-performance-safe", "revision", "blob-diff", "sha1", "sha256"] }
# ── the deltifying writer's proof, which needs the feature that provides it ───
# `required-features` and NOT a `#![cfg(feature = "delta")]` in the file: a
# cfg-ed-out test still compiles into a binary that reports `ok. 0 passed`,
# which is a green nobody can distinguish from a real one. With this, cargo
# does not build the target at all unless `delta` is on.
#
# MEASURED on oden 2026-08-24: with NEITHER gate, `cargo check -p gunnar-pack
# --all-targets` (and every `--workspace --all-targets` in edda) died with
# `error[E0432]: unresolved imports gunnar_pack::write_pack_deltified,
# gunnar_pack::DeltaOptions` — the encoder is behind `delta`, which is
# `default = []` on purpose (§2 keeps it out of the SERVER graph).
[[test]]
name = "deltified"
path = "tests/deltified.rs"
required-features = ["delta"]