Skip to content

Commit 03e9010

Browse files
felipecgitster
authored andcommitted
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>
1 parent 8b2f86a commit 03e9010

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

Documentation/git-fast-export.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ marks the same across runs.
105105
in the commit (as opposed to just listing the files which are
106106
different from the commit's first parent).
107107

108+
--refspec::
109+
Apply the specified refspec to each ref exported. Multiple of them can
110+
be specified.
111+
108112
[<git-rev-list-args>...]::
109113
A list of arguments, acceptable to 'git rev-parse' and
110114
'git rev-list', that specifies the specific objects and references

builtin/fast-export.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "utf8.h"
1818
#include "parse-options.h"
1919
#include "quote.h"
20+
#include "remote.h"
2021

2122
static const char *fast_export_usage[] = {
2223
N_("git fast-export [rev-list-opts]"),
@@ -31,6 +32,8 @@ static int use_done_feature;
3132
static int no_data;
3233
static int full_tree;
3334
static struct string_list extra_refs = STRING_LIST_INIT_NODUP;
35+
static struct refspec *refspecs;
36+
static int refspecs_nr;
3437

3538
static int parse_opt_signed_tag_mode(const struct option *opt,
3639
const char *arg, int unset)
@@ -525,6 +528,15 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
525528
if (dwim_ref(e->name, strlen(e->name), sha1, &full_name) != 1)
526529
continue;
527530

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+
528540
commit = get_commit(e, full_name);
529541
if (!commit) {
530542
warning("%s: Unexpected object of type %s, skipping.",
@@ -668,6 +680,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
668680
struct commit *commit;
669681
char *export_filename = NULL, *import_filename = NULL;
670682
uint32_t lastimportid;
683+
struct string_list refspecs_list = STRING_LIST_INIT_NODUP;
671684
struct option options[] = {
672685
OPT_INTEGER(0, "progress", &progress,
673686
N_("show progress after <n> objects")),
@@ -688,6 +701,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
688701
OPT_BOOL(0, "use-done-feature", &use_done_feature,
689702
N_("Use the done feature to terminate the stream")),
690703
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")),
691706
OPT_END()
692707
};
693708

@@ -707,6 +722,21 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
707722
if (argc > 1)
708723
usage_with_options (fast_export_usage, options);
709724

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+
710740
if (use_done_feature)
711741
printf("feature done\n");
712742

@@ -741,5 +771,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
741771
if (use_done_feature)
742772
printf("done\n");
743773

774+
free_refspec(refspecs_nr, refspecs);
775+
744776
return 0;
745777
}

t/t9350-fast-export.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,4 +504,11 @@ test_expect_success 'refs are updated even if no commits need to be exported' '
504504
test_cmp expected actual
505505
'
506506

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+
507514
test_done

0 commit comments

Comments
 (0)