@@ -80,6 +80,25 @@ pub struct GitCheckout<'a> {
80
80
repo : git2:: Repository ,
81
81
}
82
82
83
+ /// See [`GitCheckout::reset`] for rationale on this type.
84
+ struct CheckoutGuard {
85
+ ok_file : PathBuf ,
86
+ }
87
+
88
+ impl CheckoutGuard {
89
+ #[ must_use]
90
+ fn guard ( path : & Path ) -> Self {
91
+ let ok_file = path. join ( CHECKOUT_READY_LOCK ) ;
92
+ let _ = paths:: remove_file ( & ok_file) ;
93
+ Self { ok_file }
94
+ }
95
+
96
+ fn mark_ok ( self ) -> CargoResult < ( ) > {
97
+ let _ = paths:: create ( self . ok_file ) ?;
98
+ Ok ( ( ) )
99
+ }
100
+ }
101
+
83
102
impl GitRemote {
84
103
/// Creates an instance for a remote repository URL.
85
104
pub fn new ( url : & Url ) -> GitRemote {
@@ -182,8 +201,9 @@ impl GitDatabase {
182
201
{
183
202
Some ( co) => co,
184
203
None => {
185
- let checkout = GitCheckout :: clone_into ( dest, self , rev, gctx) ?;
204
+ let ( checkout, guard ) = GitCheckout :: clone_into ( dest, self , rev, gctx) ?;
186
205
checkout. update_submodules ( gctx) ?;
206
+ guard. mark_ok ( ) ?;
187
207
checkout
188
208
}
189
209
} ;
@@ -284,7 +304,7 @@ impl<'a> GitCheckout<'a> {
284
304
database : & ' a GitDatabase ,
285
305
revision : git2:: Oid ,
286
306
gctx : & GlobalContext ,
287
- ) -> CargoResult < GitCheckout < ' a > > {
307
+ ) -> CargoResult < ( GitCheckout < ' a > , CheckoutGuard ) > {
288
308
let dirname = into. parent ( ) . unwrap ( ) ;
289
309
paths:: create_dir_all ( & dirname) ?;
290
310
if into. exists ( ) {
@@ -333,8 +353,8 @@ impl<'a> GitCheckout<'a> {
333
353
let repo = repo. unwrap ( ) ;
334
354
335
355
let checkout = GitCheckout :: new ( database, revision, repo) ;
336
- checkout. reset ( gctx) ?;
337
- Ok ( checkout)
356
+ let guard = checkout. reset ( gctx) ?;
357
+ Ok ( ( checkout, guard ) )
338
358
}
339
359
340
360
/// Checks if the `HEAD` of this checkout points to the expected revision.
@@ -359,12 +379,12 @@ impl<'a> GitCheckout<'a> {
359
379
/// To enable this we have a dummy file in our checkout, [`.cargo-ok`],
360
380
/// which if present means that the repo has been successfully reset and is
361
381
/// ready to go. Hence if we start to do a reset, we make sure this file
362
- /// *doesn't* exist, and then once we're done we create the file.
382
+ /// *doesn't* exist. The caller of [`reset`] has an option to perform additional operations
383
+ /// (e.g. submodule update) before marking the check-out as ready.
363
384
///
364
385
/// [`.cargo-ok`]: CHECKOUT_READY_LOCK
365
- fn reset ( & self , gctx : & GlobalContext ) -> CargoResult < ( ) > {
366
- let ok_file = self . path . join ( CHECKOUT_READY_LOCK ) ;
367
- let _ = paths:: remove_file ( & ok_file) ;
386
+ fn reset ( & self , gctx : & GlobalContext ) -> CargoResult < CheckoutGuard > {
387
+ let guard = CheckoutGuard :: guard ( & self . path ) ;
368
388
info ! ( "reset {} to {}" , self . repo. path( ) . display( ) , self . revision) ;
369
389
370
390
// Ensure libgit2 won't mess with newlines when we vendor.
@@ -374,8 +394,8 @@ impl<'a> GitCheckout<'a> {
374
394
375
395
let object = self . repo . find_object ( self . revision , None ) ?;
376
396
reset ( & self . repo , & object, gctx) ?;
377
- paths :: create ( ok_file ) ? ;
378
- Ok ( ( ) )
397
+
398
+ Ok ( guard )
379
399
}
380
400
381
401
/// Like `git submodule update --recursive` but for this git checkout.
0 commit comments