@matheusbsbs / matheus-bagliano / commits / fb7749e4e4
Fork 0

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 <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>

Jonathan Nieder committed May 2, 2010 at 03:57 UTC fb7749e4e4d4d9fef61f35b2f8b40f80c2d5942f
2 files changed +59 -7
builtin/commit.c
+13 -7
@@ -455,15 +455,21 @@ static void determine_author_info(void)
455 if (!a)
456 die("invalid commit: %s", use_message);
457
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)
462 die("invalid commit: %s", use_message);
463
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 <foo@example.com> */
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("> ")));
473 }
474
475 if (force_author) {
t/t7509-commit.sh
+46
@@ -83,6 +83,52 @@ test_expect_success '--amend option copies authorship' '
83 test_cmp expect actual
84 '
85
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 +
132 test_expect_success '--reset-author makes the commit ours even with --amend option' '
133 git checkout Initial &&
134 echo "Test 6" >>foo &&