pull: handle git-fetch's options as well
[gitweb.git] / fetch-pack.c
index 655ee642564e3ada5b782dd6fa2d2c799f340978..ff8a13b8c4d8ac18d87fa30ddfde27b07a742b4c 100644 (file)
@@ -43,7 +43,12 @@ static int marked;
 #define MAX_IN_VAIN 256
 
 static struct prio_queue rev_list = { compare_commits_by_commit_date };
-static int non_common_revs, multi_ack, use_sideband, allow_tip_sha1_in_want;
+static int non_common_revs, multi_ack, use_sideband;
+/* Allow specifying sha1 if it is a ref tip. */
+#define ALLOW_TIP_SHA1 01
+/* Allow request of a sha1 if it is reachable from a ref (possibly hidden ref). */
+#define ALLOW_REACHABLE_SHA1   02
+static unsigned int allow_unadvertised_object_request;
 
 static void rev_list_push(struct commit *commit, int mark)
 {
@@ -542,18 +547,22 @@ static void filter_refs(struct fetch_pack_args *args,
        }
 
        /* Append unmatched requests to the list */
-       if (allow_tip_sha1_in_want) {
+       if ((allow_unadvertised_object_request &
+           (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1))) {
                for (i = 0; i < nr_sought; i++) {
+                       unsigned char sha1[20];
+
                        ref = sought[i];
                        if (ref->matched)
                                continue;
-                       if (get_sha1_hex(ref->name, ref->old_sha1))
+                       if (get_sha1_hex(ref->name, sha1) ||
+                           ref->name[40] != '\0' ||
+                           hashcmp(sha1, ref->old_sha1))
                                continue;
 
                        ref->matched = 1;
-                       *newtail = ref;
-                       ref->next = NULL;
-                       newtail = &ref->next;
+                       *newtail = copy_ref(ref);
+                       newtail = &(*newtail)->next;
                }
        }
        *refs = newlist;
@@ -625,7 +634,6 @@ static int everything_local(struct fetch_pack_args *args,
 
        for (retval = 1, ref = *refs; ref ; ref = ref->next) {
                const unsigned char *remote = ref->old_sha1;
-               unsigned char local[20];
                struct object *o;
 
                o = lookup_object(remote);
@@ -638,8 +646,6 @@ static int everything_local(struct fetch_pack_args *args,
                                ref->name);
                        continue;
                }
-
-               hashcpy(ref->new_sha1, local);
                if (!args->verbose)
                        continue;
                fprintf(stderr,
@@ -821,7 +827,12 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
        if (server_supports("allow-tip-sha1-in-want")) {
                if (args->verbose)
                        fprintf(stderr, "Server supports allow-tip-sha1-in-want\n");
-               allow_tip_sha1_in_want = 1;
+               allow_unadvertised_object_request |= ALLOW_TIP_SHA1;
+       }
+       if (server_supports("allow-reachable-sha1-in-want")) {
+               if (args->verbose)
+                       fprintf(stderr, "Server supports allow-reachable-sha1-in-want\n");
+               allow_unadvertised_object_request |= ALLOW_REACHABLE_SHA1;
        }
        if (!server_supports("thin-pack"))
                args->use_thin_pack = 0;