match_explicit_lhs: allow a "verify only" mode

The match_explicit_lhs function has all of the logic necessary to verify the refspecs without actually doing any work. This patch lets callers pass a NULL "match" pointer to indicate they want a "verify only" operation. For the most part, we just need to avoid writing to the NULL pointer. However, we also have to refactor the try_explicit_object_name sub-function; it indicates success by allocating and returning a new ref. Instead, we give it an "out" parameter for the match and return a numeric status. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Mar 5, 2014 at 14:03 UTC 471fd3fe410ad95ef11270a865203482ce4bca7d
1 file changed +24 -14
remote.c
+24 -14
@@ -1031,11 +1031,13 @@ int count_refspec_match(const char *pattern,
1031 }
1032 }
1033 if (!matched) {
1034 - *matched_ref = matched_weak;
1034 + if (matched_ref)
1035 + *matched_ref = matched_weak;
1036 return weak_match;
1037 }
1038 else {
1038 - *matched_ref = matched;
1039 + if (matched_ref)
1040 + *matched_ref = matched;
1041 return match;
1042 }
1043 }
@@ -1055,18 +1057,25 @@ static struct ref *alloc_delete_ref(void)
1057 return ref;
1058 }
1059
1058 -static struct ref *try_explicit_object_name(const char *name)
1060 +static int try_explicit_object_name(const char *name,
1061 + struct ref **match)
1062 {
1063 unsigned char sha1[20];
1061 - struct ref *ref;
1064
1063 - if (!*name)
1064 - return alloc_delete_ref();
1065 + if (!*name) {
1066 + if (match)
1067 + *match = alloc_delete_ref();
1068 + return 0;
1069 + }
1070 +
1071 if (get_sha1(name, sha1))
1066 - return NULL;
1067 - ref = alloc_ref(name);
1068 - hashcpy(ref->new_sha1, sha1);
1069 - return ref;
1072 + return -1;
1073 +
1074 + if (match) {
1075 + *match = alloc_ref(name);
1076 + hashcpy((*match)->new_sha1, sha1);
1077 + }
1078 + return 0;
1079 }
1080
1081 static struct ref *make_linked_ref(const char *name, struct ref ***tail)
@@ -1103,17 +1112,18 @@ static int match_explicit_lhs(struct ref *src,
1112 {
1113 switch (count_refspec_match(rs->src, src, match)) {
1114 case 1:
1106 - *allocated_match = 0;
1115 + if (allocated_match)
1116 + *allocated_match = 0;
1117 return 0;
1118 case 0:
1119 /* The source could be in the get_sha1() format
1120 * not a reference name. :refs/other is a
1121 * way to delete 'other' ref at the remote end.
1122 */
1113 - *match = try_explicit_object_name(rs->src);
1114 - if (!*match)
1123 + if (try_explicit_object_name(rs->src, match) < 0)
1124 return error("src refspec %s does not match any.", rs->src);
1116 - *allocated_match = 1;
1125 + if (allocated_match)
1126 + *allocated_match = 1;
1127 return 0;
1128 default:
1129 return error("src refspec %s matches more than one.", rs->src);