Merge branch 'rr/triangle'
[gitweb.git] / builtin / fast-export.c
index 77dffd1ce3a5f809a81793f67b9297a555bab1fa..f44b76cb330250f969a50fd684465dc5c1cb4ecc 100644 (file)
@@ -113,12 +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;
@@ -126,16 +127,18 @@ static void handle_object(const unsigned char *sha1)
        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);
 
@@ -147,7 +150,8 @@ static void handle_object(const unsigned char *sha1)
        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 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)
        /* 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))
@@ -512,7 +516,7 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info,
                                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.",
@@ -614,9 +618,12 @@ static void import_marks(char *input_file)
                        || *mark_end != ' ' || get_sha1(mark_end + 1, sha1))
                        die("corrupt mark line: %s", line);
 
+               if (last_idnum < mark)
+                       last_idnum = mark;
+
                object = parse_object(sha1);
                if (!object)
-                       die ("Could not read blob %s", sha1_to_hex(sha1));
+                       continue;
 
                if (object->flags & SHOWN)
                        error("Object %s already has a mark", sha1_to_hex(sha1));
@@ -626,8 +633,6 @@ static void import_marks(char *input_file)
                        continue;
 
                mark_object(object, mark);
-               if (last_idnum < mark)
-                       last_idnum = mark;
 
                object->flags |= SHOWN;
        }
@@ -641,6 +646,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
        struct string_list extra_refs = STRING_LIST_INIT_NODUP;
        struct commit *commit;
        char *export_filename = NULL, *import_filename = NULL;
+       uint32_t lastimportid;
        struct option options[] = {
                OPT_INTEGER(0, "progress", &progress,
                            N_("show progress after <n> objects")),
@@ -684,6 +690,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
 
        if (import_filename)
                import_marks(import_filename);
+       lastimportid = last_idnum;
 
        if (import_filename && revs.prune_data.nr)
                full_tree = 1;
@@ -706,7 +713,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
 
        handle_tags_and_duplicates(&extra_refs);
 
-       if (export_filename)
+       if (export_filename && lastimportid != last_idnum)
                export_marks(export_filename);
 
        if (use_done_feature)