Skip to content

Commit

Permalink
Make trailing LF following fast-import data commands optional
Browse files Browse the repository at this point in the history
A few fast-import frontend developers have found it odd that we
require the LF following a `data` command, especially in the exact
byte count format.  Technically we don't need this LF to parse
the stream properly, but having it here does make the stream more
readable to humans.  We can easily make the LF optional by peeking
at the next byte available from the stream and pushing it back into
the buffer if its not LF.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
  • Loading branch information
Shawn O. Pearce committed Aug 19, 2007
1 parent 401d53f commit 2c570cd
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 5 deletions.
10 changes: 9 additions & 1 deletion Documentation/git-fast-import.txt
Original file line number Diff line number Diff line change
Expand Up @@ -708,13 +708,18 @@ Exact byte count format::
+
....
'data' SP <count> LF
<raw> LF
<raw> LF?
....
+
where `<count>` is the exact number of bytes appearing within
`<raw>`. The value of `<count>` is expressed as an ASCII decimal
integer. The `LF` on either side of `<raw>` is not
included in `<count>` and will not be included in the imported data.
+
The `LF` after `<raw>` is optional (it used to be required) but
recommended. Always including it makes debugging a fast-import
stream easier as the next command always starts in column 0
of the next line, even if `<raw>` did not end with an `LF`.

Delimited format::
A delimiter string is used to mark the end of the data.
Expand All @@ -726,6 +731,7 @@ Delimited format::
'data' SP '<<' <delim> LF
<raw> LF
<delim> LF
LF?
....
+
where `<delim>` is the chosen delimiter string. The string `<delim>`
Expand All @@ -734,6 +740,8 @@ fast-import will think the data ends earlier than it really does. The `LF`
immediately trailing `<raw>` is part of `<raw>`. This is one of
the limitations of the delimited format, it is impossible to supply
a data chunk which does not have an LF as its last byte.
+
The `LF` after `<delim> LF` is optional (it used to be required).

`checkpoint`
~~~~~~~~~~~~
Expand Down
13 changes: 9 additions & 4 deletions fast-import.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Format of STDIN stream:
#
mark ::= 'mark' sp idnum lf;
data ::= (delimited_data | exact_data)
lf;
lf?;
# note: delim may be any string but must not contain lf.
# data_line may contain any data but must not be exactly
Expand Down Expand Up @@ -1470,6 +1470,13 @@ static void read_next_command(void)
} while (!command_buf.eof && command_buf.buf[0] == '#');
}

static void skip_optional_lf()
{
int term_char = fgetc(stdin);
if (term_char != '\n' && term_char != EOF)
ungetc(term_char, stdin);
}

static void cmd_mark(void)
{
if (!prefixcmp(command_buf.buf, "mark :")) {
Expand Down Expand Up @@ -1522,9 +1529,7 @@ static void *cmd_data (size_t *size)
}
}

if (fgetc(stdin) != '\n')
die("An lf did not trail the binary data as expected.");

skip_optional_lf();
*size = length;
return buffer;
}
Expand Down
21 changes: 21 additions & 0 deletions t/t9300-fast-import.sh
Original file line number Diff line number Diff line change
Expand Up @@ -818,4 +818,25 @@ test_expect_success \
'git-fast-import <input &&
test `git-rev-parse N3` = `git-rev-parse O1`'

cat >input <<INPUT_END
commit refs/heads/O2
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
dirty directory copy
COMMIT
from refs/heads/branch^0
M 644 inline file2/file5
data <<EOF
$file5_data
EOF
C file2 file3
D file2/file5
INPUT_END

test_expect_success \
'O: blank lines not necessary after data commands' \
'git-fast-import <input &&
test `git-rev-parse N3` = `git-rev-parse O2`'

test_done

0 comments on commit 2c570cd

Please sign in to comment.