Merge branch 'jk/ignore-broken-tags-when-ignoring-missing-links' into maint
authorJunio C Hamano <gitster@pobox.com>
Sun, 4 Jun 2017 01:21:03 +0000 (10:21 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sun, 4 Jun 2017 01:21:03 +0000 (10:21 +0900)
Tag objects, which are not reachable from any ref, that point at
missing objects were mishandled by "git gc" and friends (they
should silently be ignored instead)

* jk/ignore-broken-tags-when-ignoring-missing-links:
revision.c: ignore broken tags with ignore_missing_links

1  2 
revision.c
diff --combined revision.c
index 7ff61ff5f73db07af522ac57d62ed9e699aedf72,7d57d440a10e9192491056b4168c3bdc5137d1a9..67ebc6fc4b89358f1d28dc223935d66bfb00135b
@@@ -147,7 -147,7 +147,7 @@@ static void add_pending_object_with_pat
                revs->no_walk = 0;
        if (revs->reflog_info && obj->type == OBJ_COMMIT) {
                struct strbuf buf = STRBUF_INIT;
 -              int len = interpret_branch_name(name, 0, &buf);
 +              int len = interpret_branch_name(name, 0, &buf, 0);
                int st;
  
                if (0 < len && name[len] && buf.len)
@@@ -230,7 -230,7 +230,7 @@@ static struct commit *handle_commit(str
                        die("bad tag");
                object = parse_object(tag->tagged->oid.hash);
                if (!object) {
-                       if (flags & UNINTERESTING)
+                       if (revs->ignore_missing_links || (flags & UNINTERESTING))
                                return NULL;
                        die("bad object %s", oid_to_hex(&tag->tagged->oid));
                }
@@@ -1196,11 -1196,11 +1196,11 @@@ static void handle_refs(const char *sub
        for_each(submodule, handle_one_ref, &cb);
  }
  
 -static void handle_one_reflog_commit(unsigned char *sha1, void *cb_data)
 +static void handle_one_reflog_commit(struct object_id *oid, void *cb_data)
  {
        struct all_refs_cb *cb = cb_data;
 -      if (!is_null_sha1(sha1)) {
 -              struct object *o = parse_object(sha1);
 +      if (!is_null_oid(oid)) {
 +              struct object *o = parse_object(oid->hash);
                if (o) {
                        o->flags |= cb->all_flags;
                        /* ??? CMDLINEFLAGS ??? */
        }
  }
  
 -static int handle_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
 +static int handle_one_reflog_ent(struct object_id *ooid, struct object_id *noid,
                const char *email, unsigned long timestamp, int tz,
                const char *message, void *cb_data)
  {
 -      handle_one_reflog_commit(osha1, cb_data);
 -      handle_one_reflog_commit(nsha1, cb_data);
 +      handle_one_reflog_commit(ooid, cb_data);
 +      handle_one_reflog_commit(noid, cb_data);
        return 0;
  }
  
@@@ -1275,7 -1275,7 +1275,7 @@@ void add_index_objects_to_pending(struc
                if (S_ISGITLINK(ce->ce_mode))
                        continue;
  
 -              blob = lookup_blob(ce->sha1);
 +              blob = lookup_blob(ce->oid.hash);
                if (!blob)
                        die("unable to add index blob to traversal");
                add_pending_object_with_path(revs, &blob->object, "",
        }
  }
  
 -static int add_parents_only(struct rev_info *revs, const char *arg_, int flags)
 +static int add_parents_only(struct rev_info *revs, const char *arg_, int flags,
 +                          int exclude_parent)
  {
        unsigned char sha1[20];
        struct object *it;
        struct commit *commit;
        struct commit_list *parents;
 +      int parent_number;
        const char *arg = arg_;
  
        if (*arg == '^') {
        if (it->type != OBJ_COMMIT)
                return 0;
        commit = (struct commit *)it;
 -      for (parents = commit->parents; parents; parents = parents->next) {
 +      if (exclude_parent &&
 +          exclude_parent > commit_list_count(commit->parents))
 +              return 0;
 +      for (parents = commit->parents, parent_number = 1;
 +           parents;
 +           parents = parents->next, parent_number++) {
 +              if (exclude_parent && parent_number != exclude_parent)
 +                      continue;
 +
                it = &parents->item->object;
                it->flags |= flags;
                add_rev_cmdline(revs, it, arg_, REV_CMD_PARENTS_ONLY, flags);
@@@ -1529,33 -1519,17 +1529,33 @@@ int handle_revision_arg(const char *arg
                }
                *dotdot = '.';
        }
 +
        dotdot = strstr(arg, "^@");
        if (dotdot && !dotdot[2]) {
                *dotdot = 0;
 -              if (add_parents_only(revs, arg, flags))
 +              if (add_parents_only(revs, arg, flags, 0))
                        return 0;
                *dotdot = '^';
        }
        dotdot = strstr(arg, "^!");
        if (dotdot && !dotdot[2]) {
                *dotdot = 0;
 -              if (!add_parents_only(revs, arg, flags ^ (UNINTERESTING | BOTTOM)))
 +              if (!add_parents_only(revs, arg, flags ^ (UNINTERESTING | BOTTOM), 0))
 +                      *dotdot = '^';
 +      }
 +      dotdot = strstr(arg, "^-");
 +      if (dotdot) {
 +              int exclude_parent = 1;
 +
 +              if (dotdot[2]) {
 +                      char *end;
 +                      exclude_parent = strtoul(dotdot + 2, &end, 10);
 +                      if (*end != '\0' || !exclude_parent)
 +                              return -1;
 +              }
 +
 +              *dotdot = 0;
 +              if (!add_parents_only(revs, arg, flags ^ (UNINTERESTING | BOTTOM), exclude_parent))
                        *dotdot = '^';
        }