Skip to content

Commit

Permalink
commit --amend: cope with missing display name
Browse files Browse the repository at this point in the history
Though I have not seen this in the wild, it has been said that there
are likely to be git repositories converted from other version control
systems with an invalid ident line like this one:

  author <user@example.com> 18746342 +0000

Because there is no space between the (empty) user name and the email
address, commit --amend chokes.  When searching for a
space-left-bracket sequence on the ident line, it finds it in the
committer line, ending up utterly confused.

Better for commit --amend to treat this like a valid ident line with
empty username and complain.

The tests remove the questionable commit objects after use so there is
no chance for them to confuse later tests.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jonathan Nieder authored and Junio C Hamano committed May 4, 2010
1 parent 3bf7886 commit fb7749e
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 7 deletions.
20 changes: 13 additions & 7 deletions builtin/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,15 +455,21 @@ static void determine_author_info(void)
if (!a)
die("invalid commit: %s", use_message);

lb = strstr(a + 8, " <");
rb = strstr(a + 8, "> ");
eol = strchr(a + 8, '\n');
if (!lb || !rb || !eol)
lb = strchrnul(a + strlen("\nauthor "), '<');
rb = strchrnul(lb, '>');
eol = strchrnul(rb, '\n');
if (!*lb || !*rb || !*eol)
die("invalid commit: %s", use_message);

name = xstrndup(a + 8, lb - (a + 8));
email = xstrndup(lb + 2, rb - (lb + 2));
date = xstrndup(rb + 2, eol - (rb + 2));
if (lb == a + strlen("\nauthor "))
/* \nauthor <foo@example.com> */
name = xcalloc(1, 1);
else
name = xmemdupz(a + strlen("\nauthor "),
(lb - strlen(" ") -
(a + strlen("\nauthor "))));
email = xmemdupz(lb + strlen("<"), rb - (lb + strlen("<")));
date = xmemdupz(rb + strlen("> "), eol - (rb + strlen("> ")));
}

if (force_author) {
Expand Down
46 changes: 46 additions & 0 deletions t/t7509-commit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,52 @@ test_expect_success '--amend option copies authorship' '
test_cmp expect actual
'

sha1_file() {
echo "$*" | sed "s#..#.git/objects/&/#"
}
remove_object() {
rm -f $(sha1_file "$*")
}
no_reflog() {
cp .git/config .git/config.saved &&
echo "[core] logallrefupdates = false" >>.git/config &&
test_when_finished "mv -f .git/config.saved .git/config" &&

if test -e .git/logs
then
mv .git/logs . &&
test_when_finished "mv logs .git/"
fi
}

test_expect_success '--amend option with empty author' '
git cat-file commit Initial >tmp &&
sed "s/author [^<]* </author </" tmp >empty-author &&
no_reflog &&
sha=$(git hash-object -t commit -w empty-author) &&
test_when_finished "remove_object $sha" &&
git checkout $sha &&
test_when_finished "git checkout Initial" &&
echo "Empty author test" >>foo &&
test_tick &&
! git commit -a -m "empty author" --amend 2>err &&
grep "empty ident" err
'

test_expect_success '--amend option with missing author' '
git cat-file commit Initial >tmp &&
sed "s/author [^<]* </author </" tmp >malformed &&
no_reflog &&
sha=$(git hash-object -t commit -w malformed) &&
test_when_finished "remove_object $sha" &&
git checkout $sha &&
test_when_finished "git checkout Initial" &&
echo "Missing author test" >>foo &&
test_tick &&
! git commit -a -m "malformed author" --amend 2>err &&
grep "empty ident" err
'

test_expect_success '--reset-author makes the commit ours even with --amend option' '
git checkout Initial &&
echo "Test 6" >>foo &&
Expand Down

0 comments on commit fb7749e

Please sign in to comment.