@@ -2,9 +2,34 @@ use crate::multi_index::File;
22use git_features:: progress:: Progress ;
33use std:: sync:: atomic:: AtomicBool ;
44
5+ ///
6+ pub mod integrity {
7+ /// Returned by [`multi_index::File::verify_integrity()`][crate::multi_index::File::verify_integrity()].
8+ #[ derive( thiserror:: Error , Debug ) ]
9+ #[ allow( missing_docs) ]
10+ pub enum Error {
11+ #[ error( transparent) ]
12+ MultiIndexChecksum ( #[ from] crate :: multi_index:: verify:: checksum:: Error ) ,
13+ #[ error( transparent) ]
14+ IndexIntegrity ( #[ from] crate :: index:: verify:: integrity:: Error ) ,
15+ #[ error( transparent) ]
16+ BundleInit ( #[ from] crate :: bundle:: init:: Error ) ,
17+ }
18+
19+ /// Returned by [`multi_index::File::verify_integrity()`][crate::multi_index::File::verify_integrity()].
20+ pub struct Outcome < P > {
21+ /// The computed checksum of the multi-index which matched the stored one.
22+ pub actual_index_checksum : git_hash:: ObjectId ,
23+ /// The for each entry in [`index_names()`][super::File::index_names()] provide the corresponding pack traversal outcome.
24+ pub pack_traverse_outcomes : Vec < crate :: index:: traverse:: Outcome > ,
25+ /// The provided progress instance.
26+ pub progress : Option < P > ,
27+ }
28+ }
29+
530///
631pub mod checksum {
7- /// Returned by [`index ::File::verify_checksum()`][crate::index ::File::verify_checksum()].
32+ /// Returned by [`multi_index ::File::verify_checksum()`][crate::multi_index ::File::verify_checksum()].
833 pub type Error = crate :: verify:: checksum:: Error ;
934}
1035
@@ -36,16 +61,88 @@ impl File {
3661 traversal : crate :: index:: traverse:: Algorithm ,
3762 make_pack_lookup_cache : impl Fn ( ) -> C + Send + Clone ,
3863 thread_limit : Option < usize > ,
39- progress : Option < P > ,
64+ mut progress : Option < P > ,
4065 should_interrupt : & AtomicBool ,
41- ) -> Result <
42- ( git_hash:: ObjectId , Option < crate :: index:: traverse:: Outcome > , Option < P > ) ,
43- crate :: index:: traverse:: Error < crate :: index:: verify:: integrity:: Error > ,
44- >
66+ ) -> Result < integrity:: Outcome < P > , crate :: index:: traverse:: Error < integrity:: Error > >
4567 where
4668 P : Progress ,
4769 C : crate :: cache:: DecodeEntry ,
4870 {
49- todo ! ( )
71+ let parent = self . path . parent ( ) . expect ( "must be in a directory" ) ;
72+
73+ let mut progress = git_features:: progress:: DoOrDiscard :: from ( progress) ;
74+ let actual_index_checksum = self
75+ . verify_checksum (
76+ progress. add_child ( format ! ( "checksum of '{}'" , self . path. display( ) ) ) ,
77+ should_interrupt,
78+ )
79+ . map_err ( integrity:: Error :: from)
80+ . map_err ( crate :: index:: traverse:: Error :: Processor ) ?;
81+ let mut progress = progress. into_inner ( ) ;
82+
83+ let mut pack_traverse_outcomes = Vec :: new ( ) ;
84+ for index_file_name in & self . index_names {
85+ let bundle = crate :: Bundle :: at ( parent. join ( index_file_name) , self . object_hash )
86+ . map_err ( integrity:: Error :: from)
87+ . map_err ( crate :: index:: traverse:: Error :: Processor ) ?;
88+ if let Some ( progress) = progress. as_mut ( ) {
89+ progress. set_name ( index_file_name. display ( ) . to_string ( ) ) ;
90+ }
91+ let crate :: bundle:: verify:: integrity:: Outcome {
92+ actual_index_checksum : _,
93+ pack_traverse_outcome,
94+ progress : used_progress,
95+ } = bundle
96+ . verify_integrity (
97+ verify_mode,
98+ traversal,
99+ make_pack_lookup_cache. clone ( ) ,
100+ thread_limit,
101+ progress,
102+ should_interrupt,
103+ )
104+ . map_err ( |err| {
105+ use crate :: index:: traverse:: Error :: * ;
106+ match err {
107+ Processor ( err) => Processor ( integrity:: Error :: IndexIntegrity ( err) ) ,
108+ VerifyChecksum ( err) => VerifyChecksum ( err) ,
109+ Tree ( err) => Tree ( err) ,
110+ TreeTraversal ( err) => TreeTraversal ( err) ,
111+ PackDecode { id, offset, source } => PackDecode { id, offset, source } ,
112+ PackMismatch { expected, actual } => PackMismatch { expected, actual } ,
113+ PackObjectMismatch {
114+ expected,
115+ actual,
116+ offset,
117+ kind,
118+ } => PackObjectMismatch {
119+ expected,
120+ actual,
121+ offset,
122+ kind,
123+ } ,
124+ Crc32Mismatch {
125+ expected,
126+ actual,
127+ offset,
128+ kind,
129+ } => Crc32Mismatch {
130+ expected,
131+ actual,
132+ offset,
133+ kind,
134+ } ,
135+ Interrupted => Interrupted ,
136+ }
137+ } ) ?;
138+ pack_traverse_outcomes. push ( pack_traverse_outcome) ;
139+ progress = used_progress;
140+ }
141+
142+ Ok ( integrity:: Outcome {
143+ actual_index_checksum,
144+ pack_traverse_outcomes,
145+ progress,
146+ } )
50147 }
51148}
0 commit comments