@@ -85,6 +85,74 @@ mod blocking_and_async_io {
85
85
try_repo_rw ( name) . unwrap ( )
86
86
}
87
87
88
+ #[ test]
89
+ #[ cfg( feature = "blocking-network-client" ) ]
90
+ fn fetch_more_packs_than_can_be_handled ( ) -> gix_testtools:: Result {
91
+ use gix:: config:: tree:: User ;
92
+ use gix:: interrupt:: IS_INTERRUPTED ;
93
+ use gix_odb:: store:: init:: Slots ;
94
+ use gix_testtools:: tempfile;
95
+ fn create_empty_commit ( repo : & gix:: Repository ) -> anyhow:: Result < ( ) > {
96
+ let name = repo. head_name ( ) ?. expect ( "no detached head" ) ;
97
+ repo. commit (
98
+ name. as_bstr ( ) ,
99
+ "empty" ,
100
+ gix:: hash:: ObjectId :: empty_tree ( repo. object_hash ( ) ) ,
101
+ repo. try_find_reference ( name. as_ref ( ) ) ?. map ( |r| r. id ( ) ) ,
102
+ ) ?;
103
+ Ok ( ( ) )
104
+ }
105
+ for max_packs in 1 ..=3 {
106
+ let remote_dir = tempfile:: tempdir ( ) ?;
107
+ let mut remote_repo = gix:: init_bare ( remote_dir. path ( ) ) ?;
108
+ {
109
+ let mut config = remote_repo. config_snapshot_mut ( ) ;
110
+ config. set_value ( & User :: NAME , "author" ) ?;
111
+ config
. set_value ( & User :: EMAIL , "[email protected] " ) ?
;
112
+ }
113
+ create_empty_commit ( & remote_repo) ?;
114
+
115
+ let local_dir = tempfile:: tempdir ( ) ?;
116
+ let ( local_repo, _) = gix:: clone:: PrepareFetch :: new (
117
+ remote_repo. path ( ) ,
118
+ local_dir. path ( ) ,
119
+ gix:: create:: Kind :: Bare ,
120
+ Default :: default ( ) ,
121
+ gix:: open:: Options :: isolated ( ) . object_store_slots ( Slots :: Given ( max_packs) ) ,
122
+ ) ?
123
+ . fetch_only ( gix:: progress:: Discard , & IS_INTERRUPTED ) ?;
124
+
125
+ let remote = local_repo
126
+ . branch_remote (
127
+ local_repo. head_ref ( ) ?. expect ( "branch available" ) . name ( ) . shorten ( ) ,
128
+ Fetch ,
129
+ )
130
+ . expect ( "remote is configured after clone" ) ?;
131
+ for _round_to_create_pack in 1 ..12 {
132
+ create_empty_commit ( & remote_repo) ?;
133
+ match remote
134
+ . connect ( Fetch ) ?
135
+ . prepare_fetch ( gix:: progress:: Discard , Default :: default ( ) ) ?
136
+ . receive ( gix:: progress:: Discard , & IS_INTERRUPTED )
137
+ {
138
+ Ok ( out) => {
139
+ for local_tracking_branch_name in out. ref_map . mappings . into_iter ( ) . filter_map ( |m| m. local ) {
140
+ let r = local_repo. find_reference ( & local_tracking_branch_name) ?;
141
+ r. id ( )
142
+ . object ( )
143
+ . expect ( "object should be present after fetching, triggering pack refreshes works" ) ;
144
+ local_repo. head_ref ( ) ?. unwrap ( ) . set_target_id ( r. id ( ) , "post fetch" ) ?;
145
+ }
146
+ }
147
+ Err ( err) => assert ! ( err
148
+ . to_string( )
149
+ . starts_with( "The slotmap turned out to be too small with " ) ) ,
150
+ }
151
+ }
152
+ }
153
+ Ok ( ( ) )
154
+ }
155
+
88
156
#[ test]
89
157
#[ cfg( feature = "blocking-network-client" ) ]
90
158
#[ allow( clippy:: result_large_err) ]
0 commit comments