Skip to content

Commit 59fd268

Browse files
committed
reproduce issue with 'too many packs' for slotmap
1 parent 8d84818 commit 59fd268

File tree

4 files changed

+68
-2
lines changed

4 files changed

+68
-2
lines changed

Cargo.lock

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ serde_derive = ">=1.0.185"
194194

195195
once_cell = "1.18.0"
196196
document-features = { version = "0.2.0", optional = true }
197+
198+
[dev-dependencies]
199+
tempfile = "3.15.0"
200+
197201
[profile.dev.package]
198202
insta.opt-level = 3
199203
similar.opt-level = 3

examples/fetch-stress.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use gix::interrupt::IS_INTERRUPTED;
2+
use gix::remote::Direction;
3+
4+
fn main() -> anyhow::Result<()> {
5+
let remote_dir = tempfile::tempdir()?;
6+
let remote_repo = gix::init_bare(remote_dir.path())?;
7+
create_empty_commit(&remote_repo)?;
8+
9+
let local_dir = tempfile::tempdir()?;
10+
let (local_repo, _) = gix::prepare_clone_bare(remote_repo.path(), local_dir.path())?
11+
.fetch_only(gix::progress::Discard, &gix::interrupt::IS_INTERRUPTED)?;
12+
13+
unsafe { gix::interrupt::init_handler(0, || gix::interrupt::trigger())? };
14+
15+
let remote = local_repo
16+
.branch_remote(
17+
local_repo.head_ref()?.expect("branch available").name().shorten(),
18+
Direction::Fetch,
19+
)
20+
.expect("remote is configured after clone")?;
21+
for round in 1.. {
22+
if gix::interrupt::is_triggered() {
23+
eprintln!("Round {round} aborted by user - cleaning up");
24+
break;
25+
}
26+
27+
eprintln!("Fetch number {round}…");
28+
create_empty_commit(&remote_repo)?;
29+
let out = remote
30+
.connect(Direction::Fetch)?
31+
.prepare_fetch(gix::progress::Discard, Default::default())?
32+
.receive(gix::progress::Discard, &IS_INTERRUPTED)?;
33+
for local_tracking_branch_name in out.ref_map.mappings.into_iter().filter_map(|m| m.local) {
34+
let r = local_repo.find_reference(&local_tracking_branch_name)?;
35+
r.id()
36+
.object()
37+
.expect("object should be present after fetching, triggering pack refreshes works");
38+
}
39+
}
40+
Ok(())
41+
}
42+
43+
fn create_empty_commit(repo: &gix::Repository) -> anyhow::Result<()> {
44+
let name = repo.head_name()?.expect("no detached head");
45+
repo.commit(
46+
name.as_bstr(),
47+
"empty",
48+
gix::hash::ObjectId::empty_tree(repo.object_hash()),
49+
repo.try_find_reference(name.as_ref())?.map(|r| r.id()),
50+
)?;
51+
Ok(())
52+
}

gix/src/commit.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//!
22
#![allow(clippy::empty_docs)]
33

4+
use std::convert::Infallible;
5+
46
/// An empty array of a type usable with the `gix::easy` API to help declaring no parents should be used
57
pub const NO_PARENT_IDS: [gix_hash::ObjectId; 0] = [];
68

@@ -22,6 +24,12 @@ pub enum Error {
2224
ReferenceEdit(#[from] crate::reference::edit::Error),
2325
}
2426

27+
impl From<std::convert::Infallible> for Error {
28+
fn from(_value: Infallible) -> Self {
29+
unreachable!("cannot be invoked")
30+
}
31+
}
32+
2533
///
2634
#[cfg(feature = "revision")]
2735
pub mod describe {

0 commit comments

Comments
 (0)