4 * Commit handling functions.
6 * The functions implemented in this file retrieve all kinds of
7 * information from commits.
9 * Luiz Fernando N. Capitulino
10 * <lcapitulino@gmail.com>
22 /**< Commit structure */
24 struct commit
*commit
;
31 char *committer_email
;
34 time_t committer_time
;
37 unsigned char tree_sha1
[20];
40 static char *commit_info_alloc(const char *src
, size_t len
)
54 static char *commit_strstr(const struct git_commit
*commit
,
62 p
= strstr(commit
->commit
->buffer
, needle
);
66 endp
= strstr(commit
->commit
->buffer
, "\n\n");
68 endp
= commit
->commit
->buffer
+ strlen(commit
->commit
->buffer
);
70 return (p
< endp
) ? p
: NULL
;
73 static char *email_line_strchr(char *p
, int c
)
75 while (*p
&& *p
!= c
&& *p
!= '\n')
78 return (*p
!= c
) ? NULL
: p
;
81 static inline char *email_line_start(char *p
)
83 return email_line_strchr(p
, '<');
86 static inline char *email_line_end(char *p
)
88 return email_line_strchr(p
, '>');
91 static inline char *tz_start(char *p
)
93 return email_line_strchr(p
, ' ');
96 static inline int check_strtoul_ret(unsigned long ret
)
98 if ((!ret
|| ret
== ULONG_MAX
) && errno
!= 0)
103 static inline int check_strtol_ret(long ret
)
105 if ((ret
== LONG_MIN
|| ret
== LONG_MAX
) && errno
!= 0)
111 * Get the commit's message.
113 * \param commit git_commit structure to get the message from
115 * \return A pointer to the commit's message on success,
118 const char *git_commit_message(struct git_commit
*commit
)
123 if (!commit
->message
) {
129 p
= strstr(commit
->commit
->buffer
, "\n\n");
131 /* empty message (probably) */
140 commit
->message
= commit_info_alloc(p
, strlen(p
));
143 return commit
->message
;
151 * Get the commit's committer email.
153 * \param commit git_commit structure to get the committer's email
156 * \return A pointer to the commit's committer email on success,
159 const char *git_commit_committer_email(struct git_commit
*commit
)
164 if (!commit
->committer_email
) {
167 p
= commit_strstr(commit
, "committer ");
171 p
= email_line_start(p
);
175 endp
= email_line_end(p
);
180 commit
->committer_email
= commit_info_alloc(p
, endp
- p
);
183 return commit
->committer_email
;
191 * Get the commit's committer name.
193 * \param commit git_commit structure to get the committer's name
196 * \return A pointer to the commit's committer name on success,
199 const char *git_commit_committer_name(struct git_commit
*commit
)
204 if (!commit
->committer_name
) {
207 p
= commit_strstr(commit
, "committer ");
211 endp
= email_line_start(p
);
220 commit
->committer_name
= commit_info_alloc(p
, endp
- p
);
223 return commit
->committer_name
;
231 * Get the commit's (committer) date
233 * \param commit git_commit structure to get the (committer's) date from
234 * \param com_time return the date timestamp as seconds since the
235 * epoch, UTC (might be NULL)
236 * \param com_tz return the timezone information as the number of
237 * hours and minutes offset from UTC (might be NULL)
239 * \return 0 on succes, -1 otherwise
241 int git_commit_committer_date(struct git_commit
*commit
,
242 time_t *com_time
, int *com_tz
)
247 if (!com_time
&& !com_tz
)
250 if (!commit
->committer_date
) {
254 p
= commit_strstr(commit
, "committer ");
258 p
= email_line_end(p
);
267 commit
->committer_time
= (time_t) strtoul(++p
, NULL
, 10);
268 err
= check_strtoul_ret(commit
->committer_time
);
277 commit
->committer_tz
= strtol(++p
, NULL
, 10);
278 err
= check_strtol_ret(commit
->committer_tz
);
282 commit
->committer_date
= 1;
286 *com_time
= commit
->committer_time
;
289 *com_tz
= commit
->committer_tz
;
299 * Get the commit's author email.
301 * \param commit git_commit structure to get the author's email
304 * \return A pointer to the commit's author's email on success,
307 const char *git_commit_author_email(struct git_commit
*commit
)
312 if (!commit
->author_email
) {
315 p
= commit_strstr(commit
, "author ");
319 p
= email_line_start(p
);
323 endp
= email_line_end(p
);
328 commit
->author_email
= commit_info_alloc(p
, endp
- p
);
331 return commit
->author_email
;
339 * Get the commit's (author) date
341 * \param commit git_commit structure to get the (author's) date from
342 * \param com_time return the date timestamp as seconds since the
343 * epoch, UTC (might be NULL)
344 * \param com_tz return the timezone information as the number of
345 * hours and minutes offset from UTC (might be NULL)
347 * \return 0 on succes, -1 otherwise
349 int git_commit_author_date(struct git_commit
*commit
,
350 time_t *com_time
, int *com_tz
)
355 if (!com_time
&& !com_tz
)
358 if (!commit
->author_date
) {
362 p
= commit_strstr(commit
, "author ");
366 p
= email_line_end(p
);
375 commit
->author_time
= (time_t) strtoul(++p
, NULL
, 10);
376 err
= check_strtoul_ret(commit
->author_time
);
385 commit
->author_tz
= strtol(++p
, NULL
, 10);
386 err
= check_strtol_ret(commit
->author_tz
);
390 commit
->author_date
= 1;
394 *com_time
= commit
->author_time
;
397 *com_tz
= commit
->author_tz
;
407 * Get the commit's author name.
409 * \param commit git_commit structure to get the author's name
412 * \return A pointer to the commit's author's name on success,
415 const char *git_commit_author_name(struct git_commit
*commit
)
420 if (!commit
->author_name
) {
423 p
= commit_strstr(commit
, "author ");
427 endp
= email_line_start(p
);
436 commit
->author_name
= commit_info_alloc(p
, endp
- p
);
439 return commit
->author_name
;
447 * Get the commit's SHA1.
449 * \param commit git_commit structure to get the commit's SHA1 from
450 * \param sha1 pointer to an 20-byte array to return the SHA1 into
452 * \return 0 on success, -1 otherwise
454 int git_commit_id(struct git_commit
*commit
, unsigned char *sha1
)
456 if (!commit
|| !commit
->commit
|| !sha1
) {
461 memcpy(sha1
, commit
->commit
->object
.sha1
, 20);
466 * Get the commit's tree SHA1.
468 * \param commit git_commit structure to get the tree SHA1 from
469 * \param sha1 pointer to an 20-byte array to return the SHA1 into
471 * \return 0 on success, -1 otherwise
473 int git_commit_tree(struct git_commit
*commit
, unsigned char *sha1
)
475 if (!commit
|| !sha1
)
478 if (!commit
->tree_id
) {
482 p
= commit_strstr(commit
, "tree ");
490 err
= get_sha1_hex(p
, commit
->tree_sha1
);
497 memcpy(sha1
, commit
->tree_sha1
, 20);
506 * Get the commit's buffer raw data.
508 * \param commit git_commit structure to get the raw buffer
511 * \return A pointer to the commit's raw buffer (if any).
513 const char *git_commit_raw(struct git_commit
*commit
)
515 if (!commit
|| !commit
->commit
) {
520 return commit
->commit
->buffer
;
524 * Free all the memory allocated by the git_commit structure's
527 * This is a low-level function, only use it if you know
530 * \param commit git_commit structure to have the contents
533 void __git_commit_free(struct git_commit
*commit
)
538 free(commit
->commit
->buffer
);
539 free_commit_list(commit
->commit
->parents
);
541 free(commit
->author_name
);
542 free(commit
->author_email
);
543 free(commit
->committer_name
);
544 free(commit
->committer_email
);
545 free(commit
->message
);
549 * Free all the memory allocated by a git_commit structure.
551 * \param commit git_commit structure to be freed.
553 void git_commit_free(struct git_commit
*commit
)
556 __git_commit_free(commit
);
562 * Initialize a git_commit structure.
564 * This is a low-level function, only use it if you know
567 * \param commit git_commit structure to be initialized
569 void __git_commit_init(struct git_commit
*commit
)
571 commit
->commit
= NULL
;
572 commit
->author_name
= NULL
;
573 commit
->author_email
= NULL
;
574 commit
->author_date
= 0;
575 commit
->committer_name
= NULL
;
576 commit
->committer_email
= NULL
;
577 commit
->committer_date
= 0;
578 commit
->message
= NULL
;
583 * Allocate and initialize a git_commit structure.
585 * Should be called before using git_revlist_next().
587 * \return A pointer to an allocated git_commit structure
588 * on success, NULL otherwise.
590 struct git_commit
*git_commit_init(void)
592 struct git_commit
*commit
;
594 commit
= malloc(sizeof(*commit
));
598 __git_commit_init(commit
);
603 * Get the raw GIT commit object from a git_commit
606 * This is a low-level function, only use it if you know
609 * \param commit git_commit structure to get the commit object
612 * \return A pointer to the raw GIT commit object if any,
615 struct commit
*__git_commit_obj(struct git_commit
*commit
)
617 return commit
->commit
;
621 * Set the git_commit structure's (raw) GIT commit object
624 * This is a low-level function, only use it if you know
627 * \param commit git_commit structure to set the raw GIT
629 * \param new The raw GIT commit object to set into the git_commit
632 void __git_commit_obj_set(struct git_commit
*commit
, struct commit
*new)
634 commit
->commit
= new;
638 * Return a filled git_commit structure from a given commit's SHA1
640 * \param sha1 commit's SHA1 to be read
642 * \returns git_commit structure on success, NULL otherwise.
644 struct git_commit
*git_commit_lookup(const unsigned char *sha1
)
646 struct git_commit
*commit
;
653 commit
= git_commit_init();
657 commit
->commit
= lookup_commit_reference_gently(sha1
, 1);
658 if (!commit
->commit
) {
659 git_commit_free(commit
);