static struct ref *get_ref_map(struct transport *transport, struct refspec *refs, int ref_count, int tags, int *autotags) { int i; struct ref *rm; struct ref *ref_map = NULL; struct ref **tail = &ref_map; const struct ref *remote_refs = transport_get_remote_refs(transport); if (ref_count || tags == TAGS_SET) { for (i = 0; i < ref_count; i++) { get_fetch_map(remote_refs, &refs[i], &tail, 0); if (refs[i].dst && refs[i].dst[0]) *autotags = 1; } /* Merge everything on the command line, but not --tags */ for (rm = ref_map; rm; rm = rm->next) rm->merge = 1; if (tags == TAGS_SET) get_fetch_map(remote_refs, tag_refspec, &tail, 0); } else { /* Use the defaults */ struct remote *remote = transport->remote; struct branch *branch = branch_get(NULL); int has_merge = branch_has_merge_config(branch); if (remote && (remote->fetch_refspec_nr || has_merge)) { for (i = 0; i < remote->fetch_refspec_nr; i++) { get_fetch_map(remote_refs, &remote->fetch[i], &tail, 0); if (remote->fetch[i].dst && remote->fetch[i].dst[0]) *autotags = 1; if (!i && !has_merge && ref_map && !remote->fetch[0].pattern) ref_map->merge = 1; } /* * if the remote we're fetching from is the same * as given in branch.<name>.remote, we add the * ref given in branch.<name>.merge, too. */ if (has_merge && !strcmp(branch->remote_name, remote->name)) add_merge_config(&ref_map, remote_refs, branch, &tail); } else { ref_map = get_remote_ref(remote_refs, "HEAD"); if (!ref_map) die("Couldn't find remote ref HEAD"); ref_map->merge = 1; tail = &ref_map->next; } } if (tags == TAGS_DEFAULT && *autotags) find_non_local_tags(transport, &ref_map, &tail); ref_remove_duplicates(ref_map); return ref_map; }
int get_fetch_map(const struct ref *remote_refs, const struct refspec *refspec, struct ref ***tail, int missing_ok) { struct ref *ref_map, **rmp; if (refspec->pattern) { ref_map = get_expanded_map(remote_refs, refspec); } else { 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 (rmp = &ref_map; *rmp; ) { if ((*rmp)->peer_ref) { int st = check_ref_format((*rmp)->peer_ref->name + 5); if (st && st != CHECK_REF_FORMAT_ONELEVEL) { struct ref *ignore = *rmp; error("* Ignoring funny ref '%s' locally", (*rmp)->peer_ref->name); *rmp = (*rmp)->next; free(ignore->peer_ref); free(ignore); continue; } } rmp = &((*rmp)->next); } if (ref_map) tail_link_ref(ref_map, tail); return 0; }