pack-objects: refactor code into compute_layer_order()
[gitweb.git] / remote.c
index 4a9bddf0d7af66f2e1705bf459432ae69fd6735f..86e6098774d891a3b7045cf1dd9c11959faf13dc 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -3,6 +3,7 @@
 #include "remote.h"
 #include "refs.h"
 #include "refspec.h"
+#include "object-store.h"
 #include "commit.h"
 #include "diff.h"
 #include "revision.h"
@@ -525,8 +526,7 @@ const char *remote_ref_for_branch(struct branch *branch, int for_push,
                        struct remote *remote = remote_get(remote_name);
 
                        if (remote && remote->push.nr &&
-                           (dst = apply_refspecs(remote->push.items,
-                                                 remote->push.nr,
+                           (dst = apply_refspecs(&remote->push,
                                                  branch->refname))) {
                                if (explicit)
                                        *explicit = 1;
@@ -698,7 +698,9 @@ static int match_name_with_pattern(const char *key, const char *name,
        return ret;
 }
 
-static void query_refspecs_multiple(struct refspec_item *refs, int ref_count, struct refspec_item *query, struct string_list *results)
+static void query_refspecs_multiple(struct refspec *rs,
+                                   struct refspec_item *query,
+                                   struct string_list *results)
 {
        int i;
        int find_src = !query->src;
@@ -706,8 +708,8 @@ static void query_refspecs_multiple(struct refspec_item *refs, int ref_count, st
        if (find_src && !query->dst)
                error("query_refspecs_multiple: need either src or dst");
 
-       for (i = 0; i < ref_count; i++) {
-               struct refspec_item *refspec = &refs[i];
+       for (i = 0; i < rs->nr; i++) {
+               struct refspec_item *refspec = &rs->items[i];
                const char *key = find_src ? refspec->dst : refspec->src;
                const char *value = find_src ? refspec->src : refspec->dst;
                const char *needle = find_src ? query->dst : query->src;
@@ -724,7 +726,7 @@ static void query_refspecs_multiple(struct refspec_item *refs, int ref_count, st
        }
 }
 
-int query_refspecs(struct refspec_item *refs, int ref_count, struct refspec_item *query)
+int query_refspecs(struct refspec *rs, struct refspec_item *query)
 {
        int i;
        int find_src = !query->src;
@@ -734,8 +736,8 @@ int query_refspecs(struct refspec_item *refs, int ref_count, struct refspec_item
        if (find_src && !query->dst)
                return error("query_refspecs: need either src or dst");
 
-       for (i = 0; i < ref_count; i++) {
-               struct refspec_item *refspec = &refs[i];
+       for (i = 0; i < rs->nr; i++) {
+               struct refspec_item *refspec = &rs->items[i];
                const char *key = find_src ? refspec->dst : refspec->src;
                const char *value = find_src ? refspec->src : refspec->dst;
 
@@ -755,15 +757,14 @@ int query_refspecs(struct refspec_item *refs, int ref_count, struct refspec_item
        return -1;
 }
 
-char *apply_refspecs(struct refspec_item *refspecs, int nr_refspec,
-                    const char *name)
+char *apply_refspecs(struct refspec *rs, const char *name)
 {
        struct refspec_item query;
 
        memset(&query, 0, sizeof(struct refspec_item));
        query.src = (char *)name;
 
-       if (query_refspecs(refspecs, nr_refspec, &query))
+       if (query_refspecs(rs, &query))
                return NULL;
 
        return query.dst;
@@ -771,7 +772,7 @@ char *apply_refspecs(struct refspec_item *refspecs, int nr_refspec,
 
 int remote_find_tracking(struct remote *remote, struct refspec_item *refspec)
 {
-       return query_refspecs(remote->fetch.items, remote->fetch.nr, refspec);
+       return query_refspecs(&remote->fetch, refspec);
 }
 
 static struct ref *alloc_ref_with_prefix(const char *prefix, size_t prefixlen,
@@ -1073,36 +1074,37 @@ static int match_explicit(struct ref *src, struct ref *dst,
 }
 
 static int match_explicit_refs(struct ref *src, struct ref *dst,
-                              struct ref ***dst_tail, struct refspec_item *rs,
-                              int rs_nr)
+                              struct ref ***dst_tail, struct refspec *rs)
 {
        int i, errs;
-       for (i = errs = 0; i < rs_nr; i++)
-               errs += match_explicit(src, dst, dst_tail, &rs[i]);
+       for (i = errs = 0; i < rs->nr; i++)
+               errs += match_explicit(src, dst, dst_tail, &rs->items[i]);
        return errs;
 }
 
-static char *get_ref_match(const struct refspec_item *rs, int rs_nr, const struct ref *ref,
-               int send_mirror, int direction, const struct refspec_item **ret_pat)
+static char *get_ref_match(const struct refspec *rs, const struct ref *ref,
+                          int send_mirror, int direction,
+                          const struct refspec_item **ret_pat)
 {
        const struct refspec_item *pat;
        char *name;
        int i;
        int matching_refs = -1;
-       for (i = 0; i < rs_nr; i++) {
-               if (rs[i].matching &&
-                   (matching_refs == -1 || rs[i].force)) {
+       for (i = 0; i < rs->nr; i++) {
+               const struct refspec_item *item = &rs->items[i];
+               if (item->matching &&
+                   (matching_refs == -1 || item->force)) {
                        matching_refs = i;
                        continue;
                }
 
-               if (rs[i].pattern) {
-                       const char *dst_side = rs[i].dst ? rs[i].dst : rs[i].src;
+               if (item->pattern) {
+                       const char *dst_side = item->dst ? item->dst : item->src;
                        int match;
                        if (direction == FROM_SRC)
-                               match = match_name_with_pattern(rs[i].src, ref->name, dst_side, &name);
+                               match = match_name_with_pattern(item->src, ref->name, dst_side, &name);
                        else
-                               match = match_name_with_pattern(dst_side, ref->name, rs[i].src, &name);
+                               match = match_name_with_pattern(dst_side, ref->name, item->src, &name);
                        if (match) {
                                matching_refs = i;
                                break;
@@ -1112,7 +1114,7 @@ static char *get_ref_match(const struct refspec_item *rs, int rs_nr, const struc
        if (matching_refs == -1)
                return NULL;
 
-       pat = rs + matching_refs;
+       pat = &rs->items[matching_refs];
        if (pat->matching) {
                /*
                 * "matching refs"; traditionally we pushed everything
@@ -1147,7 +1149,7 @@ static void add_to_tips(struct tips *tips, const struct object_id *oid)
 
        if (is_null_oid(oid))
                return;
-       commit = lookup_commit_reference_gently(oid, 1);
+       commit = lookup_commit_reference_gently(the_repository, oid, 1);
        if (!commit || (commit->object.flags & TMP_MARK))
                return;
        commit->object.flags |= TMP_MARK;
@@ -1187,7 +1189,7 @@ static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***ds
                        continue; /* not a tag */
                if (string_list_has_string(&dst_tag, ref->name))
                        continue; /* they already have it */
-               if (oid_object_info(&ref->new_oid, NULL) != OBJ_TAG)
+               if (oid_object_info(the_repository, &ref->new_oid, NULL) != OBJ_TAG)
                        continue; /* be conservative */
                item = string_list_append(&src_tag, ref->name);
                item->util = ref;
@@ -1209,7 +1211,8 @@ static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***ds
 
                        if (is_null_oid(&ref->new_oid))
                                continue;
-                       commit = lookup_commit_reference_gently(&ref->new_oid,
+                       commit = lookup_commit_reference_gently(the_repository,
+                                                               &ref->new_oid,
                                                                1);
                        if (!commit)
                                /* not pushing a commit, which is not an error */
@@ -1254,24 +1257,20 @@ static void prepare_ref_index(struct string_list *ref_index, struct ref *ref)
  * but we can catch some errors early before even talking to the
  * remote side.
  */
-int check_push_refs(struct ref *src, int nr_refspec, const char **refspec_names)
+int check_push_refs(struct ref *src, struct refspec *rs)
 {
-       struct refspec refspec = REFSPEC_INIT_PUSH;
        int ret = 0;
        int i;
 
-       refspec_appendn(&refspec, refspec_names, nr_refspec);
+       for (i = 0; i < rs->nr; i++) {
+               struct refspec_item *item = &rs->items[i];
 
-       for (i = 0; i < refspec.nr; i++) {
-               struct refspec_item *rs = &refspec.items[i];
-
-               if (rs->pattern || rs->matching)
+               if (item->pattern || item->matching)
                        continue;
 
-               ret |= match_explicit_lhs(src, rs, NULL, NULL);
+               ret |= match_explicit_lhs(src, item, NULL, NULL);
        }
 
-       refspec_clear(&refspec);
        return ret;
 }
 
@@ -1284,23 +1283,20 @@ int check_push_refs(struct ref *src, int nr_refspec, const char **refspec_names)
  * dst (e.g. pushing to a new branch, done in match_explicit_refs).
  */
 int match_push_refs(struct ref *src, struct ref **dst,
-                   int nr_refspec, const char **refspec, int flags)
+                   struct refspec *rs, int flags)
 {
-       struct refspec rs = REFSPEC_INIT_PUSH;
        int send_all = flags & MATCH_REFS_ALL;
        int send_mirror = flags & MATCH_REFS_MIRROR;
        int send_prune = flags & MATCH_REFS_PRUNE;
        int errs;
-       static const char *default_refspec[] = { ":", NULL };
        struct ref *ref, **dst_tail = tail_ref(dst);
        struct string_list dst_ref_index = STRING_LIST_INIT_NODUP;
 
-       if (!nr_refspec) {
-               nr_refspec = 1;
-               refspec = default_refspec;
-       }
-       refspec_appendn(&rs, refspec, nr_refspec);
-       errs = match_explicit_refs(src, *dst, &dst_tail, rs.items, rs.nr);
+       /* If no refspec is provided, use the default ":" */
+       if (!rs->nr)
+               refspec_append(rs, ":");
+
+       errs = match_explicit_refs(src, *dst, &dst_tail, rs);
 
        /* pick the remainder */
        for (ref = src; ref; ref = ref->next) {
@@ -1309,7 +1305,7 @@ int match_push_refs(struct ref *src, struct ref **dst,
                const struct refspec_item *pat = NULL;
                char *dst_name;
 
-               dst_name = get_ref_match(rs.items, rs.nr, ref, send_mirror, FROM_SRC, &pat);
+               dst_name = get_ref_match(rs, ref, send_mirror, FROM_SRC, &pat);
                if (!dst_name)
                        continue;
 
@@ -1358,7 +1354,7 @@ int match_push_refs(struct ref *src, struct ref **dst,
                                /* We're already sending something to this ref. */
                                continue;
 
-                       src_name = get_ref_match(rs.items, rs.nr, ref, send_mirror, FROM_DST, NULL);
+                       src_name = get_ref_match(rs, ref, send_mirror, FROM_DST, NULL);
                        if (src_name) {
                                if (!src_ref_index.nr)
                                        prepare_ref_index(&src_ref_index, src);
@@ -1371,8 +1367,6 @@ int match_push_refs(struct ref *src, struct ref **dst,
                string_list_clear(&src_ref_index, 0);
        }
 
-       refspec_clear(&rs);
-
        if (errs)
                return -1;
        return 0;
@@ -1442,8 +1436,8 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
                                reject_reason = REF_STATUS_REJECT_ALREADY_EXISTS;
                        else if (!has_object_file(&ref->old_oid))
                                reject_reason = REF_STATUS_REJECT_FETCH_FIRST;
-                       else if (!lookup_commit_reference_gently(&ref->old_oid, 1) ||
-                                !lookup_commit_reference_gently(&ref->new_oid, 1))
+                       else if (!lookup_commit_reference_gently(the_repository, &ref->old_oid, 1) ||
+                                !lookup_commit_reference_gently(the_repository, &ref->new_oid, 1))
                                reject_reason = REF_STATUS_REJECT_NEEDS_FORCE;
                        else if (!ref_newer(&ref->new_oid, &ref->old_oid))
                                reject_reason = REF_STATUS_REJECT_NONFASTFORWARD;
@@ -1569,7 +1563,7 @@ static const char *tracking_for_push_dest(struct remote *remote,
 {
        char *ret;
 
-       ret = apply_refspecs(remote->fetch.items, remote->fetch.nr, refname);
+       ret = apply_refspecs(&remote->fetch, refname);
        if (!ret)
                return error_buf(err,
                                 _("push destination '%s' on remote '%s' has no local tracking branch"),
@@ -1591,8 +1585,7 @@ static const char *branch_get_push_1(struct branch *branch, struct strbuf *err)
                char *dst;
                const char *ret;
 
-               dst = apply_refspecs(remote->push.items, remote->push.nr,
-                                    branch->refname);
+               dst = apply_refspecs(&remote->push, branch->refname);
                if (!dst)
                        return error_buf(err,
                                         _("push refspecs for '%s' do not include '%s'"),
@@ -1635,7 +1628,7 @@ static const char *branch_get_push_1(struct branch *branch, struct strbuf *err)
                }
        }
 
-       die("BUG: unhandled push situation");
+       BUG("unhandled push situation");
 }
 
 const char *branch_get_push(struct branch *branch, struct strbuf *err)
@@ -1744,6 +1737,7 @@ int get_fetch_map(const struct ref *remote_refs,
                if (refspec->exact_sha1) {
                        ref_map = alloc_ref(name);
                        get_oid_hex(name, &ref_map->old_oid);
+                       ref_map->exact_oid = 1;
                } else {
                        ref_map = get_remote_ref(remote_refs, name);
                }
@@ -1809,12 +1803,14 @@ int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid)
         * Both new_commit and old_commit must be commit-ish and new_commit is descendant of
         * old_commit.  Otherwise we require --force.
         */
-       o = deref_tag(parse_object(old_oid), NULL, 0);
+       o = deref_tag(the_repository, parse_object(the_repository, old_oid),
+                     NULL, 0);
        if (!o || o->type != OBJ_COMMIT)
                return 0;
        old_commit = (struct commit *) o;
 
-       o = deref_tag(parse_object(new_oid), NULL, 0);
+       o = deref_tag(the_repository, parse_object(the_repository, new_oid),
+                     NULL, 0);
        if (!o || o->type != OBJ_COMMIT)
                return 0;
        new_commit = (struct commit *) o;
@@ -1872,13 +1868,13 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
        /* Cannot stat if what we used to build on no longer exists */
        if (read_ref(base, &oid))
                return -1;
-       theirs = lookup_commit_reference(&oid);
+       theirs = lookup_commit_reference(the_repository, &oid);
        if (!theirs)
                return -1;
 
        if (read_ref(branch->refname, &oid))
                return -1;
-       ours = lookup_commit_reference(&oid);
+       ours = lookup_commit_reference(the_repository, &oid);
        if (!ours)
                return -1;
 
@@ -2068,8 +2064,7 @@ struct ref *guess_remote_head(const struct ref *head,
 struct stale_heads_info {
        struct string_list *ref_names;
        struct ref **stale_refs_tail;
-       struct refspec_item *refs;
-       int ref_count;
+       struct refspec *rs;
 };
 
 static int get_stale_heads_cb(const char *refname, const struct object_id *oid,
@@ -2082,7 +2077,7 @@ static int get_stale_heads_cb(const char *refname, const struct object_id *oid,
        memset(&query, 0, sizeof(struct refspec_item));
        query.dst = (char *)refname;
 
-       query_refspecs_multiple(info->refs, info->ref_count, &query, &matches);
+       query_refspecs_multiple(info->rs, &query, &matches);
        if (matches.nr == 0)
                goto clean_exit; /* No matches */
 
@@ -2110,7 +2105,7 @@ static int get_stale_heads_cb(const char *refname, const struct object_id *oid,
        return 0;
 }
 
-struct ref *get_stale_heads(struct refspec_item *refs, int ref_count, struct ref *fetch_map)
+struct ref *get_stale_heads(struct refspec *rs, struct ref *fetch_map)
 {
        struct ref *ref, *stale_refs = NULL;
        struct string_list ref_names = STRING_LIST_INIT_NODUP;
@@ -2118,8 +2113,7 @@ struct ref *get_stale_heads(struct refspec_item *refs, int ref_count, struct ref
 
        info.ref_names = &ref_names;
        info.stale_refs_tail = &stale_refs;
-       info.refs = refs;
-       info.ref_count = ref_count;
+       info.rs = rs;
        for (ref = fetch_map; ref; ref = ref->next)
                string_list_append(&ref_names, ref->name);
        string_list_sort(&ref_names);
@@ -2203,7 +2197,7 @@ static int remote_tracking(struct remote *remote, const char *refname,
 {
        char *dst;
 
-       dst = apply_refspecs(remote->fetch.items, remote->fetch.nr, refname);
+       dst = apply_refspecs(&remote->fetch, refname);
        if (!dst)
                return -1; /* no tracking ref for refname at remote */
        if (read_ref(dst, oid))