fast-export: add new --refspec option

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>

Felipe Contreras committed Apr 20, 2014 at 13:59 UTC 03e9010c66adfe5e1693eae039e6754d925b7bf4
3 files changed +43
Documentation/git-fast-export.txt
+4
@@ -105,6 +105,10 @@ marks the same across runs.
105 in the commit (as opposed to just listing the files which are
106 different from the commit's first parent).
107
108 +--refspec::
109 + Apply the specified refspec to each ref exported. Multiple of them can
110 + be specified.
111 +
112 [<git-rev-list-args>...]::
113 A list of arguments, acceptable to 'git rev-parse' and
114 'git rev-list', that specifies the specific objects and references
builtin/fast-export.c
+32
@@ -17,6 +17,7 @@
17 #include "utf8.h"
18 #include "parse-options.h"
19 #include "quote.h"
20 +#include "remote.h"
21
22 static const char *fast_export_usage[] = {
23 N_("git fast-export [rev-list-opts]"),
@@ -31,6 +32,8 @@ static int use_done_feature;
32 static int no_data;
33 static int full_tree;
34 static struct string_list extra_refs = STRING_LIST_INIT_NODUP;
35 +static struct refspec *refspecs;
36 +static int refspecs_nr;
37
38 static int parse_opt_signed_tag_mode(const struct option *opt,
39 const char *arg, int unset)
@@ -525,6 +528,15 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
528 if (dwim_ref(e->name, strlen(e->name), sha1, &full_name) != 1)
529 continue;
530
531 + if (refspecs) {
532 + char *private;
533 + private = apply_refspecs(refspecs, refspecs_nr, full_name);
534 + if (private) {
535 + free(full_name);
536 + full_name = private;
537 + }
538 + }
539 +
540 commit = get_commit(e, full_name);
541 if (!commit) {
542 warning("%s: Unexpected object of type %s, skipping.",
@@ -668,6 +680,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
680 struct commit *commit;
681 char *export_filename = NULL, *import_filename = NULL;
682 uint32_t lastimportid;
683 + struct string_list refspecs_list = STRING_LIST_INIT_NODUP;
684 struct option options[] = {
685 OPT_INTEGER(0, "progress", &progress,
686 N_("show progress after <n> objects")),
@@ -688,6 +701,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
701 OPT_BOOL(0, "use-done-feature", &use_done_feature,
702 N_("Use the done feature to terminate the stream")),
703 OPT_BOOL(0, "no-data", &no_data, N_("Skip output of blob data")),
704 + OPT_STRING_LIST(0, "refspec", &refspecs_list, N_("refspec"),
705 + N_("Apply refspec to exported refs")),
706 OPT_END()
707 };
708
@@ -707,6 +722,21 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
722 if (argc > 1)
723 usage_with_options (fast_export_usage, options);
724
725 + if (refspecs_list.nr) {
726 + const char **refspecs_str;
727 + int i;
728 +
729 + refspecs_str = xmalloc(sizeof(*refspecs_str) * refspecs_list.nr);
730 + for (i = 0; i < refspecs_list.nr; i++)
731 + refspecs_str[i] = refspecs_list.items[i].string;
732 +
733 + refspecs_nr = refspecs_list.nr;
734 + refspecs = parse_fetch_refspec(refspecs_nr, refspecs_str);
735 +
736 + string_list_clear(&refspecs_list, 1);
737 + free(refspecs_str);
738 + }
739 +
740 if (use_done_feature)
741 printf("feature done\n");
742
@@ -741,5 +771,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
771 if (use_done_feature)
772 printf("done\n");
773
774 + free_refspec(refspecs_nr, refspecs);
775 +
776 return 0;
777 }
t/t9350-fast-export.sh
+7
@@ -504,4 +504,11 @@ test_expect_success 'refs are updated even if no commits need to be exported' '
504 test_cmp expected actual
505 '
506
507 +test_expect_success 'use refspec' '
508 + git fast-export --refspec refs/heads/master:refs/heads/foobar master | \
509 + grep "^commit " | sort | uniq > actual &&
510 + echo "commit refs/heads/foobar" > expected &&
511 + test_cmp expected actual
512 +'
513 +
514 test_done