Merge branch 'jk/show-index'
[gitweb.git] / builtin / fast-export.c
index 68a762fbeaa1363d6b0d709f1500b1925796a711..73d12c1020c4c13ff00210ad4eafc028bd33b322 100644 (file)
@@ -7,6 +7,7 @@
 #include "cache.h"
 #include "config.h"
 #include "refs.h"
+#include "refspec.h"
 #include "commit.h"
 #include "object.h"
 #include "tag.h"
@@ -21,6 +22,7 @@
 #include "quote.h"
 #include "remote.h"
 #include "blob.h"
+#include "commit-slab.h"
 
 static const char *fast_export_usage[] = {
        N_("git fast-export [rev-list-opts]"),
@@ -35,9 +37,9 @@ static int use_done_feature;
 static int no_data;
 static int full_tree;
 static struct string_list extra_refs = STRING_LIST_INIT_NODUP;
-static struct refspec *refspecs;
-static int refspecs_nr;
+static struct refspec refspecs = REFSPEC_INIT_FETCH;
 static int anonymize;
+static struct revision_sources revision_sources;
 
 static int parse_opt_signed_tag_mode(const struct option *opt,
                                     const char *arg, int unset)
@@ -156,15 +158,14 @@ static void anonymize_path(struct strbuf *out, const char *path,
        }
 }
 
-/* Since intptr_t is C99, we do not use it here */
-static inline uint32_t *mark_to_ptr(uint32_t mark)
+static inline void *mark_to_ptr(uint32_t mark)
 {
-       return ((uint32_t *)NULL) + mark;
+       return (void *)(uintptr_t)mark;
 }
 
 static inline uint32_t ptr_to_mark(void * mark)
 {
-       return (uint32_t *)mark - (uint32_t *)NULL;
+       return (uint32_t)(uintptr_t)mark;
 }
 
 static inline void mark_object(struct object *object, uint32_t mark)
@@ -517,7 +518,7 @@ static void anonymize_ident_line(const char **beg, const char **end)
        /* skip "committer", "author", "tagger", etc */
        end_of_header = strchr(*beg, ' ');
        if (!end_of_header)
-               die("BUG: malformed line fed to anonymize_ident_line: %.*s",
+               BUG("malformed line fed to anonymize_ident_line: %.*s",
                    (int)(*end - *beg), *beg);
        end_of_header++;
        strbuf_add(out, *beg, end_of_header - *beg);
@@ -590,7 +591,7 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
                if (!S_ISGITLINK(diff_queued_diff.queue[i]->two->mode))
                        export_blob(&diff_queued_diff.queue[i]->two->oid);
 
-       refname = commit->util;
+       refname = *revision_sources_at(&revision_sources, commit);
        if (anonymize) {
                refname = anonymize_refname(refname);
                anonymize_ident_line(&committer, &committer_end);
@@ -829,9 +830,9 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
                if (dwim_ref(e->name, strlen(e->name), &oid, &full_name) != 1)
                        continue;
 
-               if (refspecs) {
+               if (refspecs.nr) {
                        char *private;
-                       private = apply_refspecs(refspecs, refspecs_nr, full_name);
+                       private = apply_refspecs(&refspecs, full_name);
                        if (private) {
                                free(full_name);
                                full_name = private;
@@ -862,10 +863,11 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
                 * This ref will not be updated through a commit, lets make
                 * sure it gets properly updated eventually.
                 */
-               if (commit->util || commit->object.flags & SHOWN)
+               if (*revision_sources_at(&revision_sources, commit) ||
+                   commit->object.flags & SHOWN)
                        string_list_append(&extra_refs, full_name)->util = commit;
-               if (!commit->util)
-                       commit->util = full_name;
+               if (!*revision_sources_at(&revision_sources, commit))
+                       *revision_sources_at(&revision_sources, commit) = full_name;
        }
 }
 
@@ -977,8 +979,8 @@ static void import_marks(char *input_file)
 static void handle_deletes(void)
 {
        int i;
-       for (i = 0; i < refspecs_nr; i++) {
-               struct refspec *refspec = &refspecs[i];
+       for (i = 0; i < refspecs.nr; i++) {
+               struct refspec_item *refspec = &refspecs.items[i];
                if (*refspec->src)
                        continue;
 
@@ -1029,8 +1031,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
        git_config(git_default_config, NULL);
 
        init_revisions(&revs, prefix);
+       init_revision_sources(&revision_sources);
        revs.topo_order = 1;
-       revs.show_source = 1;
+       revs.sources = &revision_sources;
        revs.rewrite_parents = 1;
        argc = parse_options(argc, argv, prefix, options, fast_export_usage,
                        PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN);
@@ -1039,18 +1042,12 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
                usage_with_options (fast_export_usage, options);
 
        if (refspecs_list.nr) {
-               const char **refspecs_str;
                int i;
 
-               ALLOC_ARRAY(refspecs_str, refspecs_list.nr);
                for (i = 0; i < refspecs_list.nr; i++)
-                       refspecs_str[i] = refspecs_list.items[i].string;
-
-               refspecs_nr = refspecs_list.nr;
-               refspecs = parse_fetch_refspec(refspecs_nr, refspecs_str);
+                       refspec_append(&refspecs, refspecs_list.items[i].string);
 
                string_list_clear(&refspecs_list, 1);
-               free(refspecs_str);
        }
 
        if (use_done_feature)
@@ -1089,7 +1086,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
        if (use_done_feature)
                printf("done\n");
 
-       free_refspec(refspecs_nr, refspecs);
+       refspec_clear(&refspecs);
 
        return 0;
 }