Merge branch 'bw/protocol-v2'
[gitweb.git] / fetch-pack.c
index 8fb67b0e31e82ed5f0daeb1dec10ca7a04e4321f..1ab0b2d37e78456db4e54bd83ade79299a71d821 100644 (file)
@@ -35,6 +35,7 @@ static int agent_supported;
 static int server_supports_filtering;
 static struct lock_file shallow_lock;
 static const char *alternate_shallow_file;
+static char *negotiation_algorithm;
 
 /* Remember to update object flag allocation in object.h */
 #define COMPLETE       (1U << 0)
@@ -78,7 +79,7 @@ static void cache_one_alternate(const char *refname,
                                void *vcache)
 {
        struct alternate_object_cache *cache = vcache;
-       struct object *obj = parse_object(oid);
+       struct object *obj = parse_object(the_repository, oid);
 
        if (!obj || (obj->flags & ALTERNATE))
                return;
@@ -109,7 +110,9 @@ static int rev_list_insert_ref(struct fetch_negotiator *negotiator,
                               const char *refname,
                               const struct object_id *oid)
 {
-       struct object *o = deref_tag(parse_object(oid), refname, 0);
+       struct object *o = deref_tag(the_repository,
+                                    parse_object(the_repository, oid),
+                                    refname, 0);
 
        if (o && o->type == OBJ_COMMIT)
                negotiator->add_tip(negotiator, (struct commit *)o);
@@ -215,6 +218,22 @@ static int next_flush(int stateless_rpc, int count)
        return count;
 }
 
+static void mark_tips(struct fetch_negotiator *negotiator,
+                     const struct oid_array *negotiation_tips)
+{
+       int i;
+
+       if (!negotiation_tips) {
+               for_each_ref(rev_list_insert_ref_oid, negotiator);
+               return;
+       }
+
+       for (i = 0; i < negotiation_tips->nr; i++)
+               rev_list_insert_ref(negotiator, NULL,
+                                   &negotiation_tips->oid[i]);
+       return;
+}
+
 static int find_common(struct fetch_negotiator *negotiator,
                       struct fetch_pack_args *args,
                       int fd[2], struct object_id *result_oid,
@@ -232,7 +251,7 @@ static int find_common(struct fetch_negotiator *negotiator,
        if (args->stateless_rpc && multi_ack == 1)
                die(_("--stateless-rpc requires multi_ack_detailed"));
 
-       for_each_ref(rev_list_insert_ref_oid, negotiator);
+       mark_tips(negotiator, args->negotiation_tips);
        for_each_cached_alternate(negotiator, insert_one_alternate_object);
 
        fetching = 0;
@@ -251,7 +270,7 @@ static int find_common(struct fetch_negotiator *negotiator,
                 * interested in the case we *know* the object is
                 * reachable and we have already scanned it.
                 */
-               if (((o = lookup_object(remote->hash)) != NULL) &&
+               if (((o = lookup_object(the_repository, remote->hash)) != NULL) &&
                                (o->flags & COMPLETE)) {
                        continue;
                }
@@ -325,10 +344,10 @@ static int find_common(struct fetch_negotiator *negotiator,
                        if (skip_prefix(line, "unshallow ", &arg)) {
                                if (get_oid_hex(arg, &oid))
                                        die(_("invalid unshallow line: %s"), line);
-                               if (!lookup_object(oid.hash))
+                               if (!lookup_object(the_repository, oid.hash))
                                        die(_("object not found: %s"), line);
                                /* make sure that it is parsed as shallow */
-                               if (!parse_object(&oid))
+                               if (!parse_object(the_repository, &oid))
                                        die(_("error in object: %s"), line);
                                if (unregister_shallow(&oid))
                                        die(_("no shallow found: %s"), line);
@@ -387,8 +406,10 @@ static int find_common(struct fetch_negotiator *negotiator,
                                case ACK_ready:
                                case ACK_continue: {
                                        struct commit *commit =
-                                               lookup_commit(result_oid);
+                                               lookup_commit(the_repository,
+                                                             result_oid);
                                        int was_common;
+
                                        if (!commit)
                                                die(_("invalid commit %s"), oid_to_hex(result_oid));
                                        was_common = negotiator->ack(negotiator, commit);
@@ -462,14 +483,14 @@ static struct commit_list *complete;
 
 static int mark_complete(const struct object_id *oid)
 {
-       struct object *o = parse_object(oid);
+       struct object *o = parse_object(the_repository, oid);
 
        while (o && o->type == OBJ_TAG) {
                struct tag *t = (struct tag *) o;
                if (!t->tagged)
                        break; /* broken repository */
                o->flags |= COMPLETE;
-               o = parse_object(&t->tagged->oid);
+               o = parse_object(the_repository, &t->tagged->oid);
        }
        if (o && o->type == OBJ_COMMIT) {
                struct commit *commit = (struct commit *)o;
@@ -670,7 +691,7 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
 
                if (!has_object_file_with_flags(&ref->old_oid, flags))
                        continue;
-               o = parse_object(&ref->old_oid);
+               o = parse_object(the_repository, &ref->old_oid);
                if (!o)
                        continue;
 
@@ -701,7 +722,9 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
                 * Don't mark them common yet; the server has to be told so first.
                 */
                for (ref = *refs; ref; ref = ref->next) {
-                       struct object *o = deref_tag(lookup_object(ref->old_oid.hash),
+                       struct object *o = deref_tag(the_repository,
+                                                    lookup_object(the_repository,
+                                                    ref->old_oid.hash),
                                                     NULL, 0);
 
                        if (!o || o->type != OBJ_COMMIT || !(o->flags & COMPLETE))
@@ -729,7 +752,7 @@ static int everything_local(struct fetch_pack_args *args,
                const struct object_id *remote = &ref->old_oid;
                struct object *o;
 
-               o = lookup_object(remote->hash);
+               o = lookup_object(the_repository, remote->hash);
                if (!o || !(o->flags & COMPLETE)) {
                        retval = 0;
                        print_verbose(args, "want %s (%s)", oid_to_hex(remote),
@@ -891,7 +914,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
        const char *agent_feature;
        int agent_len;
        struct fetch_negotiator negotiator;
-       fetch_negotiator_init(&negotiator);
+       fetch_negotiator_init(&negotiator, negotiation_algorithm);
 
        sort_ref_list(&ref, ref_compare_name);
        QSORT(sought, nr_sought, cmp_ref_by_name);
@@ -1032,7 +1055,7 @@ static void add_wants(const struct ref *wants, struct strbuf *req_buf)
                 * interested in the case we *know* the object is
                 * reachable and we have already scanned it.
                 */
-               if (((o = lookup_object(remote->hash)) != NULL) &&
+               if (((o = lookup_object(the_repository, remote->hash)) != NULL) &&
                    (o->flags & COMPLETE)) {
                        continue;
                }
@@ -1162,13 +1185,13 @@ static int process_section_header(struct packet_reader *reader,
        int ret;
 
        if (packet_reader_peek(reader) != PACKET_READ_NORMAL)
-               die("error reading section header '%s'", section);
+               die(_("error reading section header '%s'"), section);
 
        ret = !strcmp(reader->line, section);
 
        if (!peek) {
                if (!ret)
-                       die("expected '%s', received '%s'",
+                       die(_("expected '%s', received '%s'"),
                            section, reader->line);
                packet_reader_read(reader);
        }
@@ -1196,7 +1219,7 @@ static int process_acks(struct fetch_negotiator *negotiator,
                        if (!get_oid_hex(arg, &oid)) {
                                struct commit *commit;
                                oidset_insert(common, &oid);
-                               commit = lookup_commit(&oid);
+                               commit = lookup_commit(the_repository, &oid);
                                negotiator->ack(negotiator, commit);
                        }
                        continue;
@@ -1207,12 +1230,12 @@ static int process_acks(struct fetch_negotiator *negotiator,
                        continue;
                }
 
-               die("unexpected acknowledgment line: '%s'", reader->line);
+               die(_("unexpected acknowledgment line: '%s'"), reader->line);
        }
 
        if (reader->status != PACKET_READ_FLUSH &&
            reader->status != PACKET_READ_DELIM)
-               die("error processing acks: %d", reader->status);
+               die(_("error processing acks: %d"), reader->status);
 
        /* return 0 if no common, 1 if there are common, or 2 if ready */
        return received_ready ? 2 : (received_ack ? 1 : 0);
@@ -1235,10 +1258,10 @@ static void receive_shallow_info(struct fetch_pack_args *args,
                if (skip_prefix(reader->line, "unshallow ", &arg)) {
                        if (get_oid_hex(arg, &oid))
                                die(_("invalid unshallow line: %s"), reader->line);
-                       if (!lookup_object(oid.hash))
+                       if (!lookup_object(the_repository, oid.hash))
                                die(_("object not found: %s"), reader->line);
                        /* make sure that it is parsed as shallow */
-                       if (!parse_object(&oid))
+                       if (!parse_object(the_repository, &oid))
                                die(_("error in object: %s"), reader->line);
                        if (unregister_shallow(&oid))
                                die(_("no shallow found: %s"), reader->line);
@@ -1249,7 +1272,7 @@ static void receive_shallow_info(struct fetch_pack_args *args,
 
        if (reader->status != PACKET_READ_FLUSH &&
            reader->status != PACKET_READ_DELIM)
-               die("error processing shallow info: %d", reader->status);
+               die(_("error processing shallow info: %d"), reader->status);
 
        setup_alternate_shallow(&shallow_lock, &alternate_shallow_file, NULL);
        args->deepen = 1;
@@ -1264,7 +1287,7 @@ static void receive_wanted_refs(struct packet_reader *reader, struct ref *refs)
                struct ref *r = NULL;
 
                if (parse_oid_hex(reader->line, &oid, &end) || *end++ != ' ')
-                       die("expected wanted-ref, got '%s'", reader->line);
+                       die(_("expected wanted-ref, got '%s'"), reader->line);
 
                for (r = refs; r; r = r->next) {
                        if (!strcmp(end, r->name)) {
@@ -1274,11 +1297,11 @@ static void receive_wanted_refs(struct packet_reader *reader, struct ref *refs)
                }
 
                if (!r)
-                       die("unexpected wanted-ref: '%s'", reader->line);
+                       die(_("unexpected wanted-ref: '%s'"), reader->line);
        }
 
        if (reader->status != PACKET_READ_DELIM)
-               die("error processing wanted refs: %d", reader->status);
+               die(_("error processing wanted refs: %d"), reader->status);
 }
 
 enum fetch_state {
@@ -1302,7 +1325,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
        int in_vain = 0;
        int haves_to_send = INITIAL_FLUSH;
        struct fetch_negotiator negotiator;
-       fetch_negotiator_init(&negotiator);
+       fetch_negotiator_init(&negotiator, negotiation_algorithm);
        packet_reader_init(&reader, fd[0], NULL, 0,
                           PACKET_READ_CHOMP_NEWLINE);
 
@@ -1326,7 +1349,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
                        else
                                state = FETCH_SEND_REQUEST;
 
-                       for_each_ref(rev_list_insert_ref_oid, &negotiator);
+                       mark_tips(&negotiator, args->negotiation_tips);
                        for_each_cached_alternate(&negotiator,
                                                  insert_one_alternate_object);
                        break;
@@ -1384,6 +1407,8 @@ static void fetch_pack_config(void)
        git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta);
        git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects);
        git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects);
+       git_config_get_string("fetch.negotiationalgorithm",
+                             &negotiation_algorithm);
 
        git_config(git_default_config, NULL);
 }