1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
[]
= [".", "cli", "xtask"]
# Exclude xtask from the default `cargo build` / `cargo test` set so a plain
# `cargo build` does not pull a second binary into the workspace target dir.
# Invoke it explicitly with `cargo xtask install` (see `.cargo/config.toml`).
= [".", "cli"]
= "2"
# Single source of truth for the workspace MSRV. The CLI and xtask crates
# inherit this via `rust-version.workspace = true`, and the CI / release
# workflows read it from `cargo metadata` so a bump here propagates
# everywhere without manual edits.
[]
= "1.94"
[]
= "git-remote-object-store"
= "0.2.1"
= "2024"
= true
= "Apache-2.0"
= "https://github.com/dekobon/git-remote-object-store"
= ["Elijah Zupancic <elijah@zupancic.name>"]
= "Git remote helper backed by cloud object stores (S3, Azure Blob Storage)"
= "README.md"
= ["git", "remote-helper", "s3", "azure", "object-store"]
= ["command-line-utilities", "development-tools"]
[]
= "warn"
[]
= { = "warn", = -1 }
= "allow"
# `unreachable!()` expands to `panic!()`, which `.claude/rules/rust.md`
# bans in non-test code. Encoding the rule as a lint catches future
# regressions at compile time. Test code that legitimately needs
# `unreachable!()` (none today) must opt out with `#[allow(...)]`.
= "deny"
[]
# Expose test-only helpers (notably `object_store::mock::MockStore`) to
# integration tests in `tests/` and to higher-phase test code that lives
# outside the lib crate. Production builds leave the feature off; in-crate
# unit tests pick up the helpers via `cfg(test)` regardless of the feature.
= []
[]
# Async traits via Boxed futures. `async_trait` keeps `dyn ObjectStore +
# Send + Sync` ergonomic; native AFIT (stable since 1.75) is awkward
# through `dyn` because each method's future must be `Send`-bounded.
= "0.1"
# Async runtime
= { = "1", = [
"rt-multi-thread",
"macros",
"fs",
"io-std",
"io-util",
"process",
"signal",
"time",
] }
# Errors
= "2"
= "1"
# Logging
= "0.1"
# `reload` is required for runtime verbosity flips driven by the helper
# protocol's `option verbosity <n>` line.
= { = "0.3", = ["env-filter"] }
# Time
= { = "0.3", = ["parsing", "formatting", "macros"] }
# JSON (LFS)
= { = "1", = ["derive"] }
= "1"
# Interactive prompts for the management CLI (`git-remote-object-store`).
# Default features pull in fuzzy-select / completion / history machinery
# that the `Select` + `Confirm` flows here do not exercise; disabling them
# keeps the dependency footprint tight.
= { = "0.11", = false }
# UUID v4 for the doctor's quarantine ref suffix
# (`<ref>_<uuid8>`).
= { = "1", = ["v4"] }
# URL parsing
= "2"
# Git operations (gitoxide). Sub-crates are kept on the same versions
# `gix` 0.83 itself selects to avoid duplicate copies in the dep graph.
#
# `gix` is pulled in with default features on purpose: `gix-hash` 0.25's
# `Kind` enum has its `Sha1` / `Sha256` variants gated behind the matching
# crate features, and its own default feature set is empty. The explicit
# `features = ["sha1"]` below ensures `Kind` is inhabited; disabling
# `gix`'s defaults causes the rest of the gix tree to be compiled without
# `sha1` and reintroduces the non-exhaustive-match build error in
# gix-hash. Keep the defaults until we have a reason to slim the tree.
= "0.83"
= { = "0.25", = ["sha1"] }
= "0.70"
= "0.11"
= "0.32"
# Bytes / IO
= "1"
= "3"
# AWS SDK for the S3 backend. `aws-config` carries the
# `behavior-version-latest` feature so the SDK picks up its own latest
# defaults automatically; revisit pinning later if reproducibility
# becomes a concern.
#
# `credentials-login` enables IAM Identity Center (SSO) login-session
# credential providers. Without it, profiles that use `sso-session` or
# a `LoginSession` chain silently fail to provide credentials, the SDK
# falls through to the EC2 IMDS metadata endpoint, and the resulting
# network error is misreported as "invalid credentials network error".
#
# `aws-sdk-s3` defaults include the legacy `rustls` feature, which
# routes through `aws-smithy-runtime/tls-rustls` and
# `aws-smithy-http-client/legacy-rustls-ring`, pinning `rustls 0.21` +
# `rustls-webpki 0.101.x` — both of which carry open RUSTSEC advisories
# (GHSA-4p46-pwfr-66x6 high-severity panic on malformed CRL, plus two
# name-constraint advisories). The modern `default-https-client` feature
# uses `rustls 0.23` / `rustls-webpki 0.103.x` instead. Disable defaults
# and re-enable everything except the legacy `rustls` feature.
= { = "1", = [
"behavior-version-latest",
"credentials-login",
] }
= { = "1", = false, = [
"sigv4a",
"http-1x",
"default-https-client",
"rt-tokio",
] }
# Direct dep on the smithy HTTP client so `S3Store::from_remote_url`
# can install a custom connector with `pool_idle_timeout(30s)`. The
# default-built client keeps idle connections in the pool indefinitely,
# which wedges long-running LFS sessions on rotated VIPs (#26 / #27).
# `rustls-aws-lc` is the same TLS provider feature `aws-sdk-s3`'s
# `default-https-client` enables transitively (via
# `aws-smithy-runtime/default-https-client`), so cargo unifies on a
# single rustls 0.23 + aws-lc-rs stack — matching the existing tree.
#
# After bumping `aws-config` or `aws-sdk-s3`, run:
# cargo tree -e normal -d | rg rustls
# A duplicate rustls major (or any rustls 0.21 entry) means the SDK's
# `default-https-client` selected a different provider; update the
# `CryptoMode` in `src/object_store/s3.rs` to match.
= { = "1", = ["rustls-aws-lc"] }
# Bridges `aws_smithy_types::DateTime` → `time::OffsetDateTime` for the
# `ObjectMeta::last_modified` conversion.
= { = "0.60", = ["convert-time"] }
# Required for `StreamExt::next` on `aws_smithy_types::byte_stream::ByteStream`
# in the small-object GET path and the multipart download orchestrator.
= "0.3"
# `x-amz-copy-source` is forwarded verbatim by aws-sdk-s3 — keys with
# reserved characters (notably `#` in `LOCK#.lock`) must be percent-encoded
# before being passed in.
= "2"
# Azure SDK for the Blob backend. The SDK is in beta (0.12)
# and does NOT support shared-key authentication out of the box — only
# `Arc<dyn TokenCredential>` (Entra ID). We implement a custom shared-key
# signing `Policy` ourselves so users can authenticate with account keys
# (the only auth Azurite supports without HTTPS + OAuth) and so the
# documented `AZSTORE_<NAME>_KEY` / `AZSTORE_<NAME>_CONNECTION_STRING`
# credential aliases work. Tracking issue: Azure/azure-sdk-for-rust#2975.
= "0.35"
= "0.12"
= "0.35"
# Required for the shared-key signing policy: HMAC-SHA256 over the
# Azure canonicalized string-to-sign, base64-encoded for the
# `Authorization: SharedKey <account>:<sig>` header.
= "0.12"
= "0.10"
= "0.22"
# HTTP transport for the Azure Blob backend. `azure_core` 0.35's default
# transport pools connections forever and never sets TCP keepalive, so a
# rotated VIP can hang a long-running LFS session until the OS-level TCP
# timeout fires (issue #26). We build our own `reqwest::Client` with
# bounded `pool_idle_timeout` / `tcp_keepalive` and install it via
# `ClientOptions::transport`. `rustls` keeps HTTPS to
# `*.blob.core.windows.net` explicit rather than relying on
# `azure_core`'s transitive feature set; cargo unifies with the
# additional `gzip`/`deflate`/`stream` features `azure_core` already
# enables on its own `reqwest` dep, so no decompression/streaming
# capability is lost.
= { = "0.13", = false, = [
"http2",
"rustls",
] }
[]
# Property-based testing for URL round-trip parse/format.
= "1"
# `test-util` exposes `capture_request`, which the `MultipartUploadGuard`
# Drop-fires-AbortMultipartUpload test (#173) wires into the SDK's
# `http_client` slot to byte-equality-check the request the detached
# abort task issues. The crate itself is already a regular dep (above);
# this dev-only entry only flips the `test-util` feature on for test
# builds.
= { = "1", = ["test-util"] }
# `tokio` `test-util` feature gates `tokio::time::pause`, `advance`, and
# `#[tokio::test(start_paused = true)]`. Issue #118's lock-heartbeat
# tests advance virtual time across multiple TTLs without actually
# sleeping, which would otherwise force the test suite to wait minutes
# of wall time per heartbeat assertion. Production builds do not see
# this feature — it's dev-only.
= { = "1", = ["test-util"] }
# zlib compression for synthesised pack bytes in unit tests. Production
# code only needs `Decompress` (provided by `gix::features::zlib`); the
# delta-depth regression test in `packchain::read::tests` constructs a
# valid pack entry payload at test time, which requires the deflate
# direction. `flate2` is already in the transitive graph via `gix-pack`.
= "1"
# RustFS testcontainer used by `tests/s3_store_integration.rs` (gated on the
# `integration-s3` Cargo feature). Cargo does not allow `optional = true` on
# dev-dependencies, so this compiles for every `cargo test` invocation but
# only links into the integration test file when the feature is enabled.
# Features:
# - `blocking` enables `SyncRunner`, which starts the container outside of
# any tokio runtime so it can be shared across multiple `#[tokio::test]`
# -spawned runtimes without their dispatch tasks tearing each other down.
# - `http_wait_plain` enables `WaitFor::http(...)`, required because RustFS
# writes its startup logs to a log file inside the container rather than
# to stdout, so a log-message wait would never fire. We poll the S3
# endpoint instead.
#
# The fixture uses `testcontainers::GenericImage` directly with a pinned
# RustFS tag rather than `testcontainers-modules`, which hardcodes `:latest`
# and would silently drift across alpha releases.
= { = "0.27", = [
"blocking",
"http_wait_plain",
] }
# Note: `reqwest` is a regular dependency (above) — used in production
# by the Azure backend's transport tuning (#26 / #28) and reused here by
# `tests/azure_store_integration.rs` (gated on `integration-azure`) for
# the one-off Create-Container setup request signed via our shared-key
# policy. `sha2` is similarly a runtime dep (the shared-key signing
# policy) so the integration tests can reuse the same crate version
# for byte-equality assertions on the multipart-download path.
# Keep line tables in release builds so dsymutil/objcopy can produce
# meaningful backtraces from a released binary. Release CI splits
# these into separate debug-symbol artefacts and strips the primary
# binary before shipping; local `cargo install` users get a slightly
# larger binary with line-level panic backtraces.
[]
= "line-tables-only"