Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f55eca1

Browse files
committed
commit: also match the first header field when searching
We were searching only past the first header field, which meant we were unable to find e.g. `tree` which is the first field. While here, make sure to set an error message in case we cannot find the field.
1 parent 700f0af commit f55eca1

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

src/commit.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -564,41 +564,45 @@ int git_commit_nth_gen_ancestor(
564564

565565
int git_commit_header_field(git_buf *out, const git_commit *commit, const char *field)
566566
{
567-
const char *buf = commit->raw_header;
568-
const char *h, *eol;
567+
const char *eol, *buf = commit->raw_header;
569568

570569
git_buf_sanitize(out);
571-
while ((h = strchr(buf, '\n')) && h[1] != '\0' && h[1] != '\n') {
572-
h++;
573-
if (git__prefixcmp(h, field)) {
574-
buf = h;
570+
571+
while ((eol = strchr(buf, '\n')) && eol[1] != '\0') {
572+
/* We can skip continuations here */
573+
if (buf[0] == ' ') {
574+
buf = eol + 1;
575+
continue;
576+
}
577+
578+
/* Skip until we find the field we're after */
579+
if (git__prefixcmp(buf, field)) {
580+
buf = eol + 1;
575581
continue;
576582
}
577583

578-
h += strlen(field);
579-
eol = strchr(h, '\n');
580-
if (h[0] != ' ') {
581-
buf = h;
584+
buf += strlen(field);
585+
/* Check that we're not matching a prefix but the field itself */
586+
if (buf[0] != ' ') {
587+
buf = eol + 1;
582588
continue;
583589
}
584-
if (!eol)
585-
goto malformed;
586590

587-
h++; /* skip the SP */
591+
buf++; /* skip the SP */
588592

589-
git_buf_put(out, h, eol - h);
593+
git_buf_put(out, buf, eol - buf);
590594
if (git_buf_oom(out))
591595
goto oom;
592596

593597
/* If the next line starts with SP, it's multi-line, we must continue */
594598
while (eol[1] == ' ') {
595599
git_buf_putc(out, '\n');
596-
h = eol + 2;
597-
eol = strchr(h, '\n');
600+
buf = eol + 2;
601+
eol = strchr(buf, '\n');
598602
if (!eol)
599603
goto malformed;
600604

601-
git_buf_put(out, h, eol - h);
605+
git_buf_put(out, buf, eol - buf);
602606
}
603607

604608
if (git_buf_oom(out))
@@ -607,6 +611,7 @@ int git_commit_header_field(git_buf *out, const git_commit *commit, const char *
607611
return 0;
608612
}
609613

614+
giterr_set(GITERR_OBJECT, "no such field '%s'", field);
610615
return GIT_ENOTFOUND;
611616

612617
malformed:

tests/commit/parse.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,10 @@ cpxtDQQMGYFpXK/71stq\n\
443443

444444
cl_git_pass(parse_commit(&commit, passing_commit_cases[4]));
445445

446+
cl_git_pass(git_commit_header_field(&buf, commit, "tree"));
447+
cl_assert_equal_s("6b79e22d69bf46e289df0345a14ca059dfc9bdf6", buf.ptr);
448+
git_buf_clear(&buf);
449+
446450
cl_git_pass(git_commit_header_field(&buf, commit, "parent"));
447451
cl_assert_equal_s("34734e478d6cf50c27c9d69026d93974d052c454", buf.ptr);
448452
git_buf_clear(&buf);

0 commit comments

Comments
 (0)