Skip to content

Commit 7407fec

Browse files
committed
change!: use gix-object::Find trait
1 parent a81514f commit 7407fec

File tree

3 files changed

+40
-49
lines changed

3 files changed

+40
-49
lines changed

gix-status/src/index_as_worktree/function.rs

+36-45
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use bstr::BStr;
66
use filetime::FileTime;
77
use gix_features::parallel::{in_parallel_if, Reduce};
88
use gix_filter::pipeline::convert::ToGitOutcome;
9+
use gix_object::FindExt;
910

1011
use crate::index_as_worktree::traits::read_data::Stream;
1112
use crate::index_as_worktree::{Conflict, EntryStatus};
@@ -31,6 +32,7 @@ use crate::{
3132
/// `should_interrupt` can be used to stop all processing.
3233
/// `filter` is used to convert worktree files back to their internal git representation. For this to be correct,
3334
/// [`Options::attributes`] must be configured as well.
35+
/// `objects` is used to access the version of an object in the object database for direct comparison.
3436
///
3537
/// **It's important to note that the `index` should have its [timestamp updated](gix_index::State::set_timestamp()) with a timestamp
3638
/// from just before making this call *if* [entries were updated](Outcome::entries_to_update)**
@@ -45,13 +47,13 @@ use crate::{
4547
/// Thus some care has to be taken to do the right thing when letting the index match the worktree by evaluating the changes observed
4648
/// by the `collector`.
4749
#[allow(clippy::too_many_arguments)]
48-
pub fn index_as_worktree<'index, T, U, Find, E1, E2>(
50+
pub fn index_as_worktree<'index, T, U, Find, E>(
4951
index: &'index gix_index::State,
5052
worktree: &Path,
5153
collector: &mut impl VisitEntry<'index, ContentChange = T, SubmoduleStatus = U>,
5254
compare: impl CompareBlobs<Output = T> + Send + Clone,
53-
submodule: impl SubmoduleStatus<Output = U, Error = E2> + Send + Clone,
54-
find: Find,
55+
submodule: impl SubmoduleStatus<Output = U, Error = E> + Send + Clone,
56+
objects: Find,
5557
progress: &mut dyn gix_features::progress::Progress,
5658
pathspec: impl Pathspec + Send + Clone,
5759
filter: gix_filter::Pipeline,
@@ -61,9 +63,8 @@ pub fn index_as_worktree<'index, T, U, Find, E1, E2>(
6163
where
6264
T: Send,
6365
U: Send,
64-
E1: std::error::Error + Send + Sync + 'static,
65-
E2: std::error::Error + Send + Sync + 'static,
66-
Find: for<'a> FnMut(&gix_hash::oid, &'a mut Vec<u8>) -> Result<gix_object::BlobRef<'a>, E1> + Send + Clone,
66+
E: std::error::Error + Send + Sync + 'static,
67+
Find: gix_object::Find + Send + Clone,
6768
{
6869
// the order is absolutely critical here we use the old timestamp to detect racy index entries
6970
// (modified at or after the last index update) during the index update we then set those
@@ -135,7 +136,7 @@ where
135136
},
136137
compare,
137138
submodule,
138-
find,
139+
objects,
139140
pathspec,
140141
)
141142
}
@@ -151,7 +152,7 @@ where
151152
),
152153
thread_limit,
153154
new_state,
154-
|(entry_offset, chunk_entries), (state, blobdiff, submdule, find, pathspec)| {
155+
|(entry_offset, chunk_entries), (state, blobdiff, submdule, objects, pathspec)| {
155156
let all_entries = index.entries();
156157
let mut out = Vec::new();
157158
let mut idx = 0;
@@ -181,7 +182,7 @@ where
181182
pathspec,
182183
blobdiff,
183184
submdule,
184-
find,
185+
objects,
185186
&mut idx,
186187
);
187188
idx += 1;
@@ -244,21 +245,20 @@ type StatusResult<'index, T, U> = Result<(&'index gix_index::Entry, usize, &'ind
244245

245246
impl<'index> State<'_, 'index> {
246247
#[allow(clippy::too_many_arguments)]
247-
fn process<T, U, Find, E1, E2>(
248+
fn process<T, U, Find, E>(
248249
&mut self,
249250
entries: &'index [gix_index::Entry],
250251
entry: &'index gix_index::Entry,
251252
entry_index: usize,
252253
pathspec: &mut impl Pathspec,
253254
diff: &mut impl CompareBlobs<Output = T>,
254-
submodule: &mut impl SubmoduleStatus<Output = U, Error = E2>,
255-
find: &mut Find,
255+
submodule: &mut impl SubmoduleStatus<Output = U, Error = E>,
256+
objects: &Find,
256257
outer_entry_index: &mut usize,
257258
) -> Option<StatusResult<'index, T, U>>
258259
where
259-
E1: std::error::Error + Send + Sync + 'static,
260-
E2: std::error::Error + Send + Sync + 'static,
261-
Find: for<'a> FnMut(&gix_hash::oid, &'a mut Vec<u8>) -> Result<gix_object::BlobRef<'a>, E1>,
260+
E: std::error::Error + Send + Sync + 'static,
261+
Find: gix_object::Find,
262262
{
263263
if entry.flags.intersects(
264264
gix_index::entry::Flags::UPTODATE
@@ -282,7 +282,7 @@ impl<'index> State<'_, 'index> {
282282
}),
283283
)
284284
} else {
285-
self.compute_status(entry, path, diff, submodule, find)
285+
self.compute_status(entry, path, diff, submodule, objects)
286286
};
287287
match status {
288288
Ok(None) => None,
@@ -330,18 +330,17 @@ impl<'index> State<'_, 'index> {
330330
/// which is a constant.
331331
///
332332
/// Adapted from [here](https://github.com/Byron/gitoxide/pull/805#discussion_r1164676777).
333-
fn compute_status<T, U, Find, E1, E2>(
333+
fn compute_status<T, U, Find, E>(
334334
&mut self,
335335
entry: &gix_index::Entry,
336336
rela_path: &BStr,
337337
diff: &mut impl CompareBlobs<Output = T>,
338-
submodule: &mut impl SubmoduleStatus<Output = U, Error = E2>,
339-
find: &mut Find,
338+
submodule: &mut impl SubmoduleStatus<Output = U, Error = E>,
339+
objects: &Find,
340340
) -> Result<Option<EntryStatus<T, U>>, Error>
341341
where
342-
E1: std::error::Error + Send + Sync + 'static,
343-
E2: std::error::Error + Send + Sync + 'static,
344-
Find: for<'a> FnMut(&gix_hash::oid, &'a mut Vec<u8>) -> Result<gix_object::BlobRef<'a>, E1>,
342+
E: std::error::Error + Send + Sync + 'static,
343+
Find: gix_object::Find,
345344
{
346345
let worktree_path = match self.path_stack.verified_path(gix_path::from_bstr(rela_path).as_ref()) {
347346
Ok(path) => path,
@@ -423,7 +422,7 @@ impl<'index> State<'_, 'index> {
423422
attr_stack: &mut self.attr_stack,
424423
options: self.options,
425424
id: &entry.id,
426-
find,
425+
objects,
427426
worktree_reads: self.worktree_reads,
428427
worktree_bytes: self.worktree_bytes,
429428
odb_reads: self.odb_reads,
@@ -478,10 +477,9 @@ impl<'index, T, U, C: VisitEntry<'index, ContentChange = T, SubmoduleStatus = U>
478477
}
479478
}
480479

481-
struct ReadDataImpl<'a, Find, E>
480+
struct ReadDataImpl<'a, Find>
482481
where
483-
E: std::error::Error + Send + Sync + 'static,
484-
Find: for<'b> FnMut(&gix_hash::oid, &'b mut Vec<u8>) -> Result<gix_object::BlobRef<'b>, E>,
482+
Find: gix_object::Find,
485483
{
486484
buf: &'a mut Vec<u8>,
487485
path: &'a Path,
@@ -492,29 +490,26 @@ where
492490
attr_stack: &'a mut gix_worktree::Stack,
493491
options: &'a Options,
494492
id: &'a gix_hash::oid,
495-
find: Find,
493+
objects: Find,
496494
worktree_bytes: &'a AtomicU64,
497495
worktree_reads: &'a AtomicUsize,
498496
odb_bytes: &'a AtomicU64,
499497
odb_reads: &'a AtomicUsize,
500498
}
501499

502-
impl<'a, Find, E> traits::ReadData<'a> for ReadDataImpl<'a, Find, E>
500+
impl<'a, Find> traits::ReadData<'a> for ReadDataImpl<'a, Find>
503501
where
504-
E: std::error::Error + Send + Sync + 'static,
505-
Find: for<'b> FnMut(&gix_hash::oid, &'b mut Vec<u8>) -> Result<gix_object::BlobRef<'b>, E>,
502+
Find: gix_object::Find,
506503
{
507-
fn read_blob(mut self) -> Result<&'a [u8], Error> {
508-
(self.find)(self.id, self.buf)
509-
.map(|b| {
510-
self.odb_reads.fetch_add(1, Ordering::Relaxed);
511-
self.odb_bytes.fetch_add(b.data.len() as u64, Ordering::Relaxed);
512-
b.data
513-
})
514-
.map_err(move |err| Error::Find(Box::new(err)))
504+
fn read_blob(self) -> Result<&'a [u8], Error> {
505+
Ok(self.objects.find_blob(self.id, self.buf).map(|b| {
506+
self.odb_reads.fetch_add(1, Ordering::Relaxed);
507+
self.odb_bytes.fetch_add(b.data.len() as u64, Ordering::Relaxed);
508+
b.data
509+
})?)
515510
}
516511

517-
fn stream_worktree_file(mut self) -> Result<Stream<'a>, Error> {
512+
fn stream_worktree_file(self) -> Result<Stream<'a>, Error> {
518513
self.buf.clear();
519514
// symlinks are only stored as actual symlinks if the FS supports it otherwise they are just
520515
// normal files with their content equal to the linked path (so can be read normally)
@@ -534,7 +529,7 @@ where
534529
}
535530
} else {
536531
self.buf.clear();
537-
let platform = self.attr_stack.at_entry(self.rela_path, Some(false), &mut self.find)?;
532+
let platform = self.attr_stack.at_entry(self.rela_path, Some(false), &self.objects)?;
538533
let file = std::fs::File::open(self.path)?;
539534
let out = self
540535
.filter
@@ -544,11 +539,7 @@ where
544539
&mut |_path, attrs| {
545540
platform.matching_attributes(attrs);
546541
},
547-
&mut |buf| {
548-
(self.find)(self.id, buf)
549-
.map(|_| Some(()))
550-
.map_err(|err| Box::new(err) as Box<dyn std::error::Error + Send + Sync + 'static>)
551-
},
542+
&mut |buf| Ok(self.objects.find_blob(self.id, buf).map(|_| Some(()))?),
552543
)
553544
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
554545
let len = match out {

gix-status/src/index_as_worktree/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub enum Error {
1111
#[error("IO error while writing blob or reading file metadata or changing filetype")]
1212
Io(#[from] std::io::Error),
1313
#[error("Failed to obtain blob from object database")]
14-
Find(#[source] Box<dyn std::error::Error + Send + Sync + 'static>),
14+
Find(#[from] gix_object::find::existing_object::Error),
1515
#[error("Could not determine status for submodule at '{rela_path}'")]
1616
SubmoduleStatus {
1717
rela_path: BString,

gix-status/tests/status/index_as_worktree.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ fn fixture_filtered_detailed(
102102
&mut recorder,
103103
FastEq,
104104
SubmoduleStatusMock { dirty: submodule_dirty },
105-
|_, _| Ok::<_, std::convert::Infallible>(gix_object::BlobRef { data: &[] }),
105+
gix_object::find::Never,
106106
&mut gix_features::progress::Discard,
107107
Pathspec(search),
108108
Default::default(),
@@ -615,7 +615,7 @@ fn racy_git() {
615615
&mut recorder,
616616
counter.clone(),
617617
SubmoduleStatusMock { dirty: false },
618-
|_, _| Err(std::io::Error::new(std::io::ErrorKind::Other, "no odb access expected")),
618+
gix_object::find::Never,
619619
&mut gix_features::progress::Discard,
620620
Pathspec::default(),
621621
Default::default(),
@@ -654,7 +654,7 @@ fn racy_git() {
654654
&mut recorder,
655655
counter,
656656
SubmoduleStatusMock { dirty: false },
657-
|_, _| Err(std::io::Error::new(std::io::ErrorKind::Other, "no odb access expected")),
657+
gix_object::find::Never,
658658
&mut gix_features::progress::Discard,
659659
Pathspec::default(),
660660
Default::default(),

0 commit comments

Comments
 (0)