@@ -54,7 +54,7 @@ pub trait SmartSubtransport: Send + 'static {
54
54
}
55
55
56
56
/// Actions that a smart transport can ask a subtransport to perform
57
- #[ derive( Copy , Clone ) ]
57
+ #[ derive( Copy , Clone , PartialEq ) ]
58
58
#[ allow( missing_docs) ]
59
59
pub enum Service {
60
60
UploadPackLs ,
@@ -87,6 +87,8 @@ struct TransportData {
87
87
#[ repr( C ) ]
88
88
struct RawSmartSubtransport {
89
89
raw : raw:: git_smart_subtransport ,
90
+ stream : Option < * mut raw:: git_smart_subtransport_stream > ,
91
+ rpc : bool ,
90
92
obj : Box < dyn SmartSubtransport > ,
91
93
}
92
94
@@ -142,6 +144,8 @@ impl Transport {
142
144
close : Some ( subtransport_close) ,
143
145
free : Some ( subtransport_free) ,
144
146
} ,
147
+ stream : None ,
148
+ rpc,
145
149
obj : Box :: new ( subtransport) ,
146
150
} ) ;
147
151
let mut defn = raw:: git_smart_subtransport_definition {
@@ -246,23 +250,36 @@ extern "C" fn subtransport_action(
246
250
raw:: GIT_SERVICE_RECEIVEPACK => Service :: ReceivePack ,
247
251
n => panic ! ( "unknown action: {}" , n) ,
248
252
} ;
249
- let transport = & mut * ( raw_transport as * mut RawSmartSubtransport ) ;
250
- let obj = match transport. obj . action ( url, action) {
251
- Ok ( s) => s,
252
- Err ( e) => {
253
- set_err ( & e) ;
254
- return e. raw_code ( ) as c_int ;
253
+
254
+ let mut transport = & mut * ( raw_transport as * mut RawSmartSubtransport ) ;
255
+ // Note: we only need to generate if rpc is on. Else, for receive-pack and upload-pack
256
+ // libgit2 reuses the stream generated for receive-pack-ls or upload-pack-ls.
257
+ let generate_stream =
258
+ transport. rpc || action == Service :: UploadPackLs || action == Service :: ReceivePackLs ;
259
+ if generate_stream {
260
+ let obj = match transport. obj . action ( url, action) {
261
+ Ok ( s) => s,
262
+ Err ( e) => {
263
+ set_err ( & e) ;
264
+ return e. raw_code ( ) as c_int ;
265
+ }
266
+ } ;
267
+ * stream = mem:: transmute ( Box :: new ( RawSmartSubtransportStream {
268
+ raw : raw:: git_smart_subtransport_stream {
269
+ subtransport : raw_transport,
270
+ read : Some ( stream_read) ,
271
+ write : Some ( stream_write) ,
272
+ free : Some ( stream_free) ,
273
+ } ,
274
+ obj : obj,
275
+ } ) ) ;
276
+ transport. stream = Some ( * stream) ;
277
+ } else {
278
+ if transport. stream . is_none ( ) {
279
+ return -1 ;
255
280
}
256
- } ;
257
- * stream = mem:: transmute ( Box :: new ( RawSmartSubtransportStream {
258
- raw : raw:: git_smart_subtransport_stream {
259
- subtransport : raw_transport,
260
- read : Some ( stream_read) ,
261
- write : Some ( stream_write) ,
262
- free : Some ( stream_free) ,
263
- } ,
264
- obj : obj,
265
- } ) ) ;
281
+ * stream = transport. stream . unwrap ( ) ;
282
+ }
266
283
0
267
284
} )
268
285
. unwrap_or ( -1 )
0 commit comments