Skip to content

Commit

Permalink
fast-import: add option command
Browse files Browse the repository at this point in the history
This allows the frontend to specify any of the supported options as
long as no non-option command has been given. This way the
user does not have to include any frontend-specific options, but
instead she can rely on the frontend to tell fast-import what it
needs.

Also factor out parsing of argv and have it execute when we reach the
first non-option command, or after all commands have been read and
no non-option command has been encountered.

Non-git options are ignored, unrecognised options result in an error.

Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Sverre Rabbelier authored and Junio C Hamano committed Dec 5, 2009
1 parent f963bd5 commit 9c8398f
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 25 deletions.
32 changes: 32 additions & 0 deletions Documentation/git-fast-import.txt
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,11 @@ and control the current import process. More detailed discussion
Require that fast-import supports the specified feature, or
abort if it does not.

`option`::
Specify any of the options listed under OPTIONS that do not
change stream semantic to suit the frontend's needs. This
command is optional and is not needed to perform an import.

`commit`
~~~~~~~~
Create or update a branch with a new commit, recording one logical
Expand Down Expand Up @@ -871,6 +876,33 @@ The following features are currently supported:
* export-marks
* force

`option`
~~~~~~~~
Processes the specified option so that git fast-import behaves in a
way that suits the frontend's needs.
Note that options specified by the frontend are overridden by any
options the user may specify to git fast-import itself.

....
'option' SP <option> LF
....

The `<option>` part of the command may contain any of the options
listed in the OPTIONS section that do not change import semantics,
without the leading '--' and is treated in the same way.

Option commands must be the first commands on the input (not counting
feature commands), to give an option command after any non-option
command is an error.

The following commandline options change import semantics and may therefore
not be passed as option:

* date-format
* import-marks
* export-marks
* force

Crash Reports
-------------
If fast-import is supplied invalid input it will terminate with a
Expand Down
87 changes: 62 additions & 25 deletions fast-import.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ static unsigned long branch_load_count;
static int failure;
static FILE *pack_edges;
static unsigned int show_stats = 1;
static int global_argc;
static const char **global_argv;

/* Memory pools */
static size_t mem_pool_alloc = 2*1024*1024 - sizeof(struct mem_pool);
Expand Down Expand Up @@ -355,6 +357,8 @@ static uintmax_t next_mark;
static struct strbuf new_data = STRBUF_INIT;
static int seen_data_command;

static void parse_argv(void);

static void write_branch_report(FILE *rpt, struct branch *b)
{
fprintf(rpt, "%s:\n", b->name);
Expand Down Expand Up @@ -1706,8 +1710,9 @@ static int read_next_command(void)
return EOF;

if (!seen_data_command
&& prefixcmp(command_buf.buf, "feature ")) {
seen_data_command = 1;
&& prefixcmp(command_buf.buf, "feature ")
&& prefixcmp(command_buf.buf, "option ")) {
parse_argv();
}

rc = rc_free;
Expand Down Expand Up @@ -2512,31 +2517,25 @@ static void option_export_pack_edges(const char *edges)
die_errno("Cannot open '%s'", edges);
}

static void parse_one_option(const char *option)
static int parse_one_option(const char *option)
{
if (!prefixcmp(option, "date-format=")) {
option_date_format(option + 12);
} else if (!prefixcmp(option, "max-pack-size=")) {
if (!prefixcmp(option, "max-pack-size=")) {
option_max_pack_size(option + 14);
} else if (!prefixcmp(option, "depth=")) {
option_depth(option + 6);
} else if (!prefixcmp(option, "active-branches=")) {
option_active_branches(option + 16);
} else if (!prefixcmp(option, "import-marks=")) {
option_import_marks(option + 13);
} else if (!prefixcmp(option, "export-marks=")) {
option_export_marks(option + 13);
} else if (!prefixcmp(option, "export-pack-edges=")) {
option_export_pack_edges(option + 18);
} else if (!prefixcmp(option, "force")) {
force_update = 1;
} else if (!prefixcmp(option, "quiet")) {
show_stats = 0;
} else if (!prefixcmp(option, "stats")) {
show_stats = 1;
} else {
die("Unsupported option: %s", option);
return 0;
}

return 1;
}

static int parse_one_feature(const char *feature)
Expand Down Expand Up @@ -2569,6 +2568,19 @@ static void parse_feature(void)
die("This version of fast-import does not support feature %s.", feature);
}

static void parse_option(void)
{
char *option = command_buf.buf + 11;

if (seen_data_command)
die("Got option command '%s' after data command", option);

if (parse_one_option(option))
return;

die("This version of fast-import does not support option: %s", option);
}

static int git_pack_config(const char *k, const char *v, void *cb)
{
if (!strcmp(k, "pack.depth")) {
Expand All @@ -2593,6 +2605,32 @@ static int git_pack_config(const char *k, const char *v, void *cb)
static const char fast_import_usage[] =
"git fast-import [--date-format=f] [--max-pack-size=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]";

static void parse_argv(void)
{
unsigned int i;

for (i = 1; i < global_argc; i++) {
const char *a = global_argv[i];

if (*a != '-' || !strcmp(a, "--"))
break;

if (parse_one_option(a + 2))
continue;

if (parse_one_feature(a + 2))
continue;

die("unknown option %s", a);
}
if (i != global_argc)
usage(fast_import_usage);

seen_data_command = 1;
if (import_marks_file)
read_marks();
}

int main(int argc, const char **argv)
{
unsigned int i;
Expand All @@ -2614,18 +2652,8 @@ int main(int argc, const char **argv)
avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*));
marks = pool_calloc(1, sizeof(struct mark_set));

for (i = 1; i < argc; i++) {
const char *a = argv[i];

if (*a != '-' || !strcmp(a, "--"))
break;

parse_one_option(a + 2);
}
if (i != argc)
usage(fast_import_usage);
if (import_marks_file)
read_marks();
global_argc = argc;
global_argv = argv;

rc_free = pool_alloc(cmd_save * sizeof(*rc_free));
for (i = 0; i < (cmd_save - 1); i++)
Expand All @@ -2650,9 +2678,18 @@ int main(int argc, const char **argv)
parse_progress();
else if (!prefixcmp(command_buf.buf, "feature "))
parse_feature();
else if (!prefixcmp(command_buf.buf, "option git "))
parse_option();
else if (!prefixcmp(command_buf.buf, "option "))
/* ignore non-git options*/;
else
die("Unsupported command: %s", command_buf.buf);
}

/* argv hasn't been parsed yet, do so */
if (!seen_data_command)
parse_argv();

end_packfile();

dump_branches();
Expand Down

0 comments on commit 9c8398f

Please sign in to comment.