@@ -1014,4 +1014,94 @@ mod tests {
1014
1014
remote. prune ( Some ( callbacks) ) . unwrap ( ) ;
1015
1015
assert_branch_count ( & repo, 0 ) ;
1016
1016
}
1017
+
1018
+ #[ test]
1019
+ fn push_negotiation ( ) {
1020
+ let ( _td, repo) = crate :: test:: repo_init ( ) ;
1021
+ let oid = repo. head ( ) . unwrap ( ) . target ( ) . unwrap ( ) ;
1022
+
1023
+ let td2 = TempDir :: new ( ) . unwrap ( ) ;
1024
+ let url = crate :: test:: path2url ( td2. path ( ) ) ;
1025
+ let mut opts = crate :: RepositoryInitOptions :: new ( ) ;
1026
+ opts. bare ( true ) ;
1027
+ opts. initial_head ( "main" ) ;
1028
+ let remote_repo = Repository :: init_opts ( td2. path ( ) , & opts) . unwrap ( ) ;
1029
+
1030
+ // reject pushing a branch
1031
+ let mut remote = repo. remote ( "origin" , & url) . unwrap ( ) ;
1032
+ let mut updated = false ;
1033
+ {
1034
+ let mut callbacks = RemoteCallbacks :: new ( ) ;
1035
+ callbacks. push_negotiation ( |updates| {
1036
+ assert ! ( !updated) ;
1037
+ updated = true ;
1038
+ assert_eq ! ( updates. len( ) , 1 ) ;
1039
+ let u = & updates[ 0 ] ;
1040
+ assert_eq ! ( u. src_refname( ) . unwrap( ) , "refs/heads/main" ) ;
1041
+ assert ! ( u. src( ) . is_zero( ) ) ;
1042
+ assert_eq ! ( u. dst_refname( ) . unwrap( ) , "refs/heads/main" ) ;
1043
+ assert_eq ! ( u. dst( ) , oid) ;
1044
+ Err ( crate :: Error :: from_str ( "rejected" ) )
1045
+ } ) ;
1046
+ let mut options = PushOptions :: new ( ) ;
1047
+ options. remote_callbacks ( callbacks) ;
1048
+ assert ! ( remote
1049
+ . push( & [ "refs/heads/main" ] , Some ( & mut options) )
1050
+ . is_err( ) ) ;
1051
+ }
1052
+ assert ! ( updated) ;
1053
+ assert_eq ! ( remote_repo. branches( None ) . unwrap( ) . count( ) , 0 ) ;
1054
+
1055
+ // push 3 branches
1056
+ let commit = repo. find_commit ( oid) . unwrap ( ) ;
1057
+ repo. branch ( "new1" , & commit, true ) . unwrap ( ) ;
1058
+ repo. branch ( "new2" , & commit, true ) . unwrap ( ) ;
1059
+ let mut flag = 0 ;
1060
+ updated = false ;
1061
+ {
1062
+ let mut callbacks = RemoteCallbacks :: new ( ) ;
1063
+ callbacks. push_negotiation ( |updates| {
1064
+ assert ! ( !updated) ;
1065
+ updated = true ;
1066
+ assert_eq ! ( updates. len( ) , 3 ) ;
1067
+ for u in updates {
1068
+ assert ! ( u. src( ) . is_zero( ) ) ;
1069
+ assert_eq ! ( u. dst( ) , oid) ;
1070
+ let src_name = u. src_refname ( ) . unwrap ( ) ;
1071
+ let dst_name = u. dst_refname ( ) . unwrap ( ) ;
1072
+ match src_name {
1073
+ "refs/heads/main" => {
1074
+ assert_eq ! ( dst_name, src_name) ;
1075
+ flag |= 1 ;
1076
+ }
1077
+ "refs/heads/new1" => {
1078
+ assert_eq ! ( dst_name, "refs/heads/dev1" ) ;
1079
+ flag |= 2 ;
1080
+ }
1081
+ "refs/heads/new2" => {
1082
+ assert_eq ! ( dst_name, "refs/heads/dev2" ) ;
1083
+ flag |= 4 ;
1084
+ }
1085
+ _ => panic ! ( "unexpected refname: {}" , src_name) ,
1086
+ }
1087
+ }
1088
+ Ok ( ( ) )
1089
+ } ) ;
1090
+ let mut options = PushOptions :: new ( ) ;
1091
+ options. remote_callbacks ( callbacks) ;
1092
+ remote
1093
+ . push (
1094
+ & [
1095
+ "refs/heads/main" ,
1096
+ "refs/heads/new1:refs/heads/dev1" ,
1097
+ "refs/heads/new2:refs/heads/dev2" ,
1098
+ ] ,
1099
+ Some ( & mut options) ,
1100
+ )
1101
+ . unwrap ( ) ;
1102
+ }
1103
+ assert ! ( updated) ;
1104
+ assert_eq ! ( flag, 7 ) ;
1105
+ assert_eq ! ( remote_repo. branches( None ) . unwrap( ) . count( ) , 3 ) ;
1106
+ }
1017
1107
}
0 commit comments