@@ -90,6 +90,23 @@ impl Index {
9090 ///
9191 /// This index object cannot be read/written to the filesystem, but may be
9292 /// used to perform in-memory index operations.
93+ ///
94+ /// <div class="warning">
95+ ///
96+ /// # SHA1-only limitation
97+ ///
98+ /// This method **always** creates a SHA1 index.
99+ ///
100+ /// In future releases, this will be removed entirely to avoid misuse.
101+ ///
102+ /// Consider these alternatives:
103+ ///
104+ /// * [`Index::with_object_format`] if an in-memory index is needed
105+ /// * [`Repository::index`] if you have repository context
106+ ///
107+ /// </div>
108+ #[ cfg( not( feature = "unstable-sha256" ) ) ]
109+ #[ deprecated = "this always creates a SHA1 index, consider using `Index::with_object_format`" ]
93110 pub fn new ( ) -> Result < Index , Error > {
94111 crate :: init ( ) ;
95112 let mut raw = ptr:: null_mut ( ) ;
@@ -99,6 +116,30 @@ impl Index {
99116 }
100117 }
101118
119+ /// Creates a new in-memory index with the specified object format.
120+ ///
121+ /// This index object cannot be read/written to the filesystem, but may be
122+ /// used to perform in-memory index operations.
123+ pub fn with_object_format ( format : crate :: ObjectFormat ) -> Result < Index , Error > {
124+ crate :: init ( ) ;
125+ let mut raw = ptr:: null_mut ( ) ;
126+ unsafe {
127+ #[ cfg( not( feature = "unstable-sha256" ) ) ]
128+ {
129+ let _ = format;
130+ try_call ! ( raw:: git_index_new( & mut raw) ) ;
131+ }
132+ #[ cfg( feature = "unstable-sha256" ) ]
133+ {
134+ let mut opts: raw:: git_index_options = std:: mem:: zeroed ( ) ;
135+ opts. version = raw:: GIT_INDEX_OPTIONS_VERSION ;
136+ opts. oid_type = format. raw ( ) ;
137+ try_call ! ( raw:: git_index_new_ext( & mut raw, & opts) ) ;
138+ }
139+ Ok ( Binding :: from_raw ( raw) )
140+ }
141+ }
142+
102143 /// Create a new bare Git index object as a memory representation of the Git
103144 /// index file in 'index_path', without a repository to back it.
104145 ///
@@ -107,13 +148,24 @@ impl Index {
107148 ///
108149 /// If you need an index attached to a repository, use the `index()` method
109150 /// on `Repository`.
110- pub fn open ( index_path : & Path ) -> Result < Index , Error > {
151+ pub fn open (
152+ index_path : & Path ,
153+ #[ cfg( feature = "unstable-sha256" ) ] format : crate :: ObjectFormat ,
154+ ) -> Result < Index , Error > {
111155 crate :: init ( ) ;
112156 let mut raw = ptr:: null_mut ( ) ;
113157 // Normal file path OK (does not need Windows conversion).
114158 let index_path = index_path. into_c_string ( ) ?;
115159 unsafe {
160+ #[ cfg( not( feature = "unstable-sha256" ) ) ]
116161 try_call ! ( raw:: git_index_open( & mut raw, index_path) ) ;
162+ #[ cfg( feature = "unstable-sha256" ) ]
163+ {
164+ let mut opts: raw:: git_index_options = std:: mem:: zeroed ( ) ;
165+ opts. version = raw:: GIT_INDEX_OPTIONS_VERSION ;
166+ opts. oid_type = format. raw ( ) ;
167+ try_call ! ( raw:: git_index_open_ext( & mut raw, index_path, & opts) ) ;
168+ }
117169 Ok ( Binding :: from_raw ( raw) )
118170 }
119171 }
@@ -846,11 +898,12 @@ mod tests {
846898 use std:: path:: Path ;
847899 use tempfile:: TempDir ;
848900
901+ use crate :: ObjectFormat ;
849902 use crate :: { ErrorCode , Index , IndexEntry , IndexTime , Oid , Repository , ResetType } ;
850903
851904 #[ test]
852905 fn smoke ( ) {
853- let mut index = Index :: new ( ) . unwrap ( ) ;
906+ let mut index = Index :: with_object_format ( ObjectFormat :: Sha1 ) . unwrap ( ) ;
854907 assert ! ( index. add_path( & Path :: new( "." ) ) . is_err( ) ) ;
855908 index. clear ( ) . unwrap ( ) ;
856909 assert_eq ! ( index. len( ) , 0 ) ;
@@ -867,7 +920,10 @@ mod tests {
867920 index. path( ) . map( |s| s. to_path_buf( ) ) ,
868921 Some ( repo. path( ) . join( "index" ) )
869922 ) ;
923+ #[ cfg( not( feature = "unstable-sha256" ) ) ]
870924 Index :: open ( & repo. path ( ) . join ( "index" ) ) . unwrap ( ) ;
925+ #[ cfg( feature = "unstable-sha256" ) ]
926+ Index :: open ( & repo. path ( ) . join ( "index" ) , ObjectFormat :: Sha1 ) . unwrap ( ) ;
871927
872928 index. clear ( ) . unwrap ( ) ;
873929 index. read ( true ) . unwrap ( ) ;
@@ -949,7 +1005,7 @@ mod tests {
9491005
9501006 #[ test]
9511007 fn add_then_read ( ) {
952- let mut index = Index :: new ( ) . unwrap ( ) ;
1008+ let mut index = Index :: with_object_format ( ObjectFormat :: Sha1 ) . unwrap ( ) ;
9531009 let mut e = entry ( ) ;
9541010 e. path = b"foobar" . to_vec ( ) ;
9551011 index. add ( & e) . unwrap ( ) ;
@@ -959,7 +1015,7 @@ mod tests {
9591015
9601016 #[ test]
9611017 fn add_then_find ( ) {
962- let mut index = Index :: new ( ) . unwrap ( ) ;
1018+ let mut index = Index :: with_object_format ( ObjectFormat :: Sha1 ) . unwrap ( ) ;
9631019 let mut e = entry ( ) ;
9641020 e. path = b"foo/bar" . to_vec ( ) ;
9651021 index. add ( & e) . unwrap ( ) ;
@@ -1004,10 +1060,38 @@ mod tests {
10041060 uid : 0 ,
10051061 gid : 0 ,
10061062 file_size : 0 ,
1063+ #[ cfg( not( feature = "unstable-sha256" ) ) ]
10071064 id : Oid :: from_bytes ( & [ 0 ; 20 ] ) . unwrap ( ) ,
1065+ #[ cfg( feature = "unstable-sha256" ) ]
1066+ id : Oid :: from_bytes ( & [ 0 ; 32 ] ) . unwrap ( ) ,
10081067 flags : 0 ,
10091068 flags_extended : 0 ,
10101069 path : Vec :: new ( ) ,
10111070 }
10121071 }
1072+
1073+ #[ test]
1074+ #[ cfg( feature = "unstable-sha256" ) ]
1075+ fn index_sha256 ( ) {
1076+ let ( _td, repo) = crate :: test:: repo_init_sha256 ( ) ;
1077+ let mut index = repo. index ( ) . unwrap ( ) ;
1078+
1079+ // Test opening with correct format
1080+ Index :: open ( & repo. path ( ) . join ( "index" ) , ObjectFormat :: Sha256 ) . unwrap ( ) ;
1081+
1082+ // Test basic operations with SHA256
1083+ index. clear ( ) . unwrap ( ) ;
1084+ index. read ( true ) . unwrap ( ) ;
1085+ index. write ( ) . unwrap ( ) ;
1086+ let tree_id = index. write_tree ( ) . unwrap ( ) ;
1087+
1088+ // Verify OID is 32 bytes (SHA256)
1089+ assert_eq ! ( tree_id. as_bytes( ) . len( ) , 32 ) ;
1090+ }
1091+
1092+ #[ test]
1093+ #[ cfg( feature = "unstable-sha256" ) ]
1094+ fn smooke_in_memory_index_sha256 ( ) {
1095+ let _index = Index :: with_object_format ( ObjectFormat :: Sha256 ) . unwrap ( ) ;
1096+ }
10131097}
0 commit comments