fast-export: add new --refspec option
authorFelipe Contreras <felipe.contreras@gmail.com>
Sun, 20 Apr 2014 18:59:24 +0000 (13:59 -0500)
committerJunio C Hamano <gitster@pobox.com>
Mon, 21 Apr 2014 18:47:33 +0000 (11:47 -0700)
So that we can convert the exported ref names.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-fast-export.txt
builtin/fast-export.c
t/t9350-fast-export.sh
index 85f1f30fdf5c0a741c3c575bfa393fc7d88d308f..221506b04ba55fac2151d8ac95da7df57eb9d411 100644 (file)
@@ -105,6 +105,10 @@ marks the same across runs.
        in the commit (as opposed to just listing the files which are
        different from the commit's first parent).
 
        in the commit (as opposed to just listing the files which are
        different from the commit's first parent).
 
+--refspec::
+       Apply the specified refspec to each ref exported. Multiple of them can
+       be specified.
+
 [<git-rev-list-args>...]::
        A list of arguments, acceptable to 'git rev-parse' and
        'git rev-list', that specifies the specific objects and references
 [<git-rev-list-args>...]::
        A list of arguments, acceptable to 'git rev-parse' and
        'git rev-list', that specifies the specific objects and references
index bc3490cd56ebeaae7322261766be460d09646b5b..ad9c17e8e78bb86066aea807d8e0ce9ba68c5897 100644 (file)
@@ -17,6 +17,7 @@
 #include "utf8.h"
 #include "parse-options.h"
 #include "quote.h"
 #include "utf8.h"
 #include "parse-options.h"
 #include "quote.h"
+#include "remote.h"
 
 static const char *fast_export_usage[] = {
        N_("git fast-export [rev-list-opts]"),
 
 static const char *fast_export_usage[] = {
        N_("git fast-export [rev-list-opts]"),
@@ -31,6 +32,8 @@ static int use_done_feature;
 static int no_data;
 static int full_tree;
 static struct string_list extra_refs = STRING_LIST_INIT_NODUP;
 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 int parse_opt_signed_tag_mode(const struct option *opt,
                                     const char *arg, int unset)
 
 static int parse_opt_signed_tag_mode(const struct option *opt,
                                     const char *arg, int unset)
@@ -525,6 +528,15 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
                if (dwim_ref(e->name, strlen(e->name), sha1, &full_name) != 1)
                        continue;
 
                if (dwim_ref(e->name, strlen(e->name), sha1, &full_name) != 1)
                        continue;
 
+               if (refspecs) {
+                       char *private;
+                       private = apply_refspecs(refspecs, refspecs_nr, full_name);
+                       if (private) {
+                               free(full_name);
+                               full_name = private;
+                       }
+               }
+
                commit = get_commit(e, full_name);
                if (!commit) {
                        warning("%s: Unexpected object of type %s, skipping.",
                commit = get_commit(e, full_name);
                if (!commit) {
                        warning("%s: Unexpected object of type %s, skipping.",
@@ -668,6 +680,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
        struct commit *commit;
        char *export_filename = NULL, *import_filename = NULL;
        uint32_t lastimportid;
        struct commit *commit;
        char *export_filename = NULL, *import_filename = NULL;
        uint32_t lastimportid;
+       struct string_list refspecs_list = STRING_LIST_INIT_NODUP;
        struct option options[] = {
                OPT_INTEGER(0, "progress", &progress,
                            N_("show progress after <n> objects")),
        struct option options[] = {
                OPT_INTEGER(0, "progress", &progress,
                            N_("show progress after <n> objects")),
@@ -688,6 +701,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
                OPT_BOOL(0, "use-done-feature", &use_done_feature,
                             N_("Use the done feature to terminate the stream")),
                OPT_BOOL(0, "no-data", &no_data, N_("Skip output of blob data")),
                OPT_BOOL(0, "use-done-feature", &use_done_feature,
                             N_("Use the done feature to terminate the stream")),
                OPT_BOOL(0, "no-data", &no_data, N_("Skip output of blob data")),
+               OPT_STRING_LIST(0, "refspec", &refspecs_list, N_("refspec"),
+                            N_("Apply refspec to exported refs")),
                OPT_END()
        };
 
                OPT_END()
        };
 
@@ -707,6 +722,21 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
        if (argc > 1)
                usage_with_options (fast_export_usage, options);
 
        if (argc > 1)
                usage_with_options (fast_export_usage, options);
 
+       if (refspecs_list.nr) {
+               const char **refspecs_str;
+               int i;
+
+               refspecs_str = xmalloc(sizeof(*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);
+
+               string_list_clear(&refspecs_list, 1);
+               free(refspecs_str);
+       }
+
        if (use_done_feature)
                printf("feature done\n");
 
        if (use_done_feature)
                printf("feature done\n");
 
@@ -741,5 +771,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
        if (use_done_feature)
                printf("done\n");
 
        if (use_done_feature)
                printf("done\n");
 
+       free_refspec(refspecs_nr, refspecs);
+
        return 0;
 }
        return 0;
 }
index 2312dec8f096fe7e36feeabd0e1cd85b5e421d4a..3d475af173fffbc0b85f8cbc9950bcec58b9daa5 100755 (executable)
@@ -504,4 +504,11 @@ test_expect_success 'refs are updated even if no commits need to be exported' '
        test_cmp expected actual
 '
 
        test_cmp expected actual
 '
 
+test_expect_success 'use refspec' '
+       git fast-export --refspec refs/heads/master:refs/heads/foobar master | \
+               grep "^commit " | sort | uniq > actual &&
+       echo "commit refs/heads/foobar" > expected &&
+       test_cmp expected actual
+'
+
 test_done
 test_done