Merge branch 'jt/tags-to-promised-blobs-fix'
authorJunio C Hamano <gitster@pobox.com>
Thu, 2 Aug 2018 22:30:46 +0000 (15:30 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 2 Aug 2018 22:30:46 +0000 (15:30 -0700)
The lazy clone support had a few places where missing but promised
objects were not correctly tolerated, which have been fixed.

* jt/tags-to-promised-blobs-fix:
tag: don't warn if target is missing but promised
revision: tolerate promised targets of tags

1  2 
revision.c
tag.c
diff --combined revision.c
index 8bd2e27037d8136ec96d31ed1a41eb45a040e475,95546e6d446e3df7ccebb366ec3e5c04bd4a2f9f..0627494378dcf6d921af59cc83d02e6a6feb0030
@@@ -1,5 -1,4 +1,5 @@@
  #include "cache.h"
 +#include "object-store.h"
  #include "tag.h"
  #include "blob.h"
  #include "tree.h"
@@@ -30,8 -29,6 +30,8 @@@ volatile show_early_output_fn_t show_ea
  static const char *term_bad;
  static const char *term_good;
  
 +implement_shared_commit_slab(revision_sources, char *);
 +
  void show_object_with_name(FILE *out, struct object *obj, const char *name)
  {
        const char *p;
@@@ -63,10 -60,10 +63,10 @@@ static void mark_tree_contents_unintere
        while (tree_entry(&desc, &entry)) {
                switch (object_type(entry.mode)) {
                case OBJ_TREE:
 -                      mark_tree_uninteresting(lookup_tree(entry.oid));
 +                      mark_tree_uninteresting(lookup_tree(the_repository, entry.oid));
                        break;
                case OBJ_BLOB:
 -                      mark_blob_uninteresting(lookup_blob(entry.oid));
 +                      mark_blob_uninteresting(lookup_blob(the_repository, entry.oid));
                        break;
                default:
                        /* Subproject commit - not in this repository */
@@@ -198,7 -195,7 +198,7 @@@ void add_head_to_pending(struct rev_inf
        struct object *obj;
        if (get_oid("HEAD", &oid))
                return;
 -      obj = parse_object(&oid);
 +      obj = parse_object(the_repository, &oid);
        if (!obj)
                return;
        add_pending_object(revs, obj, "HEAD");
@@@ -210,7 -207,7 +210,7 @@@ static struct object *get_reference(str
  {
        struct object *object;
  
 -      object = parse_object(oid);
 +      object = parse_object(the_repository, oid);
        if (!object) {
                if (revs->ignore_missing)
                        return object;
@@@ -247,10 -244,13 +247,13 @@@ static struct commit *handle_commit(str
                        add_pending_object(revs, object, tag->tag);
                if (!tag->tagged)
                        die("bad tag");
 -              object = parse_object(&tag->tagged->oid);
 +              object = parse_object(the_repository, &tag->tagged->oid);
                if (!object) {
                        if (revs->ignore_missing_links || (flags & UNINTERESTING))
                                return NULL;
+                       if (revs->exclude_promisor_objects &&
+                           is_promisor_object(&tag->tagged->oid))
+                               return NULL;
                        die("bad object %s", oid_to_hex(&tag->tagged->oid));
                }
                object->flags |= flags;
         */
        if (object->type == OBJ_COMMIT) {
                struct commit *commit = (struct commit *)object;
 +
                if (parse_commit(commit) < 0)
                        die("unable to parse commit %s", name);
                if (flags & UNINTERESTING) {
                        mark_parents_uninteresting(commit);
                        revs->limited = 1;
                }
 -              if (revs->show_source && !commit->util)
 -                      commit->util = xstrdup(name);
 +              if (revs->sources) {
 +                      char **slot = revision_sources_at(revs->sources, commit);
 +
 +                      if (!*slot)
 +                              *slot = xstrdup(name);
 +              }
                return commit;
        }
  
@@@ -833,12 -828,8 +836,12 @@@ static int add_parents_to_list(struct r
                        }
                        return -1;
                }
 -              if (revs->show_source && !p->util)
 -                      p->util = commit->util;
 +              if (revs->sources) {
 +                      char **slot = revision_sources_at(revs->sources, p);
 +
 +                      if (!*slot)
 +                              *slot = *revision_sources_at(revs->sources, commit);
 +              }
                p->object.flags |= left_flag;
                if (!(p->object.flags & SEEN)) {
                        p->object.flags |= SEEN;
@@@ -1250,7 -1241,7 +1253,7 @@@ static void handle_one_reflog_commit(st
  {
        struct all_refs_cb *cb = cb_data;
        if (!is_null_oid(oid)) {
 -              struct object *o = parse_object(oid);
 +              struct object *o = parse_object(the_repository, oid);
                if (o) {
                        o->flags |= cb->all_flags;
                        /* ??? CMDLINEFLAGS ??? */
@@@ -1323,7 -1314,7 +1326,7 @@@ static void add_cache_tree(struct cache
        int i;
  
        if (it->entry_count >= 0) {
 -              struct tree *tree = lookup_tree(&it->oid);
 +              struct tree *tree = lookup_tree(the_repository, &it->oid);
                add_pending_object_with_path(revs, &tree->object, "",
                                             040000, path->buf);
        }
@@@ -1349,7 -1340,7 +1352,7 @@@ static void do_add_index_objects_to_pen
                if (S_ISGITLINK(ce->ce_mode))
                        continue;
  
 -              blob = lookup_blob(&ce->oid);
 +              blob = lookup_blob(the_repository, &ce->oid);
                if (!blob)
                        die("unable to add index blob to traversal");
                add_pending_object_with_path(revs, &blob->object, "",
@@@ -1578,8 -1569,8 +1581,8 @@@ static int handle_dotdot_1(const char *
                *dotdot = '\0';
        }
  
 -      a_obj = parse_object(&a_oid);
 -      b_obj = parse_object(&b_oid);
 +      a_obj = parse_object(the_repository, &a_oid);
 +      b_obj = parse_object(the_repository, &b_oid);
        if (!a_obj || !b_obj)
                return dotdot_missing(arg, dotdot, revs, symmetric);
  
                struct commit *a, *b;
                struct commit_list *exclude;
  
 -              a = lookup_commit_reference(&a_obj->oid);
 -              b = lookup_commit_reference(&b_obj->oid);
 +              a = lookup_commit_reference(the_repository, &a_obj->oid);
 +              b = lookup_commit_reference(the_repository, &b_obj->oid);
                if (!a || !b)
                        return dotdot_missing(arg, dotdot, revs, symmetric);
  
@@@ -2884,7 -2875,7 +2887,7 @@@ static int mark_uninteresting(const str
                              uint32_t pos,
                              void *unused)
  {
 -      struct object *o = parse_object(oid);
 +      struct object *o = parse_object(the_repository, oid);
        o->flags |= UNINTERESTING | SEEN;
        return 0;
  }
diff --combined tag.c
index 94a89b21cb5bdeda2f8c395a7c647bf165821849,1110e3643ef5c451681fa395fcc36d3054fd4c52..1db663d71623a493286c90b13532c7d1cf73f517
--- 1/tag.c
--- 2/tag.c
+++ b/tag.c
@@@ -1,11 -1,10 +1,12 @@@
  #include "cache.h"
  #include "tag.h"
 +#include "object-store.h"
  #include "commit.h"
  #include "tree.h"
  #include "blob.h"
 +#include "alloc.h"
  #include "gpg-interface.h"
+ #include "packfile.h"
  
  const char *tag_type = "tag";
  
@@@ -64,14 -63,20 +65,20 @@@ int gpg_verify_tag(const struct object_
        return ret;
  }
  
 -struct object *deref_tag(struct object *o, const char *warn, int warnlen)
 +struct object *deref_tag(struct repository *r, struct object *o, const char *warn, int warnlen)
  {
+       struct object_id *last_oid = NULL;
        while (o && o->type == OBJ_TAG)
-               if (((struct tag *)o)->tagged)
-                       o = parse_object(r, &((struct tag *)o)->tagged->oid);
-               else
+               if (((struct tag *)o)->tagged) {
+                       last_oid = &((struct tag *)o)->tagged->oid;
 -                      o = parse_object(last_oid);
++                      o = parse_object(r, last_oid);
+               } else {
+                       last_oid = NULL;
                        o = NULL;
+               }
        if (!o && warn) {
+               if (last_oid && is_promisor_object(last_oid))
+                       return NULL;
                if (!warnlen)
                        warnlen = strlen(warn);
                error("missing object referenced by '%.*s'", warnlen, warn);
@@@ -82,7 -87,7 +89,7 @@@
  struct object *deref_tag_noverify(struct object *o)
  {
        while (o && o->type == OBJ_TAG) {
 -              o = parse_object(&o->oid);
 +              o = parse_object(the_repository, &o->oid);
                if (o && o->type == OBJ_TAG && ((struct tag *)o)->tagged)
                        o = ((struct tag *)o)->tagged;
                else
        return o;
  }
  
 -struct tag *lookup_tag(const struct object_id *oid)
 +struct tag *lookup_tag(struct repository *r, const struct object_id *oid)
  {
 -      struct object *obj = lookup_object(oid->hash);
 +      struct object *obj = lookup_object(r, oid->hash);
        if (!obj)
 -              return create_object(oid->hash, alloc_tag_node());
 -      return object_as_type(obj, OBJ_TAG, 0);
 +              return create_object(r, oid->hash,
 +                                   alloc_tag_node(r));
 +      return object_as_type(r, obj, OBJ_TAG, 0);
  }
  
  static timestamp_t parse_tag_date(const char *buf, const char *tail)
        return parse_timestamp(dateptr, NULL, 10);
  }
  
 -int parse_tag_buffer(struct tag *item, const void *data, unsigned long size)
 +void release_tag_memory(struct tag *t)
 +{
 +      free(t->tag);
 +      t->tagged = NULL;
 +      t->object.parsed = 0;
 +      t->date = 0;
 +}
 +
 +int parse_tag_buffer(struct repository *r, struct tag *item, const void *data, unsigned long size)
  {
        struct object_id oid;
        char type[20];
        bufptr = nl + 1;
  
        if (!strcmp(type, blob_type)) {
 -              item->tagged = (struct object *)lookup_blob(&oid);
 +              item->tagged = (struct object *)lookup_blob(r, &oid);
        } else if (!strcmp(type, tree_type)) {
 -              item->tagged = (struct object *)lookup_tree(&oid);
 +              item->tagged = (struct object *)lookup_tree(r, &oid);
        } else if (!strcmp(type, commit_type)) {
 -              item->tagged = (struct object *)lookup_commit(&oid);
 +              item->tagged = (struct object *)lookup_commit(r, &oid);
        } else if (!strcmp(type, tag_type)) {
 -              item->tagged = (struct object *)lookup_tag(&oid);
 +              item->tagged = (struct object *)lookup_tag(r, &oid);
        } else {
                error("Unknown type %s", type);
                item->tagged = NULL;
@@@ -202,7 -198,7 +209,7 @@@ int parse_tag(struct tag *item
                return error("Object %s not a tag",
                             oid_to_hex(&item->object.oid));
        }
 -      ret = parse_tag_buffer(item, data, size);
 +      ret = parse_tag_buffer(the_repository, item, data, size);
        free(data);
        return ret;
  }