contrib/hooks/post-receive-email: fix typo
[gitweb.git] / remote.c
index e7d735b98af231610c460c7aa34f12cdd6f37460..bec2ba1adbed02af54572be924dcfbb47bf9c423 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -380,6 +380,33 @@ int for_each_remote(each_remote_fn fn, void *priv)
        return result;
 }
 
+void ref_remove_duplicates(struct ref *ref_map)
+{
+       struct ref **posn;
+       struct ref *next;
+       for (; ref_map; ref_map = ref_map->next) {
+               if (!ref_map->peer_ref)
+                       continue;
+               posn = &ref_map->next;
+               while (*posn) {
+                       if ((*posn)->peer_ref &&
+                           !strcmp((*posn)->peer_ref->name,
+                                   ref_map->peer_ref->name)) {
+                               if (strcmp((*posn)->name, ref_map->name))
+                                       die("%s tracks both %s and %s",
+                                           ref_map->peer_ref->name,
+                                           (*posn)->name, ref_map->name);
+                               next = (*posn)->next;
+                               free((*posn)->peer_ref);
+                               free(*posn);
+                               *posn = next;
+                       } else {
+                               posn = &(*posn)->next;
+                       }
+               }
+       }
+}
+
 int remote_has_url(struct remote *remote, const char *url)
 {
        int i;
@@ -735,6 +762,8 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
                        hashcpy(dst_peer->new_sha1, src->new_sha1);
                }
                dst_peer->peer_ref = src;
+               if (pat)
+                       dst_peer->force = pat->force;
        free_name:
                free(dst_name);
        }
@@ -828,7 +857,7 @@ struct ref *get_remote_ref(struct ref *remote_refs, const char *name)
        struct ref *ref = find_ref_by_name_abbrev(remote_refs, name);
 
        if (!ref)
-               die("Couldn't find remote ref %s\n", name);
+               return NULL;
 
        return copy_ref(ref);
 }
@@ -860,20 +889,24 @@ static struct ref *get_local_ref(const char *name)
 
 int get_fetch_map(struct ref *remote_refs,
                  const struct refspec *refspec,
-                 struct ref ***tail)
+                 struct ref ***tail,
+                 int missing_ok)
 {
        struct ref *ref_map, *rm;
 
        if (refspec->pattern) {
                ref_map = get_expanded_map(remote_refs, refspec);
        } else {
-               ref_map = get_remote_ref(remote_refs,
-                                        refspec->src[0] ?
-                                        refspec->src : "HEAD");
-
-               ref_map->peer_ref = get_local_ref(refspec->dst);
-               if (ref_map->peer_ref && refspec->force)
-                       ref_map->peer_ref->force = 1;
+               const char *name = refspec->src[0] ? refspec->src : "HEAD";
+
+               ref_map = get_remote_ref(remote_refs, name);
+               if (!missing_ok && !ref_map)
+                       die("Couldn't find remote ref %s", name);
+               if (ref_map) {
+                       ref_map->peer_ref = get_local_ref(refspec->dst);
+                       if (ref_map->peer_ref && refspec->force)
+                               ref_map->peer_ref->force = 1;
+               }
        }
 
        for (rm = ref_map; rm; rm = rm->next) {
@@ -882,7 +915,8 @@ int get_fetch_map(struct ref *remote_refs,
                            rm->peer_ref->name);
        }
 
-       tail_link_ref(ref_map, tail);
+       if (ref_map)
+               tail_link_ref(ref_map, tail);
 
        return 0;
 }