2020#include "message.h"
2121#include "refs.h"
2222#include "object.h"
23+ #include "array.h"
2324#include "oidarray.h"
2425
2526void git_commit__free (void * _commit )
@@ -383,24 +384,32 @@ int git_commit_amend(
383384 return error ;
384385}
385386
386- int git_commit__parse_raw ( void * _commit , const char * data , size_t size )
387+ static int commit_parse ( git_commit * commit , const char * data , size_t size , unsigned int flags )
387388{
388- git_commit * commit = _commit ;
389389 const char * buffer_start = data , * buffer ;
390390 const char * buffer_end = buffer_start + size ;
391391 git_oid parent_id ;
392392 size_t header_len ;
393393 git_signature dummy_sig ;
394394
395+ assert (commit && data );
396+
395397 buffer = buffer_start ;
396398
397399 /* Allocate for one, which will allow not to realloc 90% of the time */
398400 git_array_init_to_size (commit -> parent_ids , 1 );
399401 GIT_ERROR_CHECK_ARRAY (commit -> parent_ids );
400402
401403 /* The tree is always the first field */
402- if (git_oid__parse (& commit -> tree_id , & buffer , buffer_end , "tree " ) < 0 )
403- goto bad_buffer ;
404+ if (!(flags & GIT_COMMIT_PARSE_QUICK )) {
405+ if (git_oid__parse (& commit -> tree_id , & buffer , buffer_end , "tree " ) < 0 )
406+ goto bad_buffer ;
407+ } else {
408+ size_t tree_len = strlen ("tree " ) + GIT_OID_HEXSZ + 1 ;
409+ if (buffer + tree_len > buffer_end )
410+ goto bad_buffer ;
411+ buffer += tree_len ;
412+ }
404413
405414 /*
406415 * TODO: commit grafts!
@@ -413,11 +422,13 @@ int git_commit__parse_raw(void *_commit, const char *data, size_t size)
413422 git_oid_cpy (new_id , & parent_id );
414423 }
415424
416- commit -> author = git__malloc (sizeof (git_signature ));
417- GIT_ERROR_CHECK_ALLOC (commit -> author );
425+ if (!(flags & GIT_COMMIT_PARSE_QUICK )) {
426+ commit -> author = git__malloc (sizeof (git_signature ));
427+ GIT_ERROR_CHECK_ALLOC (commit -> author );
418428
419- if (git_signature__parse (commit -> author , & buffer , buffer_end , "author " , '\n' ) < 0 )
420- return -1 ;
429+ if (git_signature__parse (commit -> author , & buffer , buffer_end , "author " , '\n' ) < 0 )
430+ return -1 ;
431+ }
421432
422433 /* Some tools create multiple author fields, ignore the extra ones */
423434 while (!git__prefixncmp (buffer , buffer_end - buffer , "author " )) {
@@ -435,6 +446,9 @@ int git_commit__parse_raw(void *_commit, const char *data, size_t size)
435446 if (git_signature__parse (commit -> committer , & buffer , buffer_end , "committer " , '\n' ) < 0 )
436447 return -1 ;
437448
449+ if (flags & GIT_COMMIT_PARSE_QUICK )
450+ return 0 ;
451+
438452 /* Parse add'l header entries */
439453 while (buffer < buffer_end ) {
440454 const char * eoln = buffer ;
@@ -477,11 +491,19 @@ int git_commit__parse_raw(void *_commit, const char *data, size_t size)
477491 return -1 ;
478492}
479493
494+ int git_commit__parse_raw (void * commit , const char * data , size_t size )
495+ {
496+ return commit_parse (commit , data , size , 0 );
497+ }
498+
499+ int git_commit__parse_ext (git_commit * commit , git_odb_object * odb_obj , unsigned int flags )
500+ {
501+ return commit_parse (commit , git_odb_object_data (odb_obj ), git_odb_object_size (odb_obj ), flags );
502+ }
503+
480504int git_commit__parse (void * _commit , git_odb_object * odb_obj )
481505{
482- return git_commit__parse_raw (_commit ,
483- git_odb_object_data (odb_obj ),
484- git_odb_object_size (odb_obj ));
506+ return git_commit__parse_ext (_commit , odb_obj , 0 );
485507}
486508
487509#define GIT_COMMIT_GETTER (_rvalue , _name , _return ) \
0 commit comments