@@ -3282,3 +3282,105 @@ fn metadata_master_consistency() {
3282
3282
let bar_source = format ! ( "git+{}" , git_project. url( ) ) ;
3283
3283
p. cargo ( "metadata" ) . with_json ( & metadata ( & bar_source) ) . run ( ) ;
3284
3284
}
3285
+
3286
+ #[ cargo_test]
3287
+ fn git_with_force_push ( ) {
3288
+ // Checks that cargo can handle force-pushes to git repos.
3289
+ // This works by having a git dependency that is updated with an amend
3290
+ // commit, and tries with various forms (default branch, branch, rev,
3291
+ // tag).
3292
+ let main = |text| format ! ( r#"pub fn f() {{ println!("{}"); }}"# , text) ;
3293
+ let ( git_project, repo) = git:: new_repo ( "dep1" , |project| {
3294
+ project
3295
+ . file ( "Cargo.toml" , & basic_lib_manifest ( "dep1" ) )
3296
+ . file ( "src/lib.rs" , & main ( "one" ) )
3297
+ } ) ;
3298
+ let manifest = |extra| {
3299
+ format ! (
3300
+ r#"
3301
+ [project]
3302
+ name = "foo"
3303
+ version = "0.0.1"
3304
+ edition = "2018"
3305
+
3306
+ [dependencies]
3307
+ dep1 = {{ git = "{}"{} }}
3308
+ "# ,
3309
+ git_project. url( ) ,
3310
+ extra
3311
+ )
3312
+ } ;
3313
+ let p = project ( )
3314
+ . file ( "Cargo.toml" , & manifest ( "" ) )
3315
+ . file ( "src/main.rs" , "fn main() { dep1::f(); }" )
3316
+ . build ( ) ;
3317
+ // Download the original and make sure it is OK.
3318
+ p. cargo ( "build" ) . run ( ) ;
3319
+ p. rename_run ( "foo" , "foo1" ) . with_stdout ( "one" ) . run ( ) ;
3320
+
3321
+ let find_head = || t ! ( t!( repo. head( ) ) . peel_to_commit( ) ) ;
3322
+
3323
+ let amend_commit = |text| {
3324
+ // commit --amend a change that will require a force fetch.
3325
+ git_project. change_file ( "src/lib.rs" , & main ( text) ) ;
3326
+ git:: add ( & repo) ;
3327
+ let commit = find_head ( ) ;
3328
+ let tree_id = t ! ( t!( repo. index( ) ) . write_tree( ) ) ;
3329
+ t ! ( commit. amend(
3330
+ Some ( "HEAD" ) ,
3331
+ None ,
3332
+ None ,
3333
+ None ,
3334
+ None ,
3335
+ Some ( & t!( repo. find_tree( tree_id) ) )
3336
+ ) ) ;
3337
+ } ;
3338
+
3339
+ let mut rename_annoyance = 1 ;
3340
+
3341
+ let mut verify = |text : & str | {
3342
+ // Perform the fetch.
3343
+ p. cargo ( "update" ) . run ( ) ;
3344
+ p. cargo ( "build" ) . run ( ) ;
3345
+ rename_annoyance += 1 ;
3346
+ p. rename_run ( "foo" , & format ! ( "foo{}" , rename_annoyance) )
3347
+ . with_stdout ( text)
3348
+ . run ( ) ;
3349
+ } ;
3350
+
3351
+ amend_commit ( "two" ) ;
3352
+ verify ( "two" ) ;
3353
+
3354
+ // Try with a rev.
3355
+ let head1 = find_head ( ) . id ( ) . to_string ( ) ;
3356
+ let extra = format ! ( ", rev = \" {}\" " , head1) ;
3357
+ p. change_file ( "Cargo.toml" , & manifest ( & extra) ) ;
3358
+ verify ( "two" ) ;
3359
+ amend_commit ( "three" ) ;
3360
+ let head2 = find_head ( ) . id ( ) . to_string ( ) ;
3361
+ assert_ne ! ( & head1, & head2) ;
3362
+ let extra = format ! ( ", rev = \" {}\" " , head2) ;
3363
+ p. change_file ( "Cargo.toml" , & manifest ( & extra) ) ;
3364
+ verify ( "three" ) ;
3365
+
3366
+ // Try with a tag.
3367
+ git:: tag ( & repo, "my-tag" ) ;
3368
+ p. change_file ( "Cargo.toml" , & manifest ( ", tag = \" my-tag\" " ) ) ;
3369
+ verify ( "three" ) ;
3370
+ amend_commit ( "tag-three" ) ;
3371
+ let head = t ! ( t!( repo. head( ) ) . peel( git2:: ObjectType :: Commit ) ) ;
3372
+ t ! ( repo. tag( "my-tag" , & head, & t!( repo. signature( ) ) , "move tag" , true ) ) ;
3373
+ verify ( "tag-three" ) ;
3374
+
3375
+ // Try with a branch.
3376
+ let br = t ! ( repo. branch( "awesome-stuff" , & find_head( ) , false ) ) ;
3377
+ t ! ( repo. checkout_tree( & t!( br. get( ) . peel( git2:: ObjectType :: Tree ) ) , None ) ) ;
3378
+ t ! ( repo. set_head( "refs/heads/awesome-stuff" ) ) ;
3379
+ git_project. change_file ( "src/lib.rs" , & main ( "awesome-three" ) ) ;
3380
+ git:: add ( & repo) ;
3381
+ git:: commit ( & repo) ;
3382
+ p. change_file ( "Cargo.toml" , & manifest ( ", branch = \" awesome-stuff\" " ) ) ;
3383
+ verify ( "awesome-three" ) ;
3384
+ amend_commit ( "awesome-four" ) ;
3385
+ verify ( "awesome-four" ) ;
3386
+ }
0 commit comments