Make automatic tag following and the --tags and --no-tags options work together with arbitrary refspecs: by default, tags will always be fetched automatically, the --tags option will fetch all tags (and only tags), and the --no-tags option will not fetch any tags. This allows to define how things are mapped and which things to fetch independently. Signed-off-by: Andres Gruenbacher <agruen@xxxxxxx> --- builtin/fetch.c | 37 ++++++++++++++++++++++++++----------- 1 files changed, 26 insertions(+), 11 deletions(-) diff --git a/builtin/fetch.c b/builtin/fetch.c index 8c01876..9265d76 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -147,6 +147,7 @@ static void add_default_tags(const struct ref *remote_refs, struct string_list *existing_refs, struct string_list *peeled_map, struct ref *ref_map, + int overwrite, struct ref ***tail) { struct string_list mapped_refs = { NULL, 0, 0, 0 }; @@ -180,12 +181,8 @@ static void add_default_tags(const struct ref *remote_refs, for (tag = &tags; *tag; ) { ref = *tag; peer_ref = ref->peer_ref; - if (!(string_list_has_string(existing_refs, peer_ref->name) || - string_list_has_string(&mapped_refs, ref->name))) { - struct string_list_item *item; - - item = string_list_lookup(ref->name, peeled_map); - ref->automatic = !(item && will_fetch(ref_map, item->util)); + if ((overwrite || !string_list_has_string(existing_refs, peer_ref->name)) && + !string_list_has_string(&mapped_refs, ref->name)) { string_list_insert(peer_ref->name, existing_refs); move_tag_to_tail(tag, tail); continue; @@ -218,6 +215,10 @@ int ref_is_automatic(const struct ref *ref) { return ref->automatic; } +int ref_is_tag(const struct ref *ref) { + return !prefixcmp(ref->name, "refs/tags/"); +} + static struct ref *get_ref_map(struct transport *transport, struct refspec *refs, int ref_count, int tags, struct string_list *peeled_map, @@ -231,7 +232,7 @@ static struct ref *get_ref_map(struct transport *transport, const struct ref *remote_refs = transport_get_remote_refs(transport); - if (ref_count || tags == TAGS_SET) { + if (ref_count) { for (i = 0; i < ref_count; i++) { get_fetch_map(remote_refs, &refs[i], &tail, 0); if (refs[i].dst && refs[i].dst[0]) @@ -240,8 +241,6 @@ static struct ref *get_ref_map(struct transport *transport, /* 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; @@ -287,8 +286,24 @@ static struct ref *get_ref_map(struct transport *transport, } } - if (tags == TAGS_DEFAULT && *autotags) - add_default_tags(remote_refs, &existing_refs, peeled_map, ref_map, &tail); + if (tags == TAGS_SET) { + add_default_tags(remote_refs, &existing_refs, peeled_map, ref_map, 1, &tail); + discard_refs(&ref_map, 1, ref_is_tag); + free_refs(rm); + } else if (tags == TAGS_DEFAULT && *autotags) { + add_default_tags(remote_refs, &existing_refs, peeled_map, ref_map, 0, &tail); + for (rm = ref_map; rm; rm = rm->next) { + struct string_list_item *item; + + if (prefixcmp(rm->name, "refs/tags/")) + continue; + item = string_list_lookup(rm->name, peeled_map); + rm->automatic = !(item && will_fetch(ref_map, item->util)); + } + } else { + discard_refs(&ref_map, 0, ref_is_tag); + free_refs(rm); + } string_list_clear(&existing_refs, 0); ref_remove_duplicates(ref_map); -- 1.7.0.2.273.gc2413 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html