Merge branch 'rr/rebase-stash-store'
[gitweb.git] / builtin / fast-export.c
index ed2916595fc386fe4127dc3fe9f68b85d15b3def..d1d68e9fc62889f647aff0005cc2ca2d3fef9d94 100644 (file)
@@ -24,7 +24,7 @@ static const char *fast_export_usage[] = {
 };
 
 static int progress;
-static enum { ABORT, VERBATIM, WARN, STRIP } signed_tag_mode = ABORT;
+static enum { ABORT, VERBATIM, WARN, WARN_STRIP, STRIP } signed_tag_mode = ABORT;
 static enum { ERROR, DROP, REWRITE } tag_of_filtered_mode = ERROR;
 static int fake_missing_tagger;
 static int use_done_feature;
@@ -40,10 +40,12 @@ static int parse_opt_signed_tag_mode(const struct option *opt,
                signed_tag_mode = VERBATIM;
        else if (!strcmp(arg, "warn"))
                signed_tag_mode = WARN;
+       else if (!strcmp(arg, "warn-strip"))
+               signed_tag_mode = WARN_STRIP;
        else if (!strcmp(arg, "strip"))
                signed_tag_mode = STRIP;
        else
-               return error("Unknown signed-tag mode: %s", arg);
+               return error("Unknown signed-tags mode: %s", arg);
        return 0;
 }
 
@@ -420,7 +422,7 @@ static void handle_tag(const char *name, struct tag *tag)
                        switch(signed_tag_mode) {
                        case ABORT:
                                die ("Encountered signed tag %s; use "
-                                    "--signed-tag=<mode> to handle it.",
+                                    "--signed-tags=<mode> to handle it.",
                                     sha1_to_hex(tag->object.sha1));
                        case WARN:
                                warning ("Exporting signed tag %s",
@@ -428,6 +430,10 @@ static void handle_tag(const char *name, struct tag *tag)
                                /* fallthru */
                        case VERBATIM:
                                break;
+                       case WARN_STRIP:
+                               warning ("Stripping signature from tag %s",
+                                        sha1_to_hex(tag->object.sha1));
+                               /* fallthru */
                        case STRIP:
                                message_size = signature + 1 - message;
                                break;
@@ -478,18 +484,21 @@ static void handle_tag(const char *name, struct tag *tag)
               (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;
 
@@ -527,10 +536,14 @@ static void get_tags_and_duplicates(struct object_array *pending,
                                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;
        }
 }
@@ -600,6 +613,8 @@ static void import_marks(char *input_file)
                char *line_end, *mark_end;
                unsigned char sha1[20];
                struct object *object;
+               struct commit *commit;
+               enum object_type type;
 
                line_end = strchr(line, '\n');
                if (line[0] != ':' || !line_end)
@@ -608,19 +623,30 @@ static void import_marks(char *input_file)
 
                mark = strtoumax(line + 1, &mark_end, 10);
                if (!mark || mark_end == line + 1
-                       || *mark_end != ' ' || get_sha1(mark_end + 1, sha1))
+                       || *mark_end != ' ' || get_sha1_hex(mark_end + 1, sha1))
                        die("corrupt mark line: %s", line);
 
-               object = parse_object(sha1);
-               if (!object)
-                       die ("Could not read blob %s", sha1_to_hex(sha1));
+               if (last_idnum < mark)
+                       last_idnum = mark;
+
+               type = sha1_object_info(sha1, NULL);
+               if (type < 0)
+                       die("object not found: %s", sha1_to_hex(sha1));
+
+               if (type != OBJ_COMMIT)
+                       /* only commits */
+                       continue;
+
+               commit = lookup_commit(sha1);
+               if (!commit)
+                       die("not a commit? can't happen: %s", sha1_to_hex(sha1));
+
+               object = &commit->object;
 
                if (object->flags & SHOWN)
                        error("Object %s already has a mark", sha1_to_hex(sha1));
 
                mark_object(object, mark);
-               if (last_idnum < mark)
-                       last_idnum = mark;
 
                object->flags |= SHOWN;
        }
@@ -634,6 +660,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")),
@@ -677,11 +704,12 @@ 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;
 
-       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");
@@ -699,7 +727,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)