assert NOARG/NONEG behavior of parse-options callbacks
[gitweb.git] / builtin / fetch.c
index 6ce882ce824cd26273ffac73f96cf82b6bf591bb..354ed8bdef3a6511ddb580d97b75df60b77ac6ca 100644 (file)
@@ -98,6 +98,8 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
 
 static int parse_refmap_arg(const struct option *opt, const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+
        /*
         * "git fetch --refmap='' origin foo"
         * can be used to tell the command not to store anywhere
@@ -1186,6 +1188,7 @@ static int do_fetch(struct transport *transport,
        int retcode = 0;
        const struct ref *remote_refs;
        struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
+       int must_list_refs = 1;
 
        if (tags == TAGS_DEFAULT) {
                if (transport->remote->fetch_tags == 2)
@@ -1201,17 +1204,36 @@ static int do_fetch(struct transport *transport,
                        goto cleanup;
        }
 
-       if (rs->nr)
+       if (rs->nr) {
+               int i;
+
                refspec_ref_prefixes(rs, &ref_prefixes);
-       else if (transport->remote && transport->remote->fetch.nr)
+
+               /*
+                * We can avoid listing refs if all of them are exact
+                * OIDs
+                */
+               must_list_refs = 0;
+               for (i = 0; i < rs->nr; i++) {
+                       if (!rs->items[i].exact_sha1) {
+                               must_list_refs = 1;
+                               break;
+                       }
+               }
+       } else if (transport->remote && transport->remote->fetch.nr)
                refspec_ref_prefixes(&transport->remote->fetch, &ref_prefixes);
 
-       if (ref_prefixes.argc &&
-           (tags == TAGS_SET || (tags == TAGS_DEFAULT))) {
-               argv_array_push(&ref_prefixes, "refs/tags/");
+       if (tags == TAGS_SET || tags == TAGS_DEFAULT) {
+               must_list_refs = 1;
+               if (ref_prefixes.argc)
+                       argv_array_push(&ref_prefixes, "refs/tags/");
        }
 
-       remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
+       if (must_list_refs)
+               remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
+       else
+               remote_refs = NULL;
+
        argv_array_clear(&ref_prefixes);
 
        ref_map = get_ref_map(transport->remote, remote_refs, rs,