@@ -1036,11 +1036,13 @@ int count_refspec_match(const char *pattern,
10361036 }
10371037 }
10381038 if (!matched ) {
1039- * matched_ref = matched_weak ;
1039+ if (matched_ref )
1040+ * matched_ref = matched_weak ;
10401041 return weak_match ;
10411042 }
10421043 else {
1043- * matched_ref = matched ;
1044+ if (matched_ref )
1045+ * matched_ref = matched ;
10441046 return match ;
10451047 }
10461048}
@@ -1060,18 +1062,25 @@ static struct ref *alloc_delete_ref(void)
10601062 return ref ;
10611063}
10621064
1063- static struct ref * try_explicit_object_name (const char * name )
1065+ static int try_explicit_object_name (const char * name ,
1066+ struct ref * * match )
10641067{
10651068 unsigned char sha1 [20 ];
1066- struct ref * ref ;
10671069
1068- if (!* name )
1069- return alloc_delete_ref ();
1070+ if (!* name ) {
1071+ if (match )
1072+ * match = alloc_delete_ref ();
1073+ return 0 ;
1074+ }
1075+
10701076 if (get_sha1 (name , sha1 ))
1071- return NULL ;
1072- ref = alloc_ref (name );
1073- hashcpy (ref -> new_sha1 , sha1 );
1074- return ref ;
1077+ return -1 ;
1078+
1079+ if (match ) {
1080+ * match = alloc_ref (name );
1081+ hashcpy ((* match )-> new_sha1 , sha1 );
1082+ }
1083+ return 0 ;
10751084}
10761085
10771086static struct ref * make_linked_ref (const char * name , struct ref * * * tail )
@@ -1101,12 +1110,37 @@ static char *guess_ref(const char *name, struct ref *peer)
11011110 return strbuf_detach (& buf , NULL );
11021111}
11031112
1113+ static int match_explicit_lhs (struct ref * src ,
1114+ struct refspec * rs ,
1115+ struct ref * * match ,
1116+ int * allocated_match )
1117+ {
1118+ switch (count_refspec_match (rs -> src , src , match )) {
1119+ case 1 :
1120+ if (allocated_match )
1121+ * allocated_match = 0 ;
1122+ return 0 ;
1123+ case 0 :
1124+ /* The source could be in the get_sha1() format
1125+ * not a reference name. :refs/other is a
1126+ * way to delete 'other' ref at the remote end.
1127+ */
1128+ if (try_explicit_object_name (rs -> src , match ) < 0 )
1129+ return error ("src refspec %s does not match any." , rs -> src );
1130+ if (allocated_match )
1131+ * allocated_match = 1 ;
1132+ return 0 ;
1133+ default :
1134+ return error ("src refspec %s matches more than one." , rs -> src );
1135+ }
1136+ }
1137+
11041138static int match_explicit (struct ref * src , struct ref * dst ,
11051139 struct ref * * * dst_tail ,
11061140 struct refspec * rs )
11071141{
11081142 struct ref * matched_src , * matched_dst ;
1109- int copy_src ;
1143+ int allocated_src ;
11101144
11111145 const char * dst_value = rs -> dst ;
11121146 char * dst_guess ;
@@ -1115,23 +1149,8 @@ static int match_explicit(struct ref *src, struct ref *dst,
11151149 return 0 ;
11161150
11171151 matched_src = matched_dst = NULL ;
1118- switch (count_refspec_match (rs -> src , src , & matched_src )) {
1119- case 1 :
1120- copy_src = 1 ;
1121- break ;
1122- case 0 :
1123- /* The source could be in the get_sha1() format
1124- * not a reference name. :refs/other is a
1125- * way to delete 'other' ref at the remote end.
1126- */
1127- matched_src = try_explicit_object_name (rs -> src );
1128- if (!matched_src )
1129- return error ("src refspec %s does not match any." , rs -> src );
1130- copy_src = 0 ;
1131- break ;
1132- default :
1133- return error ("src refspec %s matches more than one." , rs -> src );
1134- }
1152+ if (match_explicit_lhs (src , rs , & matched_src , & allocated_src ) < 0 )
1153+ return -1 ;
11351154
11361155 if (!dst_value ) {
11371156 unsigned char sha1 [20 ];
@@ -1176,7 +1195,9 @@ static int match_explicit(struct ref *src, struct ref *dst,
11761195 return error ("dst ref %s receives from more than one src." ,
11771196 matched_dst -> name );
11781197 else {
1179- matched_dst -> peer_ref = copy_src ? copy_ref (matched_src ) : matched_src ;
1198+ matched_dst -> peer_ref = allocated_src ?
1199+ matched_src :
1200+ copy_ref (matched_src );
11801201 matched_dst -> force = rs -> force ;
11811202 }
11821203 return 0 ;
@@ -1357,6 +1378,31 @@ static void prepare_ref_index(struct string_list *ref_index, struct ref *ref)
13571378 sort_string_list (ref_index );
13581379}
13591380
1381+ /*
1382+ * Given only the set of local refs, sanity-check the set of push
1383+ * refspecs. We can't catch all errors that match_push_refs would,
1384+ * but we can catch some errors early before even talking to the
1385+ * remote side.
1386+ */
1387+ int check_push_refs (struct ref * src , int nr_refspec , const char * * refspec_names )
1388+ {
1389+ struct refspec * refspec = parse_push_refspec (nr_refspec , refspec_names );
1390+ int ret = 0 ;
1391+ int i ;
1392+
1393+ for (i = 0 ; i < nr_refspec ; i ++ ) {
1394+ struct refspec * rs = refspec + i ;
1395+
1396+ if (rs -> pattern || rs -> matching )
1397+ continue ;
1398+
1399+ ret |= match_explicit_lhs (src , rs , NULL , NULL );
1400+ }
1401+
1402+ free_refspec (nr_refspec , refspec );
1403+ return ret ;
1404+ }
1405+
13601406/*
13611407 * Given the set of refs the local repository has, the set of refs the
13621408 * remote repository has, and the refspec used for push, determine
0 commit comments