@@ -293,18 +293,33 @@ impl Repository {
293293 . join ( Self :: relative_index_file ( name) )
294294 }
295295
296+ /// Returns the relative path to the crate index file.
297+ /// Does not perform conversion to lowercase.
298+ fn relative_index_file_helper ( name : & str ) -> Vec < & str > {
299+ match name. len ( ) {
300+ 1 => vec ! [ "1" , & name] ,
301+ 2 => vec ! [ "2" , & name] ,
302+ 3 => vec ! [ "3" , & name[ ..1 ] , & name] ,
303+ _ => vec ! [ & name[ 0 ..2 ] , & name[ 2 ..4 ] , & name] ,
304+ }
305+ }
306+
296307 /// Returns the relative path to the crate index file that corresponds to
297- /// the given crate name.
308+ /// the given crate name as a path .
298309 ///
299310 /// see <https://doc.rust-lang.org/cargo/reference/registries.html#index-format>
300311 pub fn relative_index_file ( name : & str ) -> PathBuf {
301312 let name = name. to_lowercase ( ) ;
302- match name. len ( ) {
303- 1 => Path :: new ( "1" ) . join ( & name) ,
304- 2 => Path :: new ( "2" ) . join ( & name) ,
305- 3 => Path :: new ( "3" ) . join ( & name[ ..1 ] ) . join ( & name) ,
306- _ => Path :: new ( & name[ 0 ..2 ] ) . join ( & name[ 2 ..4 ] ) . join ( & name) ,
307- }
313+ Self :: relative_index_file_helper ( & name) . iter ( ) . collect ( )
314+ }
315+
316+ /// Returns the relative path to the crate index file that corresponds to
317+ /// the given crate name as a string.
318+ ///
319+ /// see <https://doc.rust-lang.org/cargo/reference/registries.html#index-format>
320+ pub fn relative_index_file_as_string ( name : & str ) -> String {
321+ let name = name. to_lowercase ( ) ;
322+ Self :: relative_index_file_helper ( & name) . join ( "/" )
308323 }
309324
310325 /// Returns the [Object ID](git2::Oid) of the currently checked out commit
@@ -343,6 +358,32 @@ impl Repository {
343358 self . push ( "refs/heads/master" )
344359 }
345360
361+ /// Gets a list of files that have been modified since a given commit (or None for all files).
362+ pub fn get_files_modified_since ( & self , starting_commit : Option < & str > ) -> anyhow:: Result < Vec < PathBuf > > {
363+ let starting_commit = match starting_commit {
364+ Some ( starting_commit) => {
365+ let oid = git2:: Oid :: from_str ( starting_commit) . context ( "failed to parse commit into Oid" ) ?;
366+ let commit = self . repository . find_commit ( oid) . context ( "failed to find commit" ) ?;
367+ Some ( commit. as_object ( ) . peel_to_tree ( ) . context ( "failed to find tree for commit" ) ?)
368+ }
369+ None => None ,
370+ } ;
371+
372+ let head = self . repository . find_commit ( self . head_oid ( ) ?) ?. as_object ( ) . peel_to_tree ( ) ?;
373+ let diff = self . repository
374+ . diff_tree_to_tree ( starting_commit. as_ref ( ) , Some ( & head) , None )
375+ . context ( "failed to run diff" ) ?;
376+ let mut files = Vec :: new ( ) ;
377+ for delta in diff. deltas ( ) {
378+ let file = delta. new_file ( ) ;
379+ if file. exists ( ) {
380+ files. push ( file. path ( ) . unwrap ( ) . to_path_buf ( ) ) ;
381+ }
382+ }
383+
384+ Ok ( files)
385+ }
386+
346387 /// Push the current branch to the provided refname
347388 fn push ( & self , refspec : & str ) -> anyhow:: Result < ( ) > {
348389 let mut ref_status = Ok ( ( ) ) ;
0 commit comments