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
;
26 size_t author_name_len
;
28 size_t author_email_len
;
33 size_t committer_name_len
;
34 char *committer_email
;
37 time_t committer_time
;
40 unsigned char tree_sha1
[20];
43 static char *commit_info_alloc(const char *src
, size_t len
)
57 static char *commit_strstr(const struct git_commit
*commit
,
65 p
= strstr(commit
->commit
->buffer
, needle
);
69 endp
= strstr(commit
->commit
->buffer
, "\n\n");
71 endp
= commit
->commit
->buffer
+ strlen(commit
->commit
->buffer
);
73 return (p
< endp
) ? p
: NULL
;
76 static char *email_line_strchr(char *p
, int c
)
78 while (*p
&& *p
!= c
&& *p
!= '\n')
81 return (*p
!= c
) ? NULL
: p
;
84 static inline char *email_line_start(char *p
)
86 return email_line_strchr(p
, '<');
89 static inline char *email_line_end(char *p
)
91 return email_line_strchr(p
, '>');
94 static inline char *tz_start(char *p
)
96 return email_line_strchr(p
, ' ');
99 static inline int check_strtoul_ret(unsigned long ret
)
101 if ((!ret
|| ret
== ULONG_MAX
) && errno
!= 0)
106 static inline int check_strtol_ret(long ret
)
108 if ((ret
== LONG_MIN
|| ret
== LONG_MAX
) && errno
!= 0)
114 * Get the commit's message.
116 * \param commit git_commit structure to get the message from
118 * \return A pointer to the commit's message on success,
121 const char *git_commit_message(struct git_commit
*commit
)
126 if (!commit
->message
) {
132 p
= strstr(commit
->commit
->buffer
, "\n\n");
134 /* empty message (probably) */
143 commit
->message
= commit_info_alloc(p
, strlen(p
));
146 return commit
->message
;
154 * Get the commit's committer email.
156 * \param commit git_commit structure to get the committer's email
159 * \return A pointer to the commit's committer email on success,
162 const char *git_commit_committer_email(struct git_commit
*commit
)
167 if (!commit
->committer_email
) {
170 p
= commit_strstr(commit
, "committer ");
174 p
= email_line_start(p
);
178 endp
= email_line_end(p
);
183 commit
->committer_email
= commit_info_alloc(p
, endp
- p
);
186 return commit
->committer_email
;
194 * Get the commit's committer name.
196 * \param commit git_commit structure to get the committer's name
198 * \param ret pointer to return the committer's name into
199 * \param len committer's name length
201 * \return 0 on success, NULL otherwise
203 int git_commit_committer_name(struct git_commit
*commit
,
204 const char **ret
, size_t *len
)
209 if (!commit
->committer_name
) {
212 p
= commit_strstr(commit
, "committer ");
216 endp
= email_line_start(p
);
225 commit
->committer_name
= p
;
226 commit
->committer_name_len
= endp
- p
;
229 *ret
= commit
->committer_name
;
231 *len
= commit
->committer_name_len
;
241 * Get the commit's (committer) date
243 * \param commit git_commit structure to get the (committer's) date from
244 * \param com_time return the date timestamp as seconds since the
245 * epoch, UTC (might be NULL)
246 * \param com_tz return the timezone information as the number of
247 * hours and minutes offset from UTC (might be NULL)
249 * \return 0 on succes, -1 otherwise
251 int git_commit_committer_date(struct git_commit
*commit
,
252 time_t *com_time
, int *com_tz
)
257 if (!com_time
&& !com_tz
)
260 if (!commit
->committer_date
) {
264 p
= commit_strstr(commit
, "committer ");
268 p
= email_line_end(p
);
277 commit
->committer_time
= (time_t) strtoul(++p
, NULL
, 10);
278 err
= check_strtoul_ret(commit
->committer_time
);
287 commit
->committer_tz
= strtol(++p
, NULL
, 10);
288 err
= check_strtol_ret(commit
->committer_tz
);
292 commit
->committer_date
= 1;
296 *com_time
= commit
->committer_time
;
299 *com_tz
= commit
->committer_tz
;
309 * Get the commit's author email.
311 * \param commit git_commit structure to get the author's email
314 * \return A pointer to the commit's author's email on success,
317 int git_commit_author_email(struct git_commit
*commit
,
318 const char **ret
, size_t *len
)
323 if (!commit
->author_email
) {
326 p
= commit_strstr(commit
, "author ");
330 p
= email_line_start(p
);
334 endp
= email_line_end(p
);
338 commit
->author_email
= ++p
;
339 commit
->author_email_len
= endp
- p
;
342 *ret
= commit
->author_email
;
344 *len
= commit
->author_email_len
;
354 * Get the commit's (author) date
356 * \param commit git_commit structure to get the (author's) date from
357 * \param com_time return the date timestamp as seconds since the
358 * epoch, UTC (might be NULL)
359 * \param com_tz return the timezone information as the number of
360 * hours and minutes offset from UTC (might be NULL)
362 * \return 0 on succes, -1 otherwise
364 int git_commit_author_date(struct git_commit
*commit
,
365 time_t *com_time
, int *com_tz
)
370 if (!com_time
&& !com_tz
)
373 if (!commit
->author_date
) {
377 p
= commit_strstr(commit
, "author ");
381 p
= email_line_end(p
);
390 commit
->author_time
= (time_t) strtoul(++p
, NULL
, 10);
391 err
= check_strtoul_ret(commit
->author_time
);
400 commit
->author_tz
= strtol(++p
, NULL
, 10);
401 err
= check_strtol_ret(commit
->author_tz
);
405 commit
->author_date
= 1;
409 *com_time
= commit
->author_time
;
412 *com_tz
= commit
->author_tz
;
422 * Get the commit's author name.
424 * \param commit git_commit structure to get the author's name
426 * \param ret pointer to return the author's name into
427 * \param len author's name length
429 * \return 0 on success, NULL otherwise
431 int git_commit_author_name(struct git_commit
*commit
,
432 const char **ret
, size_t *len
)
437 if (!commit
->author_name
) {
440 p
= commit_strstr(commit
, "author ");
444 endp
= email_line_start(p
);
453 commit
->author_name
= p
;
454 commit
->author_name_len
= endp
- p
;
457 *ret
= commit
->author_name
;
459 *len
= commit
->author_name_len
;
469 * Get the commit's SHA1.
471 * \param commit git_commit structure to get the commit's SHA1 from
472 * \param sha1 pointer to an 20-byte array to return the SHA1 into
474 * \return 0 on success, -1 otherwise
476 int git_commit_id(struct git_commit
*commit
, unsigned char *sha1
)
478 if (!commit
|| !commit
->commit
|| !sha1
) {
483 memcpy(sha1
, commit
->commit
->object
.sha1
, 20);
488 * Get the commit's tree SHA1.
490 * \param commit git_commit structure to get the tree SHA1 from
491 * \param sha1 pointer to an 20-byte array to return the SHA1 into
493 * \return 0 on success, -1 otherwise
495 int git_commit_tree(struct git_commit
*commit
, unsigned char *sha1
)
497 if (!commit
|| !sha1
)
500 if (!commit
->tree_id
) {
504 p
= commit_strstr(commit
, "tree ");
512 err
= get_sha1_hex(p
, commit
->tree_sha1
);
519 memcpy(sha1
, commit
->tree_sha1
, 20);
528 * Get the commit's buffer raw data.
530 * \param commit git_commit structure to get the raw buffer
533 * \return A pointer to the commit's raw buffer (if any).
535 const char *git_commit_raw(struct git_commit
*commit
)
537 if (!commit
|| !commit
->commit
) {
542 return commit
->commit
->buffer
;
546 * Free all the memory allocated by the git_commit structure's
549 * This is a low-level function, only use it if you know
552 * \param commit git_commit structure to have the contents
555 void __git_commit_free(struct git_commit
*commit
)
560 free(commit
->commit
->buffer
);
561 commit
->commit
->buffer
= NULL
;
563 free(commit
->committer_email
);
564 free(commit
->message
);
568 * Free all the memory allocated by a git_commit structure.
570 * \param commit git_commit structure to be freed.
572 void git_commit_free(struct git_commit
*commit
)
575 __git_commit_free(commit
);
581 * Initialize a git_commit structure.
583 * This is a low-level function, only use it if you know
586 * \param commit git_commit structure to be initialized
588 void __git_commit_init(struct git_commit
*commit
)
590 commit
->commit
= NULL
;
591 commit
->author_name
= NULL
;
592 commit
->author_email
= NULL
;
593 commit
->author_date
= 0;
594 commit
->committer_name
= NULL
;
595 commit
->committer_email
= NULL
;
596 commit
->committer_date
= 0;
597 commit
->message
= NULL
;
602 * Allocate and initialize a git_commit structure.
604 * Should be called before using git_revlist_next().
606 * \return A pointer to an allocated git_commit structure
607 * on success, NULL otherwise.
609 struct git_commit
*git_commit_init(void)
611 struct git_commit
*commit
;
613 commit
= malloc(sizeof(*commit
));
617 __git_commit_init(commit
);
622 * Compare two commits.
624 * \param a git_commit structure to compare with
625 * \param b git_commit structure to compare with
627 * \return 1 if commits are equal, 0 if they don't and -1 on
630 int git_commit_equal(const struct git_commit
*a
,const struct git_commit
*b
)
637 return (a
->commit
== b
->commit
);
641 * Get the raw GIT commit object from a git_commit
644 * This is a low-level function, only use it if you know
647 * \param commit git_commit structure to get the commit object
650 * \return A pointer to the raw GIT commit object if any,
653 struct commit
*__git_commit_obj(struct git_commit
*commit
)
655 return commit
->commit
;
659 * Set the git_commit structure's (raw) GIT commit object
662 * This is a low-level function, only use it if you know
665 * \param commit git_commit structure to set the raw GIT
667 * \param new The raw GIT commit object to set into the git_commit
670 void __git_commit_obj_set(struct git_commit
*commit
, struct commit
*new)
672 commit
->commit
= new;
676 * Return a filled git_commit structure from a given commit's SHA1
678 * \param sha1 commit's SHA1 to be read
680 * \returns git_commit structure on success, NULL otherwise.
682 struct git_commit
*git_commit_lookup(const unsigned char *sha1
)
684 struct git_commit
*commit
;
691 commit
= git_commit_init();
695 commit
->commit
= lookup_commit_reference_gently(sha1
, 1);
696 if (!commit
->commit
) {
697 git_commit_free(commit
);