From 5761a4daf80e5febe469e32220b71dc3063fb4a6 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 4 Nov 2023 18:21:06 +0100 Subject: [PATCH] adapt to changes related to usage of `gix-object::Find` trait where necessary --- gitoxide-core/src/hours/mod.rs | 2 +- gitoxide-core/src/index/checkout.rs | 63 +++++++---- gitoxide-core/src/index/mod.rs | 2 +- gitoxide-core/src/pack/create.rs | 17 +-- gitoxide-core/src/pack/index.rs | 4 +- gitoxide-core/src/pack/receive.rs | 2 +- gitoxide-core/src/query/engine/update.rs | 101 +++++++++++++----- gitoxide-core/src/repository/status.rs | 6 +- gitoxide-core/src/repository/verify.rs | 6 +- gix-archive/tests/archive.rs | 8 +- gix-filter/tests/pipeline/convert_to_git.rs | 12 +-- .../tests/pipeline/convert_to_worktree.rs | 12 +-- gix-index/src/verify.rs | 5 - gix-index/tests/index/file/read.rs | 4 +- gix-index/tests/index/file/write.rs | 4 +- gix-index/tests/index/init.rs | 7 +- gix-negotiate/src/lib.rs | 2 +- gix-negotiate/tests/baseline/mod.rs | 9 +- gix-worktree-stream/tests/stream.rs | 6 +- gix/src/attribute_stack.rs | 7 +- gix/src/clone/checkout.rs | 18 ++-- gix/src/commit.rs | 8 +- gix/src/ext/object_id.rs | 10 +- gix/src/ext/tree.rs | 11 +- gix/src/filter.rs | 10 +- gix/src/object/tree/diff/for_each.rs | 3 +- gix/src/object/tree/traverse.rs | 9 +- gix/src/pathspec.rs | 7 +- gix/src/reference/iter.rs | 14 +-- gix/src/reference/mod.rs | 10 +- gix/src/remote/connection/fetch/negotiate.rs | 2 +- .../remote/connection/fetch/receive_pack.rs | 3 +- .../connection/fetch/update_refs/mod.rs | 4 +- gix/src/repository/graph.rs | 8 +- gix/src/repository/index.rs | 4 +- gix/src/repository/worktree.rs | 8 +- gix/src/revision/walk.rs | 2 +- gix/src/submodule/mod.rs | 5 +- 38 files changed, 192 insertions(+), 223 deletions(-) diff --git a/gitoxide-core/src/hours/mod.rs b/gitoxide-core/src/hours/mod.rs index 24db9003fba..0418ef1f01e 100644 --- a/gitoxide-core/src/hours/mod.rs +++ b/gitoxide-core/src/hours/mod.rs @@ -140,7 +140,7 @@ where let mut skipped_merge_commits = 0; const CHUNK_SIZE: usize = 50; let mut chunk = Vec::with_capacity(CHUNK_SIZE); - let mut commit_iter = commit_id.ancestors(|oid, buf| repo.objects.find_commit_iter(oid, buf)); + let mut commit_iter = commit_id.ancestors(&repo.objects); let mut is_shallow = false; while let Some(c) = commit_iter.next() { progress.inc(); diff --git a/gitoxide-core/src/index/checkout.rs b/gitoxide-core/src/index/checkout.rs index 9436422ddab..635422c6219 100644 --- a/gitoxide-core/src/index/checkout.rs +++ b/gitoxide-core/src/index/checkout.rs @@ -4,7 +4,8 @@ use std::{ }; use anyhow::bail; -use gix::{prelude::FindExt, worktree::state::checkout, NestedProgress, Progress}; +use gix::objs::find::Error; +use gix::{worktree::state::checkout, NestedProgress, Progress}; use crate::{ index, @@ -89,20 +90,9 @@ pub fn checkout_exclusive( Some(repo) => gix::worktree::state::checkout( &mut index, dest_directory, - { - let objects = repo.objects.into_arc()?; - move |oid, buf| { - objects.find_blob(oid, buf).ok(); - if empty_files { - // We always want to query the ODB here… - objects.find_blob(oid, buf)?; - buf.clear(); - // …but write nothing - Ok(gix::objs::BlobRef { data: buf }) - } else { - objects.find_blob(oid, buf) - } - } + EmptyOrDb { + empty_files, + db: repo.objects.into_arc()?, }, &files, &bytes, @@ -112,10 +102,7 @@ pub fn checkout_exclusive( None => gix::worktree::state::checkout( &mut index, dest_directory, - |_, buf| { - buf.clear(); - Ok(gix::objs::BlobRef { data: buf }) - }, + Empty, &files, &bytes, should_interrupt, @@ -184,3 +171,41 @@ pub fn checkout_exclusive( } Ok(()) } + +#[derive(Clone)] +struct EmptyOrDb { + empty_files: bool, + db: Find, +} + +impl gix::objs::Find for EmptyOrDb +where + Find: gix::objs::Find, +{ + fn try_find<'a>(&self, id: &gix::oid, buf: &'a mut Vec) -> Result>, Error> { + if self.empty_files { + // We always want to query the ODB here… + let Some(kind) = self.db.try_find(id, buf)?.map(|d| d.kind) else { + return Ok(None); + }; + buf.clear(); + // …but write nothing + Ok(Some(gix::objs::Data { kind, data: buf })) + } else { + self.db.try_find(id, buf) + } + } +} + +#[derive(Clone)] +struct Empty; + +impl gix::objs::Find for Empty { + fn try_find<'a>(&self, _id: &gix::oid, buffer: &'a mut Vec) -> Result>, Error> { + buffer.clear(); + Ok(Some(gix::objs::Data { + kind: gix::object::Kind::Blob, + data: buffer, + })) + } +} diff --git a/gitoxide-core/src/index/mod.rs b/gitoxide-core/src/index/mod.rs index 4b6b50b36ef..0457856dbd6 100644 --- a/gitoxide-core/src/index/mod.rs +++ b/gitoxide-core/src/index/mod.rs @@ -35,7 +35,7 @@ pub fn verify( let file = parse_file(index_path, object_hash)?; file.verify_integrity()?; file.verify_entries()?; - file.verify_extensions(false, gix::index::verify::extensions::no_find)?; + file.verify_extensions(false, gix::objs::find::Never)?; #[cfg_attr(not(feature = "serde"), allow(irrefutable_let_patterns))] if let crate::OutputFormat::Human = format { writeln!(out, "OK").ok(); diff --git a/gitoxide-core/src/pack/create.rs b/gitoxide-core/src/pack/create.rs index 6b3d3d65d8c..f8141e357d6 100644 --- a/gitoxide-core/src/pack/create.rs +++ b/gitoxide-core/src/pack/create.rs @@ -2,13 +2,7 @@ use std::{ffi::OsStr, io, path::Path, str::FromStr, time::Instant}; use anyhow::anyhow; use gix::{ - hash, - hash::ObjectId, - interrupt, - objs::bstr::ByteVec, - odb::{pack, pack::FindExt}, - parallel::InOrderIter, - prelude::Finalize, + hash, hash::ObjectId, interrupt, objs::bstr::ByteVec, odb::pack, parallel::InOrderIter, prelude::Finalize, progress, traverse, Count, NestedProgress, Progress, }; @@ -136,12 +130,9 @@ where .collect::, _>>()?; let handle = repo.objects.into_shared_arc().to_cache_arc(); let iter = Box::new( - traverse::commit::Ancestors::new(tips, traverse::commit::ancestors::State::default(), { - let handle = handle.clone(); - move |oid, buf| handle.find_commit_iter(oid, buf).map(|t| t.0) - }) - .map(|res| res.map_err(|err| Box::new(err) as Box<_>).map(|c| c.id)) - .inspect(move |_| progress.inc()), + traverse::commit::Ancestors::new(tips, traverse::commit::ancestors::State::default(), handle.clone()) + .map(|res| res.map_err(|err| Box::new(err) as Box<_>).map(|c| c.id)) + .inspect(move |_| progress.inc()), ); (handle, iter) } diff --git a/gitoxide-core/src/pack/index.rs b/gitoxide-core/src/pack/index.rs index 814f43d0697..7838f6337fa 100644 --- a/gitoxide-core/src/pack/index.rs +++ b/gitoxide-core/src/pack/index.rs @@ -95,7 +95,7 @@ pub fn from_pack( directory, &mut progress, ctx.should_interrupt, - None, + None::, options, ) } @@ -105,7 +105,7 @@ pub fn from_pack( directory, &mut progress, ctx.should_interrupt, - None, + None::, options, ), } diff --git a/gitoxide-core/src/pack/receive.rs b/gitoxide-core/src/pack/receive.rs index 95f549b1583..785267ea2c5 100644 --- a/gitoxide-core/src/pack/receive.rs +++ b/gitoxide-core/src/pack/receive.rs @@ -396,7 +396,7 @@ fn receive_pack_blocking( directory.take().as_deref(), &mut progress, &ctx.should_interrupt, - None, + None::, options, ) .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; diff --git a/gitoxide-core/src/query/engine/update.rs b/gitoxide-core/src/query/engine/update.rs index 8eb65865dba..0e8281cf950 100644 --- a/gitoxide-core/src/query/engine/update.rs +++ b/gitoxide-core/src/query/engine/update.rs @@ -1,3 +1,4 @@ +use std::cell::RefCell; use std::{ convert::Infallible, sync::atomic::{AtomicUsize, Ordering}, @@ -5,12 +6,12 @@ use std::{ }; use anyhow::{anyhow, bail}; +use gix::objs::find::Error; use gix::{ bstr::{BStr, BString, ByteSlice}, features::progress, object::tree::diff::rewrites::CopySource, parallel::{InOrderIter, SequenceId}, - prelude::FindExt, prelude::ObjectIdExt, Count, Progress, }; @@ -150,13 +151,18 @@ pub fn update( }); r }; + + #[derive(Clone)] struct Task { commit: gix::hash::ObjectId, parent_commit: Option, compute_stats: bool, } + + type Packet = (SequenceId, Vec); + let (tx_tree_ids, stat_threads) = { - let (tx, rx) = crossbeam_channel::unbounded::<(SequenceId, Vec)>(); + let (tx, rx) = crossbeam_channel::unbounded::(); let stat_workers = (0..threads) .map(|_| { scope.spawn({ @@ -304,46 +310,94 @@ pub fn update( }; drop(tx_stats); - const CHUNK_SIZE: usize = 50; - let mut chunk = Vec::with_capacity(CHUNK_SIZE); - let mut chunk_id: SequenceId = 0; - let commit_iter = gix::interrupt::Iter::new( - commit_id.ancestors(|oid, buf| -> Result<_, gix::object::find::existing::Error> { - let obj = repo.objects.find(oid, buf)?; - traverse_progress.inc(); - if known_commits.binary_search(&oid.to_owned()).is_err() { + #[derive(Clone)] + struct Db<'a, Find: Clone> { + inner: &'a Find, + progress: &'a dyn gix::progress::Count, + chunk: std::cell::RefCell>, + chunk_id: std::cell::RefCell, + chunk_size: usize, + tx: crossbeam_channel::Sender, + known_commits: &'a [gix::ObjectId], + } + + impl<'a, Find> Db<'a, Find> + where + Find: gix::prelude::Find + Clone, + { + fn new( + inner: &'a Find, + progress: &'a dyn gix::progress::Count, + chunk_size: usize, + tx: crossbeam_channel::Sender, + known_commits: &'a [gix::ObjectId], + ) -> Self { + Self { + inner, + progress, + known_commits, + tx, + chunk_size, + chunk_id: 0.into(), + chunk: RefCell::new(Vec::with_capacity(chunk_size)), + } + } + + fn send_last_chunk(self) { + self.tx.send((self.chunk_id.into_inner(), self.chunk.into_inner())).ok(); + } + } + + impl<'a, Find> gix::prelude::Find for Db<'a, Find> + where + Find: gix::prelude::Find + Clone, + { + fn try_find<'b>(&self, id: &gix::oid, buf: &'b mut Vec) -> Result>, Error> { + let obj = self.inner.try_find(id, buf)?; + let Some(obj) = obj else { return Ok(None) }; + if !obj.kind.is_commit() { + return Ok(None); + } + + self.progress.inc(); + if self.known_commits.binary_search(&id.to_owned()).is_err() { let res = { let mut parents = gix::objs::CommitRefIter::from_bytes(obj.data).parent_ids(); - let res = parents.next().map(|first_parent| (Some(first_parent), oid.to_owned())); + let res = parents.next().map(|first_parent| (Some(first_parent), id.to_owned())); match parents.next() { Some(_) => None, None => res, } }; if let Some((first_parent, commit)) = res { - chunk.push(Task { + self.chunk.borrow_mut().push(Task { parent_commit: first_parent, commit, compute_stats: true, }); } else { - chunk.push(Task { + self.chunk.borrow_mut().push(Task { parent_commit: None, - commit: oid.to_owned(), + commit: id.to_owned(), compute_stats: false, }); } - if chunk.len() == CHUNK_SIZE { - tx_tree_ids - .send((chunk_id, std::mem::replace(&mut chunk, Vec::with_capacity(CHUNK_SIZE)))) + if self.chunk.borrow().len() == self.chunk_size { + self.tx + .send(( + *self.chunk_id.borrow(), + std::mem::replace(&mut self.chunk.borrow_mut(), Vec::with_capacity(self.chunk_size)), + )) .ok(); - chunk_id += 1; + *self.chunk_id.borrow_mut() += 1; } } - Ok(gix::objs::CommitRefIter::from_bytes(obj.data)) - }), - || anyhow!("Cancelled by user"), - ); + Ok(Some(obj)) + } + } + + let db = Db::new(&repo.objects, &traverse_progress, 50, tx_tree_ids, &known_commits); + let commit_iter = gix::interrupt::Iter::new(commit_id.ancestors(&db), || anyhow!("Cancelled by user")); let mut commits = Vec::new(); for c in commit_iter { match c?.map(|c| c.id) { @@ -361,8 +415,7 @@ pub fn update( Err(err) => return Err(err.into()), }; } - tx_tree_ids.send((chunk_id, chunk)).ok(); - drop(tx_tree_ids); + db.send_last_chunk(); let saw_new_commits = !commits.is_empty(); if saw_new_commits { traverse_progress.show_throughput(start); diff --git a/gitoxide-core/src/repository/status.rs b/gitoxide-core/src/repository/status.rs index e7cbea20e54..cda8d1d5bd2 100644 --- a/gitoxide-core/src/repository/status.rs +++ b/gitoxide-core/src/repository/status.rs @@ -2,7 +2,6 @@ use crate::OutputFormat; use anyhow::{bail, Context}; use gix::bstr::{BStr, BString}; use gix::index::Entry; -use gix::prelude::FindExt; use gix::Progress; use gix_status::index_as_worktree::traits::FastEq; use gix_status::index_as_worktree::{Change, Conflict, EntryStatus}; @@ -80,10 +79,7 @@ pub fn show( &mut printer, FastEq, Submodule, - { - let odb = repo.objects.clone().into_arc()?; - move |id, buf| odb.find_blob(id, buf) - }, + repo.objects.clone().into_arc()?, &mut progress, pathspec.detach()?, repo.filter_pipeline(Some(gix::hash::ObjectId::empty_tree(repo.object_hash())))? diff --git a/gitoxide-core/src/repository/verify.rs b/gitoxide-core/src/repository/verify.rs index f337e13bf2f..98b987e4704 100644 --- a/gitoxide-core/src/repository/verify.rs +++ b/gitoxide-core/src/repository/verify.rs @@ -43,11 +43,7 @@ pub fn integrity( if let Some(index) = repo.worktree().map(|wt| wt.index()).transpose()? { index.verify_integrity()?; index.verify_entries()?; - index.verify_extensions(true, { - use gix::prelude::FindExt; - let objects = repo.objects; - move |oid, buf: &mut Vec| objects.find_tree_iter(oid, buf).ok() - })?; + index.verify_extensions(true, repo.objects)?; progress.info(format!("Index at '{}' OK", index.path().display())); } match output_statistics { diff --git a/gix-archive/tests/archive.rs b/gix-archive/tests/archive.rs index 190ed85ed17..3e43f755f9b 100644 --- a/gix-archive/tests/archive.rs +++ b/gix-archive/tests/archive.rs @@ -9,7 +9,6 @@ mod from_tree { use gix_archive::Format; use gix_attributes::glob::pattern::Case; use gix_object::tree::EntryMode; - use gix_object::FindExt; use gix_testtools::bstr::ByteSlice; use gix_worktree::stack::state::attributes::Source; @@ -230,14 +229,11 @@ mod from_tree { let (dir, head_tree, odb, mut cache) = basic()?; let mut stream = gix_worktree_stream::from_tree( head_tree, - { - let odb = odb.clone(); - move |id, buf| odb.find(id, buf) - }, + odb.clone(), noop_pipeline(), move |rela_path, mode, attrs| { cache - .at_entry(rela_path, mode.is_tree().into(), |id, buf| odb.find_blob(id, buf)) + .at_entry(rela_path, mode.is_tree().into(), &odb) .map(|entry| entry.matching_attributes(attrs)) .map(|_| ()) }, diff --git a/gix-filter/tests/pipeline/convert_to_git.rs b/gix-filter/tests/pipeline/convert_to_git.rs index cfa747e2bdd..491c6043d6a 100644 --- a/gix-filter/tests/pipeline/convert_to_git.rs +++ b/gix-filter/tests/pipeline/convert_to_git.rs @@ -53,9 +53,7 @@ fn all_stages_mean_streaming_is_impossible() -> gix_testtools::Result { Path::new("any.txt"), &mut |path, attrs| { cache - .at_entry(path, Some(false), |_oid, _buf| -> Result<_, std::convert::Infallible> { - unreachable!("index access disabled") - }) + .at_entry(path, Some(false), gix_object::find::Never) .expect("cannot fail") .matching_attributes(attrs); }, @@ -84,9 +82,7 @@ fn only_driver_means_streaming_is_possible() -> gix_testtools::Result { Path::new("subdir/doesnot/matter/any.txt"), &mut |path, attrs| { cache - .at_entry(path, Some(false), |_oid, _buf| -> Result<_, std::convert::Infallible> { - unreachable!("index access disabled") - }) + .at_entry(path, Some(false), gix_object::find::Never) .expect("cannot fail") .matching_attributes(attrs); }, @@ -116,9 +112,7 @@ fn no_filter_means_reader_is_returned_unchanged() -> gix_testtools::Result { Path::new("other.txt"), &mut |path, attrs| { cache - .at_entry(path, Some(false), |_oid, _buf| -> Result<_, std::convert::Infallible> { - unreachable!("index access disabled") - }) + .at_entry(path, Some(false), gix_object::find::Never) .expect("cannot fail") .matching_attributes(attrs); }, diff --git a/gix-filter/tests/pipeline/convert_to_worktree.rs b/gix-filter/tests/pipeline/convert_to_worktree.rs index bfc15cd3e2f..8798f5a22c7 100644 --- a/gix-filter/tests/pipeline/convert_to_worktree.rs +++ b/gix-filter/tests/pipeline/convert_to_worktree.rs @@ -21,9 +21,7 @@ fn all_stages() -> gix_testtools::Result { "any.txt".into(), &mut |path, attrs| { cache - .at_entry(path, Some(false), |_oid, _buf| -> Result<_, std::convert::Infallible> { - unreachable!("index access disabled") - }) + .at_entry(path, Some(false), gix_object::find::Never) .expect("cannot fail") .matching_attributes(attrs); }, @@ -56,9 +54,7 @@ fn all_stages_no_filter() -> gix_testtools::Result { "other.txt".into(), &mut |path, attrs| { cache - .at_entry(path, Some(false), |_oid, _buf| -> Result<_, std::convert::Infallible> { - unreachable!("index access disabled") - }) + .at_entry(path, Some(false), gix_object::find::Never) .expect("cannot fail") .matching_attributes(attrs); }, @@ -90,9 +86,7 @@ fn no_filter() -> gix_testtools::Result { "other.txt".into(), &mut |path, attrs| { cache - .at_entry(path, Some(false), |_oid, _buf| -> Result<_, std::convert::Infallible> { - unreachable!("index access disabled") - }) + .at_entry(path, Some(false), gix_object::find::Never) .expect("cannot fail") .matching_attributes(attrs); }, diff --git a/gix-index/src/verify.rs b/gix-index/src/verify.rs index 171428f565f..776f13b3c5f 100644 --- a/gix-index/src/verify.rs +++ b/gix-index/src/verify.rs @@ -25,11 +25,6 @@ pub mod entries { pub mod extensions { use crate::extension; - /// An implementation of a `find` function that never finds or returns any object, a no-op. - pub fn no_find<'a>(_: &gix_hash::oid, _: &'a mut Vec) -> Option> { - None - } - /// The error returned by [`State::verify_extensions()`][crate::State::verify_extensions()]. #[derive(Debug, thiserror::Error)] #[allow(missing_docs)] diff --git a/gix-index/tests/index/file/read.rs b/gix-index/tests/index/file/read.rs index ae2b7ace9dc..0745bd8e121 100644 --- a/gix-index/tests/index/file/read.rs +++ b/gix-index/tests/index/file/read.rs @@ -11,9 +11,7 @@ use crate::{hex_to_id, index::Fixture, loose_file_path}; fn verify(index: gix_index::File) -> gix_index::File { index.verify_integrity().unwrap(); index.verify_entries().unwrap(); - index - .verify_extensions(false, gix_index::verify::extensions::no_find) - .unwrap(); + index.verify_extensions(false, gix::objs::find::Never).unwrap(); index } diff --git a/gix-index/tests/index/file/write.rs b/gix-index/tests/index/file/write.rs index b3c01b21de6..a01963c8e31 100644 --- a/gix-index/tests/index/file/write.rs +++ b/gix-index/tests/index/file/write.rs @@ -1,5 +1,5 @@ use filetime::FileTime; -use gix_index::{entry, extension, verify::extensions::no_find, write, write::Options, State, Version}; +use gix_index::{entry, extension, write, write::Options, State, Version}; use crate::index::Fixture::*; @@ -228,7 +228,7 @@ fn compare_states_against_baseline( fn compare_states(actual: &State, actual_version: Version, expected: &State, options: Options, fixture: &str) { actual.verify_entries().expect("valid"); - actual.verify_extensions(false, no_find).expect("valid"); + actual.verify_extensions(false, gix::objs::find::Never).expect("valid"); assert_eq!( actual.version(), diff --git a/gix-index/tests/index/init.rs b/gix-index/tests/index/init.rs index f9aa3c5812f..22595526605 100644 --- a/gix-index/tests/index/init.rs +++ b/gix-index/tests/index/init.rs @@ -1,5 +1,4 @@ -use gix::prelude::FindExt; -use gix_index::{verify::extensions::no_find, State}; +use gix_index::State; use gix_testtools::scripted_fixture_read_only_standalone; #[test] @@ -18,7 +17,7 @@ fn from_tree() -> crate::Result { let tree_id = repo.head_commit()?.tree_id()?; let expected_state = repo.index()?; - let actual_state = State::from_tree(&tree_id, |oid, buf| repo.objects.find_tree_iter(oid, buf).ok())?; + let actual_state = State::from_tree(&tree_id, &repo.objects)?; compare_states(&actual_state, &expected_state, fixture) } @@ -35,7 +34,7 @@ fn new() { fn compare_states(actual: &State, expected: &State, fixture: &str) { actual.verify_entries().expect("valid"); - actual.verify_extensions(false, no_find).expect("valid"); + actual.verify_extensions(false, gix::objs::find::Never).expect("valid"); assert_eq!( actual.entries().len(), diff --git a/gix-negotiate/src/lib.rs b/gix-negotiate/src/lib.rs index 24b76cf690c..bb488816fb3 100644 --- a/gix-negotiate/src/lib.rs +++ b/gix-negotiate/src/lib.rs @@ -144,4 +144,4 @@ pub trait Negotiator { } /// An error that happened during any of the methods on a [`Negotiator`]. -pub type Error = gix_revwalk::graph::lookup::commit::Error; +pub type Error = gix_revwalk::graph::try_lookup_or_insert_default::Error; diff --git a/gix-negotiate/tests/baseline/mod.rs b/gix-negotiate/tests/baseline/mod.rs index 1ee86193b25..4a4620e98cc 100644 --- a/gix-negotiate/tests/baseline/mod.rs +++ b/gix-negotiate/tests/baseline/mod.rs @@ -59,14 +59,7 @@ fn run() -> crate::Result { let cache = use_cache .then(|| gix_commitgraph::at(store.store_ref().path().join("info")).ok()) .flatten(); - let mut graph = gix_revwalk::Graph::new( - |id, buf| { - store - .try_find(id, buf) - .map(|r| r.and_then(gix_object::Data::try_into_commit_iter)) - }, - cache, - ); + let mut graph = gix_revwalk::Graph::new(&store, cache); let mut negotiator = algo.into_negotiator(); if debug { eprintln!("ALGO {algo_name} CASE {case}"); diff --git a/gix-worktree-stream/tests/stream.rs b/gix-worktree-stream/tests/stream.rs index a09e3852636..d9452281757 100644 --- a/gix-worktree-stream/tests/stream.rs +++ b/gix-worktree-stream/tests/stream.rs @@ -13,8 +13,8 @@ mod from_tree { use gix_attributes::glob::pattern::Case; use gix_hash::oid; + use gix_object::Data; use gix_object::{bstr::ByteSlice, tree::EntryMode}; - use gix_object::{Data, FindExt}; use gix_testtools::once_cell::sync::Lazy; use gix_worktree::stack::state::attributes::Source; @@ -68,7 +68,7 @@ mod from_tree { mutating_pipeline(true), move |rela_path, mode, attrs| { cache - .at_entry(rela_path, mode.is_tree().into(), |id, buf| odb.find_blob(id, buf)) + .at_entry(rela_path, mode.is_tree().into(), &odb) .map(|entry| entry.matching_attributes(attrs)) .map(|_| ()) }, @@ -226,7 +226,7 @@ mod from_tree { mutating_pipeline(false), move |rela_path, mode, attrs| { cache - .at_entry(rela_path, mode.is_tree().into(), |id, buf| odb.find_blob(id, buf)) + .at_entry(rela_path, mode.is_tree().into(), &odb) .map(|entry| entry.matching_attributes(attrs)) .map(|_| ()) }, diff --git a/gix/src/attribute_stack.rs b/gix/src/attribute_stack.rs index 3d844e79fb7..d0495c9b21c 100644 --- a/gix/src/attribute_stack.rs +++ b/gix/src/attribute_stack.rs @@ -1,7 +1,6 @@ use crate::bstr::BStr; use crate::types::AttributeStack; use crate::Repository; -use gix_object::FindExt; use std::ops::{Deref, DerefMut}; /// Lifecycle @@ -46,8 +45,7 @@ impl<'repo> AttributeStack<'repo> { relative: impl AsRef, is_dir: Option, ) -> std::io::Result> { - self.inner - .at_path(relative, is_dir, |id, buf| self.repo.objects.find_blob(id, buf)) + self.inner.at_path(relative, is_dir, &self.repo.objects) } /// Obtain a platform for lookups from a repo-`relative` path, typically obtained from an index entry. `is_dir` should reflect @@ -63,7 +61,6 @@ impl<'repo> AttributeStack<'repo> { relative: impl Into<&'r BStr>, is_dir: Option, ) -> std::io::Result> { - self.inner - .at_entry(relative, is_dir, |id, buf| self.repo.objects.find_blob(id, buf)) + self.inner.at_entry(relative, is_dir, &self.repo.objects) } } diff --git a/gix/src/clone/checkout.rs b/gix/src/clone/checkout.rs index 9eaf2f4d9f2..84a3fedbddb 100644 --- a/gix/src/clone/checkout.rs +++ b/gix/src/clone/checkout.rs @@ -4,8 +4,6 @@ use crate::{clone::PrepareCheckout, Repository}; pub mod main_worktree { use std::{path::PathBuf, sync::atomic::AtomicBool}; - use gix_object::FindExt; - use crate::{clone::PrepareCheckout, Progress, Repository}; /// The error returned by [`PrepareCheckout::main_worktree()`]. @@ -26,7 +24,7 @@ pub mod main_worktree { #[error(transparent)] CheckoutOptions(#[from] crate::config::checkout_options::Error), #[error(transparent)] - IndexCheckout(#[from] gix_worktree_state::checkout::Error), + IndexCheckout(#[from] gix_worktree_state::checkout::Error), #[error("Failed to reopen object database as Arc (only if thread-safety wasn't compiled in)")] OpenArcOdb(#[from] std::io::Error), #[error("The HEAD reference could not be located")] @@ -96,11 +94,10 @@ pub mod main_worktree { )) } }; - let index = gix_index::State::from_tree(&root_tree, |oid, buf| repo.objects.find_tree_iter(oid, buf).ok()) - .map_err(|err| Error::IndexFromTree { - id: root_tree, - source: err, - })?; + let index = gix_index::State::from_tree(&root_tree, &repo.objects).map_err(|err| Error::IndexFromTree { + id: root_tree, + source: err, + })?; let mut index = gix_index::File::from_state(index, repo.index_path()); let mut opts = repo @@ -118,10 +115,7 @@ pub mod main_worktree { let outcome = gix_worktree_state::checkout( &mut index, workdir, - { - let objects = repo.objects.clone().into_arc()?; - move |oid, buf| objects.find_blob(oid, buf) - }, + repo.objects.clone().into_arc()?, &files, &bytes, should_interrupt, diff --git a/gix/src/commit.rs b/gix/src/commit.rs index 6cc2bf7d6b7..ce5dee4d6f7 100644 --- a/gix/src/commit.rs +++ b/gix/src/commit.rs @@ -28,7 +28,6 @@ pub mod describe { use gix_hash::ObjectId; use gix_hashtable::HashMap; - use gix_object::Find; use crate::{bstr::BStr, ext::ObjectIdExt, Repository}; @@ -199,12 +198,7 @@ pub mod describe { pub fn try_resolve(&self) -> Result>, Error> { // TODO: dirty suffix with respective dirty-detection let mut graph = gix_revwalk::Graph::new( - |id, buf| { - self.repo - .objects - .try_find(id, buf) - .map(|r| r.and_then(gix_object::Data::try_into_commit_iter)) - }, + &self.repo.objects, gix_commitgraph::Graph::from_info_dir(self.repo.objects.store_ref().path().join("info").as_ref()).ok(), ); let outcome = gix_revision::describe( diff --git a/gix/src/ext/object_id.rs b/gix/src/ext/object_id.rs index a4515022b9d..d4d9467664b 100644 --- a/gix/src/ext/object_id.rs +++ b/gix/src/ext/object_id.rs @@ -8,10 +8,9 @@ pub type AncestorsIter = Ancestors bool, ances /// An extension trait to add functionality to [`ObjectId`]s. pub trait ObjectIdExt: Sealed { /// Create an iterator over the ancestry of the commits reachable from this id, which must be a commit. - fn ancestors(self, find: Find) -> AncestorsIter + fn ancestors(self, find: Find) -> AncestorsIter where - Find: for<'a> FnMut(&gix_hash::oid, &'a mut Vec) -> Result, E>, - E: std::error::Error + Send + Sync + 'static; + Find: gix_object::Find; /// Infuse this object id `repo` access. fn attach(self, repo: &crate::Repository) -> crate::Id<'_>; @@ -20,10 +19,9 @@ pub trait ObjectIdExt: Sealed { impl Sealed for ObjectId {} impl ObjectIdExt for ObjectId { - fn ancestors(self, find: Find) -> AncestorsIter + fn ancestors(self, find: Find) -> AncestorsIter where - Find: for<'a> FnMut(&gix_hash::oid, &'a mut Vec) -> Result, E>, - E: std::error::Error + Send + Sync + 'static, + Find: gix_object::Find, { Ancestors::new(Some(self), ancestors::State::default(), find) } diff --git a/gix/src/ext/tree.rs b/gix/src/ext/tree.rs index 56b832b84f4..bf3c3e5ac6e 100644 --- a/gix/src/ext/tree.rs +++ b/gix/src/ext/tree.rs @@ -1,6 +1,5 @@ use std::borrow::BorrowMut; -use gix_hash::oid; use gix_object::TreeRefIter; use gix_traverse::tree::breadthfirst; @@ -16,11 +15,11 @@ pub trait TreeIterExt: Sealed { fn traverse( &self, state: StateMut, - find: Find, + objects: Find, delegate: &mut V, ) -> Result<(), breadthfirst::Error> where - Find: for<'a> FnMut(&oid, &'a mut Vec) -> Option>, + Find: gix_object::Find, StateMut: BorrowMut, V: gix_traverse::tree::Visit; } @@ -31,15 +30,15 @@ impl<'d> TreeIterExt for TreeRefIter<'d> { fn traverse( &self, state: StateMut, - find: Find, + objects: Find, delegate: &mut V, ) -> Result<(), breadthfirst::Error> where - Find: for<'a> FnMut(&oid, &'a mut Vec) -> Option>, + Find: gix_object::Find, StateMut: BorrowMut, V: gix_traverse::tree::Visit, { - breadthfirst(self.clone(), state, find, delegate) + breadthfirst(self.clone(), state, objects, delegate) } } diff --git a/gix/src/filter.rs b/gix/src/filter.rs index 0ce251bea51..c3fda49eb23 100644 --- a/gix/src/filter.rs +++ b/gix/src/filter.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; pub use gix_filter as plumbing; -use gix_object::{Find, FindExt}; +use gix_object::Find; use crate::{ bstr::BStr, @@ -141,9 +141,7 @@ impl<'repo> Pipeline<'repo> { where R: std::io::Read, { - let entry = self - .cache - .at_path(rela_path, Some(false), |id, buf| self.repo.objects.find_blob(id, buf))?; + let entry = self.cache.at_path(rela_path, Some(false), &self.repo.objects)?; Ok(self.inner.convert_to_git( src, rela_path, @@ -175,9 +173,7 @@ impl<'repo> Pipeline<'repo> { can_delay: gix_filter::driver::apply::Delay, ) -> Result, pipeline::convert_to_worktree::Error> { - let entry = self - .cache - .at_entry(rela_path, Some(false), |id, buf| self.repo.objects.find_blob(id, buf))?; + let entry = self.cache.at_entry(rela_path, Some(false), &self.repo.objects)?; Ok(self.inner.convert_to_worktree( src, rela_path, diff --git a/gix/src/object/tree/diff/for_each.rs b/gix/src/object/tree/diff/for_each.rs index 7877f089ea9..cd9c60f547d 100644 --- a/gix/src/object/tree/diff/for_each.rs +++ b/gix/src/object/tree/diff/for_each.rs @@ -1,4 +1,3 @@ -use gix_object::FindExt; use gix_object::TreeRefIter; use super::{change, Action, Change, Platform}; @@ -61,7 +60,7 @@ impl<'a, 'old> Platform<'a, 'old> { match gix_diff::tree::Changes::from(TreeRefIter::from_bytes(&self.lhs.data)).needed_to_obtain( TreeRefIter::from_bytes(&other.data), &mut self.state, - |oid, buf| repo.objects.find_tree_iter(oid, buf), + &repo.objects, &mut delegate, ) { Ok(()) => { diff --git a/gix/src/object/tree/traverse.rs b/gix/src/object/tree/traverse.rs index b6e0a515f93..f2f3ff817f8 100644 --- a/gix/src/object/tree/traverse.rs +++ b/gix/src/object/tree/traverse.rs @@ -1,5 +1,3 @@ -use gix_object::FindExt; - use crate::Tree; /// Traversal @@ -52,11 +50,6 @@ impl<'a, 'repo> Platform<'a, 'repo> { { let root = gix_object::TreeRefIter::from_bytes(&self.root.data); let state = gix_traverse::tree::breadthfirst::State::default(); - gix_traverse::tree::breadthfirst( - root, - state, - |oid, buf| self.root.repo.objects.find_tree_iter(oid, buf).ok(), - delegate, - ) + gix_traverse::tree::breadthfirst(root, state, &self.root.repo.objects, delegate) } } diff --git a/gix/src/pathspec.rs b/gix/src/pathspec.rs index d518cb098a3..a56ad1c321e 100644 --- a/gix/src/pathspec.rs +++ b/gix/src/pathspec.rs @@ -1,6 +1,5 @@ //! Pathspec plumbing and abstractions use gix_macros::momo; -use gix_object::FindExt; pub use gix_pathspec::*; use crate::{bstr::BStr, AttributeStack, Pathspec, PathspecDetached, Repository}; @@ -122,9 +121,7 @@ impl<'repo> Pathspec<'repo> { let stack = self.stack.as_mut().expect("initialized in advance"); stack .set_case(case) - .at_entry(relative_path, Some(is_dir), |id, buf| { - self.repo.objects.find_blob(id, buf) - }) + .at_entry(relative_path, Some(is_dir), &self.repo.objects) .map_or(false, |platform| platform.matching_attributes(out)) }, ) @@ -180,7 +177,7 @@ impl PathspecDetached { let stack = self.stack.as_mut().expect("initialized in advance"); stack .set_case(case) - .at_entry(relative_path, Some(is_dir), |id, buf| self.odb.find_blob(id, buf)) + .at_entry(relative_path, Some(is_dir), &self.odb) .map_or(false, |platform| platform.matching_attributes(out)) }, ) diff --git a/gix/src/reference/iter.rs b/gix/src/reference/iter.rs index a79a74743c7..604a8ac4b05 100644 --- a/gix/src/reference/iter.rs +++ b/gix/src/reference/iter.rs @@ -2,7 +2,6 @@ use std::path::Path; use gix_macros::momo; -use gix_odb::pack::Find; use gix_ref::file::ReferenceExt; /// A platform to create iterators over references. @@ -96,15 +95,10 @@ impl<'r> Iterator for Iter<'r> { res.map_err(|err| Box::new(err) as Box) .and_then(|mut r| { if self.peel { - let handle = &self.repo; - r.peel_to_id_in_place(&handle.refs, &mut |oid, buf| { - handle - .objects - .try_find(oid.as_ref(), buf) - .map(|po| po.map(|(o, _l)| (o.kind, o.data))) - }) - .map_err(|err| Box::new(err) as Box) - .map(|_| r) + let repo = &self.repo; + r.peel_to_id_in_place(&repo.refs, &repo.objects) + .map_err(|err| Box::new(err) as Box) + .map(|_| r) } else { Ok(r) } diff --git a/gix/src/reference/mod.rs b/gix/src/reference/mod.rs index 2d32f595d7a..5dd71b7dd4d 100644 --- a/gix/src/reference/mod.rs +++ b/gix/src/reference/mod.rs @@ -1,6 +1,5 @@ //! -use gix_odb::pack::Find; use gix_ref::file::ReferenceExt; use crate::{Id, Reference}; @@ -69,13 +68,8 @@ impl<'repo> Reference<'repo> { /// /// This is useful to learn where this reference is ultimately pointing to. pub fn peel_to_id_in_place(&mut self) -> Result, peel::Error> { - let repo = &self.repo; - let oid = self.inner.peel_to_id_in_place(&repo.refs, &mut |oid, buf| { - repo.objects - .try_find(&oid, buf) - .map(|po| po.map(|(o, _l)| (o.kind, o.data))) - })?; - Ok(Id::from_id(oid, repo)) + let oid = self.inner.peel_to_id_in_place(&&self.repo.refs, &self.repo.objects)?; + Ok(Id::from_id(oid, &self.repo)) } /// Similar to [`peel_to_id_in_place()`][Reference::peel_to_id_in_place()], but consumes this instance. diff --git a/gix/src/remote/connection/fetch/negotiate.rs b/gix/src/remote/connection/fetch/negotiate.rs index 92a141f6fa2..f5b6a031c4c 100644 --- a/gix/src/remote/connection/fetch/negotiate.rs +++ b/gix/src/remote/connection/fetch/negotiate.rs @@ -16,7 +16,7 @@ pub enum Error { #[error("We were unable to figure out what objects the server should send after {rounds} round(s)")] NegotiationFailed { rounds: usize }, #[error(transparent)] - LookupCommitInGraph(#[from] gix_revwalk::graph::lookup::commit::Error), + LookupCommitInGraph(#[from] gix_revwalk::graph::try_lookup_or_insert_default::Error), #[error(transparent)] InitRefsIterator(#[from] crate::reference::iter::init::Error), #[error(transparent)] diff --git a/gix/src/remote/connection/fetch/receive_pack.rs b/gix/src/remote/connection/fetch/receive_pack.rs index 8b68804da7d..26e71f4ca36 100644 --- a/gix/src/remote/connection/fetch/receive_pack.rs +++ b/gix/src/remote/connection/fetch/receive_pack.rs @@ -3,7 +3,6 @@ use std::{ sync::atomic::{AtomicBool, Ordering}, }; -use gix_object::FindExt; use gix_odb::store::RefreshMode; use gix_protocol::{ fetch::Arguments, @@ -278,7 +277,7 @@ where should_interrupt, Some(Box::new({ let repo = repo.clone(); - move |oid, buf| repo.objects.find(&oid, buf).ok() + repo.objects })), options, )?; diff --git a/gix/src/remote/connection/fetch/update_refs/mod.rs b/gix/src/remote/connection/fetch/update_refs/mod.rs index a9c65749bea..6f45727f95c 100644 --- a/gix/src/remote/connection/fetch/update_refs/mod.rs +++ b/gix/src/remote/connection/fetch/update_refs/mod.rs @@ -1,7 +1,7 @@ #![allow(clippy::result_large_err)] use std::{collections::BTreeMap, convert::TryInto, path::PathBuf}; -use gix_object::{Exists, Find, FindExt}; +use gix_object::{Exists, Find}; use gix_ref::{ transaction::{Change, LogChange, PreviousValue, RefEdit, RefLog}, Target, TargetRef, @@ -159,7 +159,7 @@ pub(crate) fn update( }).and_then(|local_commit_time| remote_id .to_owned() - .ancestors(|id, buf| repo.objects.find_commit_iter(id, buf)) + .ancestors(&repo.objects) .sorting( gix_traverse::commit::Sorting::ByCommitTimeNewestFirstCutoffOlderThan { seconds: local_commit_time diff --git a/gix/src/repository/graph.rs b/gix/src/repository/graph.rs index 61c78567b72..7d59589ed3d 100644 --- a/gix/src/repository/graph.rs +++ b/gix/src/repository/graph.rs @@ -1,5 +1,3 @@ -use gix_object::Find; - impl crate::Repository { /// Create a graph data-structure capable of accelerating graph traversals and storing state of type `T` with each commit /// it encountered. @@ -16,11 +14,7 @@ impl crate::Repository { /// of the commit walk. pub fn revision_graph(&self) -> gix_revwalk::Graph<'_, T> { gix_revwalk::Graph::new( - |id, buf| { - self.objects - .try_find(id, buf) - .map(|r| r.and_then(gix_object::Data::try_into_commit_iter)) - }, + &self.objects, self.config .may_use_commit_graph() .unwrap_or(true) diff --git a/gix/src/repository/index.rs b/gix/src/repository/index.rs index 068ef0befd5..85a1a664bb0 100644 --- a/gix/src/repository/index.rs +++ b/gix/src/repository/index.rs @@ -1,5 +1,3 @@ -use gix_object::FindExt; - use crate::{config::cache::util::ApplyLeniencyDefault, repository::IndexPersistedOrInMemory, worktree}; /// Index access @@ -113,7 +111,7 @@ impl crate::Repository { tree: &gix_hash::oid, ) -> Result { Ok(gix_index::File::from_state( - gix_index::State::from_tree(tree, |oid, buf| self.objects.find_tree_iter(oid, buf).ok())?, + gix_index::State::from_tree(tree, &self.objects)?, self.git_dir().join("index"), )) } diff --git a/gix/src/repository/worktree.rs b/gix/src/repository/worktree.rs index 51afa6d9ee0..9e6edeea751 100644 --- a/gix/src/repository/worktree.rs +++ b/gix/src/repository/worktree.rs @@ -62,7 +62,6 @@ impl crate::Repository { &self, id: impl Into, ) -> Result<(gix_worktree_stream::Stream, gix_index::File), crate::repository::worktree_stream::Error> { - use gix_object::FindExt; use gix_odb::HeaderExt; let id = id.into(); let header = self.objects.header(id)?; @@ -85,13 +84,10 @@ impl crate::Repository { let objects = self.objects.clone().into_arc().expect("TBD error handling"); let stream = gix_worktree_stream::from_tree( id, - { - let objects = objects.clone(); - move |id, buf| objects.find(id, buf) - }, + objects.clone(), pipeline, move |path, mode, attrs| -> std::io::Result<()> { - let entry = cache.at_entry(path, Some(mode.is_tree()), |id, buf| objects.find_blob(id, buf))?; + let entry = cache.at_entry(path, Some(mode.is_tree()), &objects)?; entry.matching_attributes(attrs); Ok(()) }, diff --git a/gix/src/revision/walk.rs b/gix/src/revision/walk.rs index 7537f3cda32..19d15d569ab 100644 --- a/gix/src/revision/walk.rs +++ b/gix/src/revision/walk.rs @@ -169,7 +169,7 @@ impl<'repo> Platform<'repo> { gix_traverse::commit::Ancestors::filtered( tips, gix_traverse::commit::ancestors::State::default(), - move |oid, buf| repo.objects.find_commit_iter(oid, buf), + &repo.objects, { // Note that specific shallow handling for commit-graphs isn't needed as these contain // all information there is, and exclude shallow parents to be structurally consistent. diff --git a/gix/src/submodule/mod.rs b/gix/src/submodule/mod.rs index bb29e1b4421..14a054e8b49 100644 --- a/gix/src/submodule/mod.rs +++ b/gix/src/submodule/mod.rs @@ -7,7 +7,6 @@ use std::{ path::PathBuf, }; -use gix_object::FindExt; pub use gix_submodule::*; use crate::{bstr::BStr, repository::IndexPersistedOrInMemory, Repository, Submodule}; @@ -147,9 +146,7 @@ impl<'repo> Submodule<'repo> { &mut |relative_path, case, is_dir, out| { attributes .set_case(case) - .at_entry(relative_path, Some(is_dir), |id, buf| { - self.state.repo.objects.find_blob(id, buf) - }) + .at_entry(relative_path, Some(is_dir), &self.state.repo.objects) .map_or(false, |platform| platform.matching_attributes(out)) } })?;