Skip to content

Commit fb7749e

Browse files
jrngitster
authored andcommitted
commit --amend: cope with missing display name
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 <[email protected]> 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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3bf7886 commit fb7749e

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

builtin/commit.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -455,15 +455,21 @@ static void determine_author_info(void)
455455
if (!a)
456456
die("invalid commit: %s", use_message);
457457

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

464-
name = xstrndup(a + 8, lb - (a + 8));
465-
email = xstrndup(lb + 2, rb - (lb + 2));
466-
date = xstrndup(rb + 2, eol - (rb + 2));
464+
if (lb == a + strlen("\nauthor "))
465+
/* \nauthor <[email protected]> */
466+
name = xcalloc(1, 1);
467+
else
468+
name = xmemdupz(a + strlen("\nauthor "),
469+
(lb - strlen(" ") -
470+
(a + strlen("\nauthor "))));
471+
email = xmemdupz(lb + strlen("<"), rb - (lb + strlen("<")));
472+
date = xmemdupz(rb + strlen("> "), eol - (rb + strlen("> ")));
467473
}
468474

469475
if (force_author) {

t/t7509-commit.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,52 @@ test_expect_success '--amend option copies authorship' '
8383
test_cmp expect actual
8484
'
8585

86+
sha1_file() {
87+
echo "$*" | sed "s#..#.git/objects/&/#"
88+
}
89+
remove_object() {
90+
rm -f $(sha1_file "$*")
91+
}
92+
no_reflog() {
93+
cp .git/config .git/config.saved &&
94+
echo "[core] logallrefupdates = false" >>.git/config &&
95+
test_when_finished "mv -f .git/config.saved .git/config" &&
96+
97+
if test -e .git/logs
98+
then
99+
mv .git/logs . &&
100+
test_when_finished "mv logs .git/"
101+
fi
102+
}
103+
104+
test_expect_success '--amend option with empty author' '
105+
git cat-file commit Initial >tmp &&
106+
sed "s/author [^<]* </author </" tmp >empty-author &&
107+
no_reflog &&
108+
sha=$(git hash-object -t commit -w empty-author) &&
109+
test_when_finished "remove_object $sha" &&
110+
git checkout $sha &&
111+
test_when_finished "git checkout Initial" &&
112+
echo "Empty author test" >>foo &&
113+
test_tick &&
114+
! git commit -a -m "empty author" --amend 2>err &&
115+
grep "empty ident" err
116+
'
117+
118+
test_expect_success '--amend option with missing author' '
119+
git cat-file commit Initial >tmp &&
120+
sed "s/author [^<]* </author </" tmp >malformed &&
121+
no_reflog &&
122+
sha=$(git hash-object -t commit -w malformed) &&
123+
test_when_finished "remove_object $sha" &&
124+
git checkout $sha &&
125+
test_when_finished "git checkout Initial" &&
126+
echo "Missing author test" >>foo &&
127+
test_tick &&
128+
! git commit -a -m "malformed author" --amend 2>err &&
129+
grep "empty ident" err
130+
'
131+
86132
test_expect_success '--reset-author makes the commit ours even with --amend option' '
87133
git checkout Initial &&
88134
echo "Test 6" >>foo &&

0 commit comments

Comments
 (0)