зеркало из https://github.com/microsoft/git.git
fast-import: introduce 'done' command
Add a 'done' command that causes fast-import to stop reading from the stream and exit. If the new --done command line flag was passed on the command line (or a "feature done" declaration included at the start of the stream), make the 'done' command mandatory. So "git fast-import --done"'s input format will be prefix-free, making errors easier to detect when they show up as early termination at some convenient time of the upstream of a pipe writing to fast-import. Another possible application of the 'done' command would to be allow a fast-import stream that is only a small part of a larger encapsulating stream to be easily parsed, leaving the file offset after the "done\n" so the other application can pick up from there. This patch does not teach fast-import to do that --- fast-import still uses buffered input (stdio). Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com> Acked-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
460d10262d
Коммит
be56862f19
|
@ -101,6 +101,12 @@ OPTIONS
|
||||||
when the `cat-blob` command is encountered in the stream.
|
when the `cat-blob` command is encountered in the stream.
|
||||||
The default behaviour is to write to `stdout`.
|
The default behaviour is to write to `stdout`.
|
||||||
|
|
||||||
|
--done::
|
||||||
|
Require a `done` command at the end of the stream.
|
||||||
|
This option might be useful for detecting errors that
|
||||||
|
cause the frontend to terminate before it has started to
|
||||||
|
write a stream.
|
||||||
|
|
||||||
--export-pack-edges=<file>::
|
--export-pack-edges=<file>::
|
||||||
After creating a packfile, print a line of data to
|
After creating a packfile, print a line of data to
|
||||||
<file> listing the filename of the packfile and the last
|
<file> listing the filename of the packfile and the last
|
||||||
|
@ -330,6 +336,11 @@ and control the current import process. More detailed discussion
|
||||||
standard output. This command is optional and is not needed
|
standard output. This command is optional and is not needed
|
||||||
to perform an import.
|
to perform an import.
|
||||||
|
|
||||||
|
`done`::
|
||||||
|
Marks the end of the stream. This command is optional
|
||||||
|
unless the `done` feature was requested using the
|
||||||
|
`--done` command line option or `feature done` command.
|
||||||
|
|
||||||
`cat-blob`::
|
`cat-blob`::
|
||||||
Causes fast-import to print a blob in 'cat-file --batch'
|
Causes fast-import to print a blob in 'cat-file --batch'
|
||||||
format to the file descriptor set with `--cat-blob-fd` or
|
format to the file descriptor set with `--cat-blob-fd` or
|
||||||
|
@ -1015,6 +1026,11 @@ notes::
|
||||||
Versions of fast-import not supporting notes will exit
|
Versions of fast-import not supporting notes will exit
|
||||||
with a message indicating so.
|
with a message indicating so.
|
||||||
|
|
||||||
|
done::
|
||||||
|
Error out if the stream ends without a 'done' command.
|
||||||
|
Without this feature, errors causing the frontend to end
|
||||||
|
abruptly at a convenient point in the stream can go
|
||||||
|
undetected.
|
||||||
|
|
||||||
`option`
|
`option`
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
@ -1044,6 +1060,15 @@ not be passed as option:
|
||||||
* cat-blob-fd
|
* cat-blob-fd
|
||||||
* force
|
* force
|
||||||
|
|
||||||
|
`done`
|
||||||
|
~~~~~~
|
||||||
|
If the `done` feature is not in use, treated as if EOF was read.
|
||||||
|
This can be used to tell fast-import to finish early.
|
||||||
|
|
||||||
|
If the `--done` command line option or `feature done` command is
|
||||||
|
in use, the `done` command is mandatory and marks the end of the
|
||||||
|
stream.
|
||||||
|
|
||||||
Crash Reports
|
Crash Reports
|
||||||
-------------
|
-------------
|
||||||
If fast-import is supplied invalid input it will terminate with a
|
If fast-import is supplied invalid input it will terminate with a
|
||||||
|
|
|
@ -354,6 +354,7 @@ static unsigned int cmd_save = 100;
|
||||||
static uintmax_t next_mark;
|
static uintmax_t next_mark;
|
||||||
static struct strbuf new_data = STRBUF_INIT;
|
static struct strbuf new_data = STRBUF_INIT;
|
||||||
static int seen_data_command;
|
static int seen_data_command;
|
||||||
|
static int require_explicit_termination;
|
||||||
|
|
||||||
/* Signal handling */
|
/* Signal handling */
|
||||||
static volatile sig_atomic_t checkpoint_requested;
|
static volatile sig_atomic_t checkpoint_requested;
|
||||||
|
@ -3139,6 +3140,8 @@ static int parse_one_feature(const char *feature, int from_stream)
|
||||||
relative_marks_paths = 1;
|
relative_marks_paths = 1;
|
||||||
} else if (!strcmp(feature, "no-relative-marks")) {
|
} else if (!strcmp(feature, "no-relative-marks")) {
|
||||||
relative_marks_paths = 0;
|
relative_marks_paths = 0;
|
||||||
|
} else if (!strcmp(feature, "done")) {
|
||||||
|
require_explicit_termination = 1;
|
||||||
} else if (!strcmp(feature, "force")) {
|
} else if (!strcmp(feature, "force")) {
|
||||||
force_update = 1;
|
force_update = 1;
|
||||||
} else if (!strcmp(feature, "notes") || !strcmp(feature, "ls")) {
|
} else if (!strcmp(feature, "notes") || !strcmp(feature, "ls")) {
|
||||||
|
@ -3288,6 +3291,8 @@ int main(int argc, const char **argv)
|
||||||
parse_reset_branch();
|
parse_reset_branch();
|
||||||
else if (!strcmp("checkpoint", command_buf.buf))
|
else if (!strcmp("checkpoint", command_buf.buf))
|
||||||
parse_checkpoint();
|
parse_checkpoint();
|
||||||
|
else if (!strcmp("done", command_buf.buf))
|
||||||
|
break;
|
||||||
else if (!prefixcmp(command_buf.buf, "progress "))
|
else if (!prefixcmp(command_buf.buf, "progress "))
|
||||||
parse_progress();
|
parse_progress();
|
||||||
else if (!prefixcmp(command_buf.buf, "feature "))
|
else if (!prefixcmp(command_buf.buf, "feature "))
|
||||||
|
@ -3307,6 +3312,9 @@ int main(int argc, const char **argv)
|
||||||
if (!seen_data_command)
|
if (!seen_data_command)
|
||||||
parse_argv();
|
parse_argv();
|
||||||
|
|
||||||
|
if (require_explicit_termination && feof(stdin))
|
||||||
|
die("stream ends early");
|
||||||
|
|
||||||
end_packfile();
|
end_packfile();
|
||||||
|
|
||||||
dump_branches();
|
dump_branches();
|
||||||
|
|
|
@ -2197,6 +2197,48 @@ test_expect_success 'R: quiet option results in no stats being output' '
|
||||||
test_cmp empty output
|
test_cmp empty output
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'R: feature done means terminating "done" is mandatory' '
|
||||||
|
echo feature done | test_must_fail git fast-import &&
|
||||||
|
test_must_fail git fast-import --done </dev/null
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'R: terminating "done" with trailing gibberish is ok' '
|
||||||
|
git fast-import <<-\EOF &&
|
||||||
|
feature done
|
||||||
|
done
|
||||||
|
trailing gibberish
|
||||||
|
EOF
|
||||||
|
git fast-import <<-\EOF
|
||||||
|
done
|
||||||
|
more trailing gibberish
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'R: terminating "done" within commit' '
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
OBJID
|
||||||
|
:000000 100644 OBJID OBJID A hello.c
|
||||||
|
:000000 100644 OBJID OBJID A hello2.c
|
||||||
|
EOF
|
||||||
|
git fast-import <<-EOF &&
|
||||||
|
commit refs/heads/done-ends
|
||||||
|
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
|
||||||
|
data <<EOT
|
||||||
|
Commit terminated by "done" command
|
||||||
|
EOT
|
||||||
|
M 100644 inline hello.c
|
||||||
|
data <<EOT
|
||||||
|
Hello, world.
|
||||||
|
EOT
|
||||||
|
C hello.c hello2.c
|
||||||
|
done
|
||||||
|
EOF
|
||||||
|
git rev-list done-ends |
|
||||||
|
git diff-tree -r --stdin --root --always |
|
||||||
|
sed -e "s/$_x40/OBJID/g" >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
option git non-existing-option
|
option git non-existing-option
|
||||||
EOF
|
EOF
|
||||||
|
|
Загрузка…
Ссылка в новой задаче