@@ -14,12 +14,15 @@ mod shallow {
14
14
mod blocking_and_async_io {
15
15
use std:: sync:: atomic:: AtomicBool ;
16
16
17
+ use gix:: interrupt:: IS_INTERRUPTED ;
17
18
use gix:: {
18
19
config:: tree:: Protocol ,
19
20
remote:: { fetch, fetch:: Status , Direction :: Fetch } ,
20
21
} ;
21
22
use gix_features:: progress;
23
+ use gix_odb:: store:: init:: Slots ;
22
24
use gix_protocol:: maybe_async;
25
+ use gix_testtools:: tempfile;
23
26
use gix_testtools:: tempfile:: TempDir ;
24
27
25
28
use crate :: {
@@ -85,6 +88,65 @@ mod blocking_and_async_io {
85
88
try_repo_rw ( name) . unwrap ( )
86
89
}
87
90
91
+ #[ test]
92
+ fn fetch_more_packs_than_can_be_handled ( ) -> gix_testtools:: Result {
93
+ fn create_empty_commit ( repo : & gix:: Repository ) -> anyhow:: Result < ( ) > {
94
+ let name = repo. head_name ( ) ?. expect ( "no detached head" ) ;
95
+ repo. commit (
96
+ name. as_bstr ( ) ,
97
+ "empty" ,
98
+ gix:: hash:: ObjectId :: empty_tree ( repo. object_hash ( ) ) ,
99
+ repo. try_find_reference ( name. as_ref ( ) ) ?. map ( |r| r. id ( ) ) ,
100
+ ) ?;
101
+ Ok ( ( ) )
102
+ }
103
+ let remote_dir = tempfile:: tempdir ( ) ?;
104
+ let remote_repo = gix:: init_bare ( remote_dir. path ( ) ) ?;
105
+ create_empty_commit ( & remote_repo) ?;
106
+
107
+ for max_packs in 1 ..=2 {
108
+ let local_dir = tempfile:: tempdir ( ) ?;
109
+ let ( local_repo, _) = gix:: clone:: PrepareFetch :: new (
110
+ remote_repo. path ( ) ,
111
+ local_dir. path ( ) ,
112
+ gix:: create:: Kind :: Bare ,
113
+ Default :: default ( ) ,
114
+ gix:: open:: Options :: isolated ( ) . object_store_slots ( Slots :: Given ( max_packs) ) ,
115
+ ) ?
116
+ . fetch_only ( gix:: progress:: Discard , & IS_INTERRUPTED ) ?;
117
+
118
+ let remote = local_repo
119
+ . branch_remote (
120
+ local_repo. head_ref ( ) ?. expect ( "branch available" ) . name ( ) . shorten ( ) ,
121
+ Fetch ,
122
+ )
123
+ . expect ( "remote is configured after clone" ) ?;
124
+ for round in 1 .. {
125
+ eprintln ! ( "Fetch number {round}…" ) ;
126
+ create_empty_commit ( & remote_repo) ?;
127
+ match remote
128
+ . connect ( Fetch ) ?
129
+ . prepare_fetch ( gix:: progress:: Discard , Default :: default ( ) ) ?
130
+ . receive ( gix:: progress:: Discard , & IS_INTERRUPTED )
131
+ {
132
+ Ok ( out) => {
133
+ for local_tracking_branch_name in out. ref_map . mappings . into_iter ( ) . filter_map ( |m| m. local ) {
134
+ let r = local_repo. find_reference ( & local_tracking_branch_name) ?;
135
+ r. id ( )
136
+ . object ( )
137
+ . expect ( "object should be present after fetching, triggering pack refreshes works" ) ;
138
+ }
139
+ }
140
+ Err ( err) => assert_eq ! (
141
+ err. to_string( ) ,
142
+ "It should indicate that the ODB is exhausted for now - we can't grow"
143
+ ) ,
144
+ }
145
+ }
146
+ }
147
+ Ok ( ( ) )
148
+ }
149
+
88
150
#[ test]
89
151
#[ cfg( feature = "blocking-network-client" ) ]
90
152
#[ allow( clippy:: result_large_err) ]
0 commit comments