Merge branch 'di/fast-import-ident'

* di/fast-import-ident:
  fsck: improve committer/author check
  fsck: add a few committer name tests
  fast-import: check committer name more strictly
  fast-import: don't fail on omitted committer name
  fast-import: add input format tests
This commit is contained in:
Junio C Hamano 2011-08-28 21:18:47 -07:00
commit 0b98954975
5 changed files with 164 additions and 18 deletions

View file

@ -425,8 +425,8 @@ Here `<name>` is the person's display name (for example
(``cm@example.com''). `LT` and `GT` are the literal less-than (\x3c)
and greater-than (\x3e) symbols. These are required to delimit
the email address from the other fields in the line. Note that
`<name>` is free-form and may contain any sequence of bytes, except
`LT` and `LF`. It is typically UTF-8 encoded.
`<name>` and `<email>` are free-form and may contain any sequence
of bytes, except `LT`, `GT` and `LF`. `<name>` is typically UTF-8 encoded.
The time of the change is specified by `<when>` using the date format
that was selected by the \--date-format=<fmt> command line option.

View file

@ -1969,32 +1969,41 @@ static int validate_raw_date(const char *src, char *result, int maxlen)
static char *parse_ident(const char *buf)
{
const char *gt;
const char *ltgt;
size_t name_len;
char *ident;
gt = strrchr(buf, '>');
if (!gt)
/* ensure there is a space delimiter even if there is no name */
if (*buf == '<')
--buf;
ltgt = buf + strcspn(buf, "<>");
if (*ltgt != '<')
die("Missing < in ident string: %s", buf);
if (ltgt != buf && ltgt[-1] != ' ')
die("Missing space before < in ident string: %s", buf);
ltgt = ltgt + 1 + strcspn(ltgt + 1, "<>");
if (*ltgt != '>')
die("Missing > in ident string: %s", buf);
gt++;
if (*gt != ' ')
ltgt++;
if (*ltgt != ' ')
die("Missing space after > in ident string: %s", buf);
gt++;
name_len = gt - buf;
ltgt++;
name_len = ltgt - buf;
ident = xmalloc(name_len + 24);
strncpy(ident, buf, name_len);
switch (whenspec) {
case WHENSPEC_RAW:
if (validate_raw_date(gt, ident + name_len, 24) < 0)
die("Invalid raw date \"%s\" in ident: %s", gt, buf);
if (validate_raw_date(ltgt, ident + name_len, 24) < 0)
die("Invalid raw date \"%s\" in ident: %s", ltgt, buf);
break;
case WHENSPEC_RFC2822:
if (parse_date(gt, ident + name_len, 24) < 0)
die("Invalid rfc2822 date \"%s\" in ident: %s", gt, buf);
if (parse_date(ltgt, ident + name_len, 24) < 0)
die("Invalid rfc2822 date \"%s\" in ident: %s", ltgt, buf);
break;
case WHENSPEC_NOW:
if (strcmp("now", gt))
if (strcmp("now", ltgt))
die("Date in ident must be 'now': %s", buf);
datestamp(ident + name_len, 24);
break;

10
fsck.c
View file

@ -224,13 +224,15 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
static int fsck_ident(char **ident, struct object *obj, fsck_error error_func)
{
if (**ident == '<' || **ident == '\n')
return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
*ident += strcspn(*ident, "<\n");
if ((*ident)[-1] != ' ')
if (**ident == '<')
return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
*ident += strcspn(*ident, "<>\n");
if (**ident == '>')
return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad name");
if (**ident != '<')
return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing email");
if ((*ident)[-1] != ' ')
return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
(*ident)++;
*ident += strcspn(*ident, "<>\n");
if (**ident != '>')

View file

@ -110,6 +110,42 @@ test_expect_success 'email with embedded > is not okay' '
grep "error in commit $new" out
'
test_expect_success 'missing < email delimiter is reported nicely' '
git cat-file commit HEAD >basis &&
sed "s/<//" basis >bad-email-2 &&
new=$(git hash-object -t commit -w --stdin <bad-email-2) &&
test_when_finished "remove_object $new" &&
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
git fsck 2>out &&
cat out &&
grep "error in commit $new.* - bad name" out
'
test_expect_success 'missing email is reported nicely' '
git cat-file commit HEAD >basis &&
sed "s/[a-z]* <[^>]*>//" basis >bad-email-3 &&
new=$(git hash-object -t commit -w --stdin <bad-email-3) &&
test_when_finished "remove_object $new" &&
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
git fsck 2>out &&
cat out &&
grep "error in commit $new.* - missing email" out
'
test_expect_success '> in name is reported' '
git cat-file commit HEAD >basis &&
sed "s/ </> </" basis >bad-email-4 &&
new=$(git hash-object -t commit -w --stdin <bad-email-4) &&
test_when_finished "remove_object $new" &&
git update-ref refs/heads/bogus "$new" &&
test_when_finished "git update-ref -d refs/heads/bogus" &&
git fsck 2>out &&
cat out &&
grep "error in commit $new" out
'
test_expect_success 'tag pointing to nonexistent' '
cat >invalid-tag <<-\EOF &&
object ffffffffffffffffffffffffffffffffffffffff

View file

@ -324,6 +324,105 @@ test_expect_success \
test `git rev-parse master` = `git rev-parse TEMP_TAG^`'
rm -f .git/TEMP_TAG
git gc 2>/dev/null >/dev/null
git prune 2>/dev/null >/dev/null
cat >input <<INPUT_END
commit refs/heads/empty-committer-1
committer <> $GIT_COMMITTER_DATE
data <<COMMIT
empty commit
COMMIT
INPUT_END
test_expect_success 'B: accept empty committer' '
git fast-import <input &&
out=$(git fsck) &&
echo "$out" &&
test -z "$out"
'
git update-ref -d refs/heads/empty-committer-1 || true
git gc 2>/dev/null >/dev/null
git prune 2>/dev/null >/dev/null
cat >input <<INPUT_END
commit refs/heads/empty-committer-2
committer <a@b.com> $GIT_COMMITTER_DATE
data <<COMMIT
empty commit
COMMIT
INPUT_END
test_expect_success 'B: accept and fixup committer with no name' '
git fast-import <input &&
out=$(git fsck) &&
echo "$out" &&
test -z "$out"
'
git update-ref -d refs/heads/empty-committer-2 || true
git gc 2>/dev/null >/dev/null
git prune 2>/dev/null >/dev/null
cat >input <<INPUT_END
commit refs/heads/invalid-committer
committer Name email> $GIT_COMMITTER_DATE
data <<COMMIT
empty commit
COMMIT
INPUT_END
test_expect_success 'B: fail on invalid committer (1)' '
test_must_fail git fast-import <input
'
git update-ref -d refs/heads/invalid-committer || true
cat >input <<INPUT_END
commit refs/heads/invalid-committer
committer Name <e<mail> $GIT_COMMITTER_DATE
data <<COMMIT
empty commit
COMMIT
INPUT_END
test_expect_success 'B: fail on invalid committer (2)' '
test_must_fail git fast-import <input
'
git update-ref -d refs/heads/invalid-committer || true
cat >input <<INPUT_END
commit refs/heads/invalid-committer
committer Name <email>> $GIT_COMMITTER_DATE
data <<COMMIT
empty commit
COMMIT
INPUT_END
test_expect_success 'B: fail on invalid committer (3)' '
test_must_fail git fast-import <input
'
git update-ref -d refs/heads/invalid-committer || true
cat >input <<INPUT_END
commit refs/heads/invalid-committer
committer Name <email $GIT_COMMITTER_DATE
data <<COMMIT
empty commit
COMMIT
INPUT_END
test_expect_success 'B: fail on invalid committer (4)' '
test_must_fail git fast-import <input
'
git update-ref -d refs/heads/invalid-committer || true
cat >input <<INPUT_END
commit refs/heads/invalid-committer
committer Name<email> $GIT_COMMITTER_DATE
data <<COMMIT
empty commit
COMMIT
INPUT_END
test_expect_success 'B: fail on invalid committer (5)' '
test_must_fail git fast-import <input
'
git update-ref -d refs/heads/invalid-committer || true
###
### series C
###