X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=remote.c;h=b296d174043b5e5a11aceb9940ba6ba035e77678;hb=d82829b6128263951569221ca0c00dd143da055c;hp=4b06a11732cfc66747178d697f56ef39d7a1eb72;hpb=db70a04cbb343a58e7be93e7f581d049cf901b26;p=git.git diff --git a/remote.c b/remote.c index 4b06a1173..b296d1740 100644 --- a/remote.c +++ b/remote.c @@ -8,6 +8,8 @@ #include "tag.h" #include "string-list.h" +enum map_direction { FROM_SRC, FROM_DST }; + static struct refspec s_tag_refspec = { 0, 1, @@ -978,16 +980,20 @@ static void tail_link_ref(struct ref *ref, struct ref ***tail) *tail = &ref->next; } +static struct ref *alloc_delete_ref(void) +{ + struct ref *ref = alloc_ref("(delete)"); + hashclr(ref->new_sha1); + return ref; +} + static struct ref *try_explicit_object_name(const char *name) { unsigned char sha1[20]; struct ref *ref; - if (!*name) { - ref = alloc_ref("(delete)"); - hashclr(ref->new_sha1); - return ref; - } + if (!*name) + return alloc_delete_ref(); if (get_sha1(name, sha1)) return NULL; ref = alloc_ref(name); @@ -1111,7 +1117,7 @@ static int match_explicit_refs(struct ref *src, struct ref *dst, } static char *get_ref_match(const struct refspec *rs, int rs_nr, const struct ref *ref, - int send_mirror, const struct refspec **ret_pat) + int send_mirror, int direction, const struct refspec **ret_pat) { const struct refspec *pat; char *name; @@ -1126,7 +1132,12 @@ static char *get_ref_match(const struct refspec *rs, int rs_nr, const struct ref 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)) { + int match; + if (direction == FROM_SRC) + match = match_name_with_pattern(rs[i].src, ref->name, dst_side, &name); + else + match = match_name_with_pattern(dst_side, ref->name, rs[i].src, &name); + if (match) { matching_refs = i; break; } @@ -1173,6 +1184,7 @@ int match_push_refs(struct ref *src, struct ref **dst, struct refspec *rs; int send_all = flags & MATCH_REFS_ALL; int send_mirror = flags & MATCH_REFS_MIRROR; + int send_prune = flags & MATCH_REFS_PRUNE; int errs; static const char *default_refspec[] = { ":", NULL }; struct ref *ref, **dst_tail = tail_ref(dst); @@ -1193,7 +1205,7 @@ int match_push_refs(struct ref *src, struct ref **dst, if (ref->peer_ref) continue; - dst_name = get_ref_match(rs, nr_refspec, ref, send_mirror, &pat); + dst_name = get_ref_match(rs, nr_refspec, ref, send_mirror, FROM_SRC, &pat); if (!dst_name) continue; @@ -1220,6 +1232,23 @@ int match_push_refs(struct ref *src, struct ref **dst, free_name: free(dst_name); } + if (send_prune) { + /* check for missing refs on the remote */ + for (ref = *dst; ref; ref = ref->next) { + char *src_name; + + if (ref->peer_ref) + /* We're already sending something to this ref. */ + continue; + + src_name = get_ref_match(rs, nr_refspec, ref, send_mirror, FROM_DST, NULL); + if (src_name) { + if (!find_ref_by_name(src, src_name)) + ref->peer_ref = alloc_delete_ref(); + free(src_name); + } + } + } if (errs) return -1; return 0;