commit: allow retrieving an arbitrary header field · RetVal/libgit2@a3f42fe · GitHub
Skip to content

Commit a3f42fe

Browse files
committed
commit: allow retrieving an arbitrary header field
This allows the user to look up fields which we don't parse in libgit2, and allows them to access gpgsig or mergetag fields if they wish to check the signature.
1 parent e96a97f commit a3f42fe

4 files changed

Lines changed: 107 additions & 0 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 3 additions & 0 deletions

‎include/git2/commit.h‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,17 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor(
239239
const git_commit *commit,
240240
unsigned int n);
241241

242+
/**
243+
* Get an arbitrary header field
244+
*
245+
* @param out the buffer to fill
246+
* @param commit the commit to look in
247+
* @param field the header field to return
248+
* @return 0 on succeess, GIT_ENOTFOUND if the field does not exist,
249+
* or an error code
250+
*/
251+
GIT_EXTERN(int) git_commit_header_field(git_buf *out, const git_commit *commit, const char *field);
252+
242253
/**
243254
* Create new commit in the repository from a list of `git_object` pointers
244255
*

‎src/commit.c‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,3 +518,58 @@ int git_commit_nth_gen_ancestor(
518518
*ancestor = parent;
519519
return 0;
520520
}
521+
522+
int git_commit_header_field(git_buf *out, const git_commit *commit, const char *field)
523+
{
524+
const char *buf = commit->raw_header;
525+
const char *h, *eol;
526+
527+
git_buf_sanitize(out);
528+
while ((h = strchr(buf, '\n')) && h[1] != '\0' && h[1] != '\n') {
529+
h++;
530+
if (git__prefixcmp(h, field)) {
531+
buf = h;
532+
continue;
533+
}
534+
535+
h += strlen(field);
536+
eol = strchr(h, '\n');
537+
if (h[0] != ' ') {
538+
buf = h;
539+
continue;
540+
}
541+
if (!eol)
542+
goto malformed;
543+
544+
h++; /* skip the SP */
545+
546+
git_buf_put(out, h, eol - h);
547+
if (git_buf_oom(out))
548+
goto oom;
549+
550+
/* If the next line starts with SP, it's multi-line, we must continue */
551+
while (eol[1] == ' ') {
552+
git_buf_putc(out, '\n');
553+
h = eol + 2;
554+
eol = strchr(h, '\n');
555+
if (!eol)
556+
goto malformed;
557+
558+
git_buf_put(out, h, eol - h);
559+
}
560+
561+
if (git_buf_oom(out))
562+
goto oom;
563+
564+
return 0;
565+
}
566+
567+
return GIT_ENOTFOUND;
568+
569+
malformed:
570+
giterr_set(GITERR_OBJECT, "malformed header");
571+
return -1;
572+
oom:
573+
giterr_set_oom();
574+
return -1;
575+
}

‎tests/commit/parse.c‎

Lines changed: 38 additions & 0 deletions

0 commit comments

Comments
 (0)