@@ -6,6 +6,7 @@ use bstr::BStr;
6
6
use filetime:: FileTime ;
7
7
use gix_features:: parallel:: { in_parallel_if, Reduce } ;
8
8
use gix_filter:: pipeline:: convert:: ToGitOutcome ;
9
+ use gix_object:: FindExt ;
9
10
10
11
use crate :: index_as_worktree:: traits:: read_data:: Stream ;
11
12
use crate :: index_as_worktree:: { Conflict , EntryStatus } ;
@@ -31,6 +32,7 @@ use crate::{
31
32
/// `should_interrupt` can be used to stop all processing.
32
33
/// `filter` is used to convert worktree files back to their internal git representation. For this to be correct,
33
34
/// [`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.
34
36
///
35
37
/// **It's important to note that the `index` should have its [timestamp updated](gix_index::State::set_timestamp()) with a timestamp
36
38
/// from just before making this call *if* [entries were updated](Outcome::entries_to_update)**
@@ -45,13 +47,13 @@ use crate::{
45
47
/// Thus some care has to be taken to do the right thing when letting the index match the worktree by evaluating the changes observed
46
48
/// by the `collector`.
47
49
#[ 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 > (
49
51
index : & ' index gix_index:: State ,
50
52
worktree : & Path ,
51
53
collector : & mut impl VisitEntry < ' index , ContentChange = T , SubmoduleStatus = U > ,
52
54
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 ,
55
57
progress : & mut dyn gix_features:: progress:: Progress ,
56
58
pathspec : impl Pathspec + Send + Clone ,
57
59
filter : gix_filter:: Pipeline ,
@@ -61,9 +63,8 @@ pub fn index_as_worktree<'index, T, U, Find, E1, E2>(
61
63
where
62
64
T : Send ,
63
65
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 ,
67
68
{
68
69
// the order is absolutely critical here we use the old timestamp to detect racy index entries
69
70
// (modified at or after the last index update) during the index update we then set those
@@ -135,7 +136,7 @@ where
135
136
} ,
136
137
compare,
137
138
submodule,
138
- find ,
139
+ objects ,
139
140
pathspec,
140
141
)
141
142
}
@@ -151,7 +152,7 @@ where
151
152
) ,
152
153
thread_limit,
153
154
new_state,
154
- |( entry_offset, chunk_entries) , ( state, blobdiff, submdule, find , pathspec) | {
155
+ |( entry_offset, chunk_entries) , ( state, blobdiff, submdule, objects , pathspec) | {
155
156
let all_entries = index. entries ( ) ;
156
157
let mut out = Vec :: new ( ) ;
157
158
let mut idx = 0 ;
@@ -181,7 +182,7 @@ where
181
182
pathspec,
182
183
blobdiff,
183
184
submdule,
184
- find ,
185
+ objects ,
185
186
& mut idx,
186
187
) ;
187
188
idx += 1 ;
@@ -244,21 +245,20 @@ type StatusResult<'index, T, U> = Result<(&'index gix_index::Entry, usize, &'ind
244
245
245
246
impl < ' index > State < ' _ , ' index > {
246
247
#[ allow( clippy:: too_many_arguments) ]
247
- fn process < T , U , Find , E1 , E2 > (
248
+ fn process < T , U , Find , E > (
248
249
& mut self ,
249
250
entries : & ' index [ gix_index:: Entry ] ,
250
251
entry : & ' index gix_index:: Entry ,
251
252
entry_index : usize ,
252
253
pathspec : & mut impl Pathspec ,
253
254
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 ,
256
257
outer_entry_index : & mut usize ,
257
258
) -> Option < StatusResult < ' index , T , U > >
258
259
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 ,
262
262
{
263
263
if entry. flags . intersects (
264
264
gix_index:: entry:: Flags :: UPTODATE
@@ -282,7 +282,7 @@ impl<'index> State<'_, 'index> {
282
282
} ) ,
283
283
)
284
284
} else {
285
- self . compute_status ( entry, path, diff, submodule, find )
285
+ self . compute_status ( entry, path, diff, submodule, objects )
286
286
} ;
287
287
match status {
288
288
Ok ( None ) => None ,
@@ -330,18 +330,17 @@ impl<'index> State<'_, 'index> {
330
330
/// which is a constant.
331
331
///
332
332
/// 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 > (
334
334
& mut self ,
335
335
entry : & gix_index:: Entry ,
336
336
rela_path : & BStr ,
337
337
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 ,
340
340
) -> Result < Option < EntryStatus < T , U > > , Error >
341
341
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 ,
345
344
{
346
345
let worktree_path = match self . path_stack . verified_path ( gix_path:: from_bstr ( rela_path) . as_ref ( ) ) {
347
346
Ok ( path) => path,
@@ -423,7 +422,7 @@ impl<'index> State<'_, 'index> {
423
422
attr_stack : & mut self . attr_stack ,
424
423
options : self . options ,
425
424
id : & entry. id ,
426
- find ,
425
+ objects ,
427
426
worktree_reads : self . worktree_reads ,
428
427
worktree_bytes : self . worktree_bytes ,
429
428
odb_reads : self . odb_reads ,
@@ -478,10 +477,9 @@ impl<'index, T, U, C: VisitEntry<'index, ContentChange = T, SubmoduleStatus = U>
478
477
}
479
478
}
480
479
481
- struct ReadDataImpl < ' a , Find , E >
480
+ struct ReadDataImpl < ' a , Find >
482
481
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 ,
485
483
{
486
484
buf : & ' a mut Vec < u8 > ,
487
485
path : & ' a Path ,
@@ -492,29 +490,26 @@ where
492
490
attr_stack : & ' a mut gix_worktree:: Stack ,
493
491
options : & ' a Options ,
494
492
id : & ' a gix_hash:: oid ,
495
- find : Find ,
493
+ objects : Find ,
496
494
worktree_bytes : & ' a AtomicU64 ,
497
495
worktree_reads : & ' a AtomicUsize ,
498
496
odb_bytes : & ' a AtomicU64 ,
499
497
odb_reads : & ' a AtomicUsize ,
500
498
}
501
499
502
- impl < ' a , Find , E > traits:: ReadData < ' a > for ReadDataImpl < ' a , Find , E >
500
+ impl < ' a , Find > traits:: ReadData < ' a > for ReadDataImpl < ' a , Find >
503
501
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 ,
506
503
{
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
+ } ) ?)
515
510
}
516
511
517
- fn stream_worktree_file ( mut self ) -> Result < Stream < ' a > , Error > {
512
+ fn stream_worktree_file ( self ) -> Result < Stream < ' a > , Error > {
518
513
self . buf . clear ( ) ;
519
514
// symlinks are only stored as actual symlinks if the FS supports it otherwise they are just
520
515
// normal files with their content equal to the linked path (so can be read normally)
@@ -534,7 +529,7 @@ where
534
529
}
535
530
} else {
536
531
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 ) ?;
538
533
let file = std:: fs:: File :: open ( self . path ) ?;
539
534
let out = self
540
535
. filter
@@ -544,11 +539,7 @@ where
544
539
& mut |_path, attrs| {
545
540
platform. matching_attributes ( attrs) ;
546
541
} ,
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 ( ( ) ) ) ?) ,
552
543
)
553
544
. map_err ( |err| io:: Error :: new ( io:: ErrorKind :: Other , err) ) ?;
554
545
let len = match out {
0 commit comments