Code

remote: reorganize check_pattern_match()
[git.git] / remote.c
index af597b3a625824d05196c8ed4754fb4020026cc2..4b06a11732cfc66747178d697f56ef39d7a1eb72 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -1110,10 +1110,11 @@ static int match_explicit_refs(struct ref *src, struct ref *dst,
        return errs;
 }
 
-static const struct refspec *check_pattern_match(const struct refspec *rs,
-                                                int rs_nr,
-                                                const struct ref *src)
+static char *get_ref_match(const struct refspec *rs, int rs_nr, const struct ref *ref,
+               int send_mirror, const struct refspec **ret_pat)
 {
+       const struct refspec *pat;
+       char *name;
        int i;
        int matching_refs = -1;
        for (i = 0; i < rs_nr; i++) {
@@ -1123,14 +1124,31 @@ static const struct refspec *check_pattern_match(const struct refspec *rs,
                        continue;
                }
 
-               if (rs[i].pattern && match_name_with_pattern(rs[i].src, src->name,
-                                                            NULL, NULL))
-                       return rs + i;
+               if (rs[i].pattern) {
+                       const char *dst_side = rs[i].dst ? rs[i].dst : rs[i].src;
+                       if (match_name_with_pattern(rs[i].src, ref->name, dst_side, &name)) {
+                               matching_refs = i;
+                               break;
+                       }
+               }
        }
-       if (matching_refs != -1)
-               return rs + matching_refs;
-       else
+       if (matching_refs == -1)
                return NULL;
+
+       pat = rs + matching_refs;
+       if (pat->matching) {
+               /*
+                * "matching refs"; traditionally we pushed everything
+                * including refs outside refs/heads/ hierarchy, but
+                * that does not make much sense these days.
+                */
+               if (!send_mirror && prefixcmp(ref->name, "refs/heads/"))
+                       return NULL;
+               name = xstrdup(ref->name);
+       }
+       if (ret_pat)
+               *ret_pat = pat;
+       return name;
 }
 
 static struct ref **tail_ref(struct ref **head)
@@ -1157,7 +1175,7 @@ int match_push_refs(struct ref *src, struct ref **dst,
        int send_mirror = flags & MATCH_REFS_MIRROR;
        int errs;
        static const char *default_refspec[] = { ":", NULL };
-       struct ref **dst_tail = tail_ref(dst);
+       struct ref *ref, **dst_tail = tail_ref(dst);
 
        if (!nr_refspec) {
                nr_refspec = 1;
@@ -1167,39 +1185,23 @@ int match_push_refs(struct ref *src, struct ref **dst,
        errs = match_explicit_refs(src, *dst, &dst_tail, rs, nr_refspec);
 
        /* pick the remainder */
-       for ( ; src; src = src->next) {
+       for (ref = src; ref; ref = ref->next) {
                struct ref *dst_peer;
                const struct refspec *pat = NULL;
                char *dst_name;
-               if (src->peer_ref)
-                       continue;
 
-               pat = check_pattern_match(rs, nr_refspec, src);
-               if (!pat)
+               if (ref->peer_ref)
                        continue;
 
-               if (pat->matching) {
-                       /*
-                        * "matching refs"; traditionally we pushed everything
-                        * including refs outside refs/heads/ hierarchy, but
-                        * that does not make much sense these days.
-                        */
-                       if (!send_mirror && prefixcmp(src->name, "refs/heads/"))
-                               continue;
-                       dst_name = xstrdup(src->name);
+               dst_name = get_ref_match(rs, nr_refspec, ref, send_mirror, &pat);
+               if (!dst_name)
+                       continue;
 
-               } else {
-                       const char *dst_side = pat->dst ? pat->dst : pat->src;
-                       if (!match_name_with_pattern(pat->src, src->name,
-                                                    dst_side, &dst_name))
-                               die("Didn't think it matches any more");
-               }
                dst_peer = find_ref_by_name(*dst, dst_name);
                if (dst_peer) {
                        if (dst_peer->peer_ref)
                                /* We're already sending something to this ref. */
                                goto free_name;
-
                } else {
                        if (pat->matching && !(send_all || send_mirror))
                                /*
@@ -1211,9 +1213,9 @@ int match_push_refs(struct ref *src, struct ref **dst,
 
                        /* Create a new one and link it */
                        dst_peer = make_linked_ref(dst_name, &dst_tail);
-                       hashcpy(dst_peer->new_sha1, src->new_sha1);
+                       hashcpy(dst_peer->new_sha1, ref->new_sha1);
                }
-               dst_peer->peer_ref = copy_ref(src);
+               dst_peer->peer_ref = copy_ref(ref);
                dst_peer->force = pat->force;
        free_name:
                free(dst_name);