@@ -91,6 +91,7 @@ static struct expand_data {
9191 struct object_id delta_base_oid ;
9292 void * content ;
9393
94+ struct object * maybe_object ;
9495 struct object_info info ;
9596} oi , oi_deref ;
9697
@@ -1475,18 +1476,44 @@ static void grab_common_values(struct atom_value *val, int deref, struct expand_
14751476 }
14761477}
14771478
1479+ static struct object * get_or_parse_object (struct expand_data * data , const char * refname ,
1480+ struct strbuf * err , int * eaten )
1481+ {
1482+ if (!data -> maybe_object ) {
1483+ data -> maybe_object = parse_object_buffer (the_repository , & data -> oid , data -> type ,
1484+ data -> size , data -> content , eaten );
1485+ if (!data -> maybe_object ) {
1486+ strbuf_addf (err , _ ("parse_object_buffer failed on %s for %s" ),
1487+ oid_to_hex (& data -> oid ), refname );
1488+ return NULL ;
1489+ }
1490+ }
1491+
1492+ return data -> maybe_object ;
1493+ }
1494+
14781495/* See grab_values */
1479- static void grab_tag_values (struct atom_value * val , int deref , struct object * obj )
1496+ static int grab_tag_values (struct atom_value * val , int deref ,
1497+ struct expand_data * data , const char * refname ,
1498+ struct strbuf * err , int * eaten )
14801499{
1500+ struct tag * tag = NULL ;
14811501 int i ;
1482- struct tag * tag = (struct tag * ) obj ;
14831502
14841503 for (i = 0 ; i < used_atom_cnt ; i ++ ) {
14851504 const char * name = used_atom [i ].name ;
14861505 enum atom_type atom_type = used_atom [i ].atom_type ;
14871506 struct atom_value * v = & val [i ];
14881507 if (!!deref != (* name == '*' ))
14891508 continue ;
1509+
1510+ if (!tag ) {
1511+ tag = (struct tag * ) get_or_parse_object (data , refname ,
1512+ err , eaten );
1513+ if (!tag )
1514+ return -1 ;
1515+ }
1516+
14901517 if (deref )
14911518 name ++ ;
14921519 if (atom_type == ATOM_TAG )
@@ -1496,22 +1523,35 @@ static void grab_tag_values(struct atom_value *val, int deref, struct object *ob
14961523 else if (atom_type == ATOM_OBJECT && tag -> tagged )
14971524 v -> s = xstrdup (oid_to_hex (& tag -> tagged -> oid ));
14981525 }
1526+
1527+ return 0 ;
14991528}
15001529
15011530/* See grab_values */
1502- static void grab_commit_values (struct atom_value * val , int deref , struct object * obj )
1531+ static int grab_commit_values (struct atom_value * val , int deref ,
1532+ struct expand_data * data , const char * refname ,
1533+ struct strbuf * err , int * eaten )
15031534{
15041535 int i ;
1505- struct commit * commit = ( struct commit * ) obj ;
1536+ struct commit * commit = NULL ;
15061537
15071538 for (i = 0 ; i < used_atom_cnt ; i ++ ) {
15081539 const char * name = used_atom [i ].name ;
15091540 enum atom_type atom_type = used_atom [i ].atom_type ;
15101541 struct atom_value * v = & val [i ];
1542+
15111543 if (!!deref != (* name == '*' ))
15121544 continue ;
15131545 if (deref )
15141546 name ++ ;
1547+
1548+ if (!commit ) {
1549+ commit = (struct commit * ) get_or_parse_object (data , refname ,
1550+ err , eaten );
1551+ if (!commit )
1552+ return -1 ;
1553+ }
1554+
15151555 if (atom_type == ATOM_TREE &&
15161556 grab_oid (name , "tree" , get_commit_tree_oid (commit ), v , & used_atom [i ]))
15171557 continue ;
@@ -1531,6 +1571,8 @@ static void grab_commit_values(struct atom_value *val, int deref, struct object
15311571 v -> s = strbuf_detach (& s , NULL );
15321572 }
15331573 }
1574+
1575+ return 0 ;
15341576}
15351577
15361578static const char * find_wholine (const char * who , int wholen , const char * buf )
@@ -1759,10 +1801,12 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void
17591801 }
17601802}
17611803
1762- static void grab_signature (struct atom_value * val , int deref , struct object * obj )
1804+ static int grab_signature (struct atom_value * val , int deref ,
1805+ struct expand_data * data , const char * refname ,
1806+ struct strbuf * err , int * eaten )
17631807{
17641808 int i ;
1765- struct commit * commit = ( struct commit * ) obj ;
1809+ struct commit * commit = NULL ;
17661810 struct signature_check sigc = { 0 };
17671811 int signature_checked = 0 ;
17681812
@@ -1790,6 +1834,13 @@ static void grab_signature(struct atom_value *val, int deref, struct object *obj
17901834 continue ;
17911835
17921836 if (!signature_checked ) {
1837+ if (!commit ) {
1838+ commit = (struct commit * ) get_or_parse_object (data , refname ,
1839+ err , eaten );
1840+ if (!commit )
1841+ return -1 ;
1842+ }
1843+
17931844 check_commit_signature (commit , & sigc );
17941845 signature_checked = 1 ;
17951846 }
@@ -1843,6 +1894,8 @@ static void grab_signature(struct atom_value *val, int deref, struct object *obj
18431894
18441895 if (signature_checked )
18451896 signature_check_clear (& sigc );
1897+
1898+ return 0 ;
18461899}
18471900
18481901static void find_subpos (const char * buf ,
@@ -1920,9 +1973,8 @@ static void append_lines(struct strbuf *out, const char *buf, unsigned long size
19201973}
19211974
19221975static void grab_describe_values (struct atom_value * val , int deref ,
1923- struct object * obj )
1976+ struct expand_data * data )
19241977{
1925- struct commit * commit = (struct commit * )obj ;
19261978 int i ;
19271979
19281980 for (i = 0 ; i < used_atom_cnt ; i ++ ) {
@@ -1944,7 +1996,7 @@ static void grab_describe_values(struct atom_value *val, int deref,
19441996 cmd .git_cmd = 1 ;
19451997 strvec_push (& cmd .args , "describe" );
19461998 strvec_pushv (& cmd .args , atom -> u .describe_args .v );
1947- strvec_push (& cmd .args , oid_to_hex (& commit -> object . oid ));
1999+ strvec_push (& cmd .args , oid_to_hex (& data -> oid ));
19482000 if (pipe_command (& cmd , NULL , 0 , & out , 0 , & err , 0 ) < 0 ) {
19492001 error (_ ("failed to run 'describe'" ));
19502002 v -> s = xstrdup ("" );
@@ -2066,24 +2118,36 @@ static void fill_missing_values(struct atom_value *val)
20662118 * pointed at by the ref itself; otherwise it is the object the
20672119 * ref (which is a tag) refers to.
20682120 */
2069- static void grab_values (struct atom_value * val , int deref , struct object * obj , struct expand_data * data )
2121+ static int grab_values (struct atom_value * val , int deref , struct expand_data * data ,
2122+ const char * refname , struct strbuf * err , int * eaten )
20702123{
20712124 void * buf = data -> content ;
2125+ int ret ;
20722126
2073- switch (obj -> type ) {
2127+ switch (data -> type ) {
20742128 case OBJ_TAG :
2075- grab_tag_values (val , deref , obj );
2129+ ret = grab_tag_values (val , deref , data , refname , err , eaten );
2130+ if (ret < 0 )
2131+ goto out ;
2132+
20762133 grab_sub_body_contents (val , deref , data );
20772134 grab_person ("tagger" , val , deref , buf );
2078- grab_describe_values (val , deref , obj );
2135+ grab_describe_values (val , deref , data );
20792136 break ;
20802137 case OBJ_COMMIT :
2081- grab_commit_values (val , deref , obj );
2138+ ret = grab_commit_values (val , deref , data , refname , err , eaten );
2139+ if (ret < 0 )
2140+ goto out ;
2141+
20822142 grab_sub_body_contents (val , deref , data );
20832143 grab_person ("author" , val , deref , buf );
20842144 grab_person ("committer" , val , deref , buf );
2085- grab_signature (val , deref , obj );
2086- grab_describe_values (val , deref , obj );
2145+
2146+ ret = grab_signature (val , deref , data , refname , err , eaten );
2147+ if (ret < 0 )
2148+ goto out ;
2149+
2150+ grab_describe_values (val , deref , data );
20872151 break ;
20882152 case OBJ_TREE :
20892153 /* grab_tree_values(val, deref, obj, buf, sz); */
@@ -2094,8 +2158,12 @@ static void grab_values(struct atom_value *val, int deref, struct object *obj, s
20942158 grab_sub_body_contents (val , deref , data );
20952159 break ;
20962160 default :
2097- die ("Eh? Object of type %d?" , obj -> type );
2161+ die ("Eh? Object of type %d?" , data -> type );
20982162 }
2163+
2164+ ret = 0 ;
2165+ out :
2166+ return ret ;
20992167}
21002168
21012169static inline char * copy_advance (char * dst , const char * src )
@@ -2292,38 +2360,41 @@ static const char *get_refname(struct used_atom *atom, struct ref_array_item *re
22922360 return show_ref (& atom -> u .refname , ref -> refname );
22932361}
22942362
2295- static int get_object (struct ref_array_item * ref , int deref , struct object * * obj ,
2363+ static int get_object (struct ref_array_item * ref , int deref ,
22962364 struct expand_data * oi , struct strbuf * err )
22972365{
2298- /* parse_object_buffer() will set eaten to 0 if free() will be needed */
2299- int eaten = 1 ;
2366+ /* parse_object_buffer() will set eaten to 1 if free() will be needed */
2367+ int eaten = 0 ;
2368+ int ret ;
2369+
23002370 if (oi -> info .contentp ) {
23012371 /* We need to know that to use parse_object_buffer properly */
23022372 oi -> info .sizep = & oi -> size ;
23032373 oi -> info .typep = & oi -> type ;
23042374 }
2375+
23052376 if (odb_read_object_info_extended (the_repository -> objects , & oi -> oid , & oi -> info ,
2306- OBJECT_INFO_LOOKUP_REPLACE ))
2307- return strbuf_addf_ret (err , -1 , _ ("missing object %s for %s" ),
2308- oid_to_hex (& oi -> oid ), ref -> refname );
2377+ OBJECT_INFO_LOOKUP_REPLACE )) {
2378+ ret = strbuf_addf_ret (err , -1 , _ ("missing object %s for %s" ),
2379+ oid_to_hex (& oi -> oid ), ref -> refname );
2380+ goto out ;
2381+ }
23092382 if (oi -> info .disk_sizep && oi -> disk_size < 0 )
23102383 BUG ("Object size is less than zero." );
23112384
23122385 if (oi -> info .contentp ) {
2313- * obj = parse_object_buffer (the_repository , & oi -> oid , oi -> type , oi -> size , oi -> content , & eaten );
2314- if (!* obj ) {
2315- if (!eaten )
2316- free (oi -> content );
2317- return strbuf_addf_ret (err , -1 , _ ("parse_object_buffer failed on %s for %s" ),
2318- oid_to_hex (& oi -> oid ), ref -> refname );
2319- }
2320- grab_values (ref -> value , deref , * obj , oi );
2386+ ret = grab_values (ref -> value , deref , oi , ref -> refname , err , & eaten );
2387+ if (ret < 0 )
2388+ goto out ;
23212389 }
23222390
23232391 grab_common_values (ref -> value , deref , oi );
2392+ ret = 0 ;
2393+
2394+ out :
23242395 if (!eaten )
23252396 free (oi -> content );
2326- return 0 ;
2397+ return ret ;
23272398}
23282399
23292400static void populate_worktree_map (struct hashmap * map , struct worktree * * worktrees )
@@ -2376,7 +2447,6 @@ static char *get_worktree_path(const struct ref_array_item *ref)
23762447 */
23772448static int populate_value (struct ref_array_item * ref , struct strbuf * err )
23782449{
2379- struct object * obj ;
23802450 int i ;
23812451 struct object_info empty = OBJECT_INFO_INIT ;
23822452 int ahead_behind_atoms = 0 ;
@@ -2564,14 +2634,14 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
25642634
25652635
25662636 oi .oid = ref -> objectname ;
2567- if (get_object (ref , 0 , & obj , & oi , err ))
2637+ if (get_object (ref , 0 , & oi , err ))
25682638 return -1 ;
25692639
25702640 /*
25712641 * If there is no atom that wants to know about tagged
25722642 * object, we are done.
25732643 */
2574- if (!need_tagged || (obj -> type != OBJ_TAG ))
2644+ if (!need_tagged || (oi . type != OBJ_TAG ))
25752645 return 0 ;
25762646
25772647 /*
@@ -2589,7 +2659,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
25892659 }
25902660 }
25912661
2592- return get_object (ref , 1 , & obj , & oi_deref , err );
2662+ return get_object (ref , 1 , & oi_deref , err );
25932663}
25942664
25952665/*
0 commit comments