Merge branch 'jk/fast-export-object-lookup'
authorJunio C Hamano <gitster@pobox.com>
Mon, 25 Mar 2013 21:01:05 +0000 (14:01 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 25 Mar 2013 21:01:05 +0000 (14:01 -0700)
* jk/fast-export-object-lookup:
fast-export: do not load blob objects twice
fast-export: rename handle_object function

1  2 
builtin/fast-export.c
diff --combined builtin/fast-export.c
index 77dffd1ce3a5f809a81793f67b9297a555bab1fa,ed2916595fc386fe4127dc3fe9f68b85d15b3def..d380155d9cf8fedf133dddbae479a910decd55b2
@@@ -113,12 -113,13 +113,13 @@@ static void show_progress(void
                printf("progress %d objects\n", counter);
  }
  
- static void handle_object(const unsigned char *sha1)
+ static void export_blob(const unsigned char *sha1)
  {
        unsigned long size;
        enum object_type type;
        char *buf;
        struct object *object;
+       int eaten;
  
        if (no_data)
                return;
        if (is_null_sha1(sha1))
                return;
  
-       object = parse_object(sha1);
-       if (!object)
-               die ("Could not read blob %s", sha1_to_hex(sha1));
-       if (object->flags & SHOWN)
+       object = lookup_object(sha1);
+       if (object && object->flags & SHOWN)
                return;
  
        buf = read_sha1_file(sha1, &type, &size);
        if (!buf)
                die ("Could not read blob %s", sha1_to_hex(sha1));
+       if (check_sha1_signature(sha1, buf, size, typename(type)) < 0)
+               die("sha1 mismatch in blob %s", sha1_to_hex(sha1));
+       object = parse_object_buffer(sha1, type, size, buf, &eaten);
+       if (!object)
+               die("Could not read blob %s", sha1_to_hex(sha1));
  
        mark_next_object(object);
  
        show_progress();
  
        object->flags |= SHOWN;
-       free(buf);
+       if (!eaten)
+               free(buf);
  }
  
  static int depth_first(const void *a_, const void *b_)
@@@ -312,7 -316,7 +316,7 @@@ static void handle_commit(struct commi
        /* Export the referenced blobs, and remember the marks. */
        for (i = 0; i < diff_queued_diff.nr; i++)
                if (!S_ISGITLINK(diff_queued_diff.queue[i]->two->mode))
-                       handle_object(diff_queued_diff.queue[i]->two->sha1);
+                       export_blob(diff_queued_diff.queue[i]->two->sha1);
  
        mark_next_object(&commit->object);
        if (!is_encoding_utf8(encoding))
@@@ -474,21 -478,18 +478,21 @@@ static void handle_tag(const char *name
               (int)message_size, (int)message_size, message ? message : "");
  }
  
 -static void get_tags_and_duplicates(struct object_array *pending,
 +static void get_tags_and_duplicates(struct rev_cmdline_info *info,
                                    struct string_list *extra_refs)
  {
        struct tag *tag;
        int i;
  
 -      for (i = 0; i < pending->nr; i++) {
 -              struct object_array_entry *e = pending->objects + i;
 +      for (i = 0; i < info->nr; i++) {
 +              struct rev_cmdline_entry *e = info->rev + i;
                unsigned char sha1[20];
 -              struct commit *commit = commit;
 +              struct commit *commit;
                char *full_name;
  
 +              if (e->flags & UNINTERESTING)
 +                      continue;
 +
                if (dwim_ref(e->name, strlen(e->name), sha1, &full_name) != 1)
                        continue;
  
                                commit = (struct commit *)tag;
                                break;
                        case OBJ_BLOB:
-                               handle_object(tag->object.sha1);
+                               export_blob(tag->object.sha1);
                                continue;
                        default: /* OBJ_TAG (nested tags) is already handled */
                                warning("Tag points to object of unexpected type %s, skipping.",
                                typename(e->item->type));
                        continue;
                }
 -              if (commit->util)
 -                      /* more than one name for the same object */
 +
 +              /*
 +               * This ref will not be updated through a commit, lets make
 +               * sure it gets properly updated eventually.
 +               */
 +              if (commit->util || commit->object.flags & SHOWN)
                        string_list_append(extra_refs, full_name)->util = commit;
 -              else
 +              if (!commit->util)
                        commit->util = full_name;
        }
  }
@@@ -621,10 -618,6 +625,10 @@@ static void import_marks(char *input_fi
                if (object->flags & SHOWN)
                        error("Object %s already has a mark", sha1_to_hex(sha1));
  
 +              if (object->type != OBJ_COMMIT)
 +                      /* only commits */
 +                      continue;
 +
                mark_object(object, mark);
                if (last_idnum < mark)
                        last_idnum = mark;
@@@ -688,7 -681,7 +692,7 @@@ int cmd_fast_export(int argc, const cha
        if (import_filename && revs.prune_data.nr)
                full_tree = 1;
  
 -      get_tags_and_duplicates(&revs.pending, &extra_refs);
 +      get_tags_and_duplicates(&revs.cmdline, &extra_refs);
  
        if (prepare_revision_walk(&revs))
                die("revision walk setup failed");