@@ -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,46 @@ static void grab_common_values(struct atom_value *val, int deref, struct expand_
14751476 }
14761477}
14771478
1479+ static int get_or_parse_object (struct expand_data * data , const char * refname ,
1480+ struct object * * object , 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+ return strbuf_addf_ret (err , -1 , _ ("parse_object_buffer failed on %s for %s" ),
1487+ oid_to_hex (& data -> oid ), refname );
1488+ }
1489+
1490+ * object = data -> maybe_object ;
1491+ return 0 ;
1492+ }
1493+
14781494/* See grab_values */
1479- static void grab_tag_values (struct atom_value * val , int deref , struct object * obj )
1495+ static int grab_tag_values (struct atom_value * val , int deref ,
1496+ struct expand_data * data , const char * refname ,
1497+ struct strbuf * err , int * eaten )
14801498{
1481- int i ;
1482- struct tag * tag = ( struct tag * ) obj ;
1499+ struct tag * tag = NULL ;
1500+ int i , ret ;
14831501
14841502 for (i = 0 ; i < used_atom_cnt ; i ++ ) {
14851503 const char * name = used_atom [i ].name ;
14861504 enum atom_type atom_type = used_atom [i ].atom_type ;
14871505 struct atom_value * v = & val [i ];
14881506 if (!!deref != (* name == '*' ))
14891507 continue ;
1508+
1509+ if (!tag ) {
1510+ struct object * object ;
1511+
1512+ ret = get_or_parse_object (data , refname , & object , err , eaten );
1513+ if (ret < 0 )
1514+ return ret ;
1515+
1516+ tag = (struct tag * ) object ;
1517+ }
1518+
14901519 if (deref )
14911520 name ++ ;
14921521 if (atom_type == ATOM_TAG )
@@ -1496,22 +1525,38 @@ static void grab_tag_values(struct atom_value *val, int deref, struct object *ob
14961525 else if (atom_type == ATOM_OBJECT && tag -> tagged )
14971526 v -> s = xstrdup (oid_to_hex (& tag -> tagged -> oid ));
14981527 }
1528+
1529+ return 0 ;
14991530}
15001531
15011532/* See grab_values */
1502- static void grab_commit_values (struct atom_value * val , int deref , struct object * obj )
1533+ static int grab_commit_values (struct atom_value * val , int deref ,
1534+ struct expand_data * data , const char * refname ,
1535+ struct strbuf * err , int * eaten )
15031536{
1504- int i ;
1505- struct commit * commit = ( struct commit * ) obj ;
1537+ int i , ret ;
1538+ struct commit * commit = NULL ;
15061539
15071540 for (i = 0 ; i < used_atom_cnt ; i ++ ) {
15081541 const char * name = used_atom [i ].name ;
15091542 enum atom_type atom_type = used_atom [i ].atom_type ;
15101543 struct atom_value * v = & val [i ];
1544+
15111545 if (!!deref != (* name == '*' ))
15121546 continue ;
15131547 if (deref )
15141548 name ++ ;
1549+
1550+ if (!commit ) {
1551+ struct object * object ;
1552+
1553+ ret = get_or_parse_object (data , refname , & object , err , eaten );
1554+ if (ret < 0 )
1555+ return ret ;
1556+
1557+ commit = (struct commit * ) object ;
1558+ }
1559+
15151560 if (atom_type == ATOM_TREE &&
15161561 grab_oid (name , "tree" , get_commit_tree_oid (commit ), v , & used_atom [i ]))
15171562 continue ;
@@ -1531,6 +1576,8 @@ static void grab_commit_values(struct atom_value *val, int deref, struct object
15311576 v -> s = strbuf_detach (& s , NULL );
15321577 }
15331578 }
1579+
1580+ return 0 ;
15341581}
15351582
15361583static const char * find_wholine (const char * who , int wholen , const char * buf )
@@ -1759,10 +1806,12 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void
17591806 }
17601807}
17611808
1762- static void grab_signature (struct atom_value * val , int deref , struct object * obj )
1809+ static int grab_signature (struct atom_value * val , int deref ,
1810+ struct expand_data * data , const char * refname ,
1811+ struct strbuf * err , int * eaten )
17631812{
1764- int i ;
1765- struct commit * commit = ( struct commit * ) obj ;
1813+ int i , ret ;
1814+ struct commit * commit = NULL ;
17661815 struct signature_check sigc = { 0 };
17671816 int signature_checked = 0 ;
17681817
@@ -1790,6 +1839,16 @@ static void grab_signature(struct atom_value *val, int deref, struct object *obj
17901839 continue ;
17911840
17921841 if (!signature_checked ) {
1842+ if (!commit ) {
1843+ struct object * object ;
1844+
1845+ ret = get_or_parse_object (data , refname , & object , err , eaten );
1846+ if (ret < 0 )
1847+ return ret ;
1848+
1849+ commit = (struct commit * ) object ;
1850+ }
1851+
17931852 check_commit_signature (commit , & sigc );
17941853 signature_checked = 1 ;
17951854 }
@@ -1843,6 +1902,8 @@ static void grab_signature(struct atom_value *val, int deref, struct object *obj
18431902
18441903 if (signature_checked )
18451904 signature_check_clear (& sigc );
1905+
1906+ return 0 ;
18461907}
18471908
18481909static void find_subpos (const char * buf ,
@@ -1920,9 +1981,8 @@ static void append_lines(struct strbuf *out, const char *buf, unsigned long size
19201981}
19211982
19221983static void grab_describe_values (struct atom_value * val , int deref ,
1923- struct object * obj )
1984+ struct expand_data * data )
19241985{
1925- struct commit * commit = (struct commit * )obj ;
19261986 int i ;
19271987
19281988 for (i = 0 ; i < used_atom_cnt ; i ++ ) {
@@ -1944,7 +2004,7 @@ static void grab_describe_values(struct atom_value *val, int deref,
19442004 cmd .git_cmd = 1 ;
19452005 strvec_push (& cmd .args , "describe" );
19462006 strvec_pushv (& cmd .args , atom -> u .describe_args .v );
1947- strvec_push (& cmd .args , oid_to_hex (& commit -> object . oid ));
2007+ strvec_push (& cmd .args , oid_to_hex (& data -> oid ));
19482008 if (pipe_command (& cmd , NULL , 0 , & out , 0 , & err , 0 ) < 0 ) {
19492009 error (_ ("failed to run 'describe'" ));
19502010 v -> s = xstrdup ("" );
@@ -2066,24 +2126,36 @@ static void fill_missing_values(struct atom_value *val)
20662126 * pointed at by the ref itself; otherwise it is the object the
20672127 * ref (which is a tag) refers to.
20682128 */
2069- static void grab_values (struct atom_value * val , int deref , struct object * obj , struct expand_data * data )
2129+ static int grab_values (struct atom_value * val , int deref , struct expand_data * data ,
2130+ const char * refname , struct strbuf * err , int * eaten )
20702131{
20712132 void * buf = data -> content ;
2133+ int ret ;
20722134
2073- switch (obj -> type ) {
2135+ switch (data -> type ) {
20742136 case OBJ_TAG :
2075- grab_tag_values (val , deref , obj );
2137+ ret = grab_tag_values (val , deref , data , refname , err , eaten );
2138+ if (ret < 0 )
2139+ goto out ;
2140+
20762141 grab_sub_body_contents (val , deref , data );
20772142 grab_person ("tagger" , val , deref , buf );
2078- grab_describe_values (val , deref , obj );
2143+ grab_describe_values (val , deref , data );
20792144 break ;
20802145 case OBJ_COMMIT :
2081- grab_commit_values (val , deref , obj );
2146+ ret = grab_commit_values (val , deref , data , refname , err , eaten );
2147+ if (ret < 0 )
2148+ goto out ;
2149+
20822150 grab_sub_body_contents (val , deref , data );
20832151 grab_person ("author" , val , deref , buf );
20842152 grab_person ("committer" , val , deref , buf );
2085- grab_signature (val , deref , obj );
2086- grab_describe_values (val , deref , obj );
2153+
2154+ ret = grab_signature (val , deref , data , refname , err , eaten );
2155+ if (ret < 0 )
2156+ goto out ;
2157+
2158+ grab_describe_values (val , deref , data );
20872159 break ;
20882160 case OBJ_TREE :
20892161 /* grab_tree_values(val, deref, obj, buf, sz); */
@@ -2094,8 +2166,12 @@ static void grab_values(struct atom_value *val, int deref, struct object *obj, s
20942166 grab_sub_body_contents (val , deref , data );
20952167 break ;
20962168 default :
2097- die ("Eh? Object of type %d?" , obj -> type );
2169+ die ("Eh? Object of type %d?" , data -> type );
20982170 }
2171+
2172+ ret = 0 ;
2173+ out :
2174+ return ret ;
20992175}
21002176
21012177static inline char * copy_advance (char * dst , const char * src )
@@ -2292,38 +2368,41 @@ static const char *get_refname(struct used_atom *atom, struct ref_array_item *re
22922368 return show_ref (& atom -> u .refname , ref -> refname );
22932369}
22942370
2295- static int get_object (struct ref_array_item * ref , int deref , struct object * * obj ,
2371+ static int get_object (struct ref_array_item * ref , int deref ,
22962372 struct expand_data * oi , struct strbuf * err )
22972373{
2298- /* parse_object_buffer() will set eaten to 0 if free() will be needed */
2299- int eaten = 1 ;
2374+ /* parse_object_buffer() will set eaten to 1 if free() will be needed */
2375+ int eaten = 0 ;
2376+ int ret ;
2377+
23002378 if (oi -> info .contentp ) {
23012379 /* We need to know that to use parse_object_buffer properly */
23022380 oi -> info .sizep = & oi -> size ;
23032381 oi -> info .typep = & oi -> type ;
23042382 }
2383+
23052384 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 );
2385+ OBJECT_INFO_LOOKUP_REPLACE )) {
2386+ ret = strbuf_addf_ret (err , -1 , _ ("missing object %s for %s" ),
2387+ oid_to_hex (& oi -> oid ), ref -> refname );
2388+ goto out ;
2389+ }
23092390 if (oi -> info .disk_sizep && oi -> disk_size < 0 )
23102391 BUG ("Object size is less than zero." );
23112392
23122393 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 );
2394+ ret = grab_values (ref -> value , deref , oi , ref -> refname , err , & eaten );
2395+ if (ret < 0 )
2396+ goto out ;
23212397 }
23222398
23232399 grab_common_values (ref -> value , deref , oi );
2400+ ret = 0 ;
2401+
2402+ out :
23242403 if (!eaten )
23252404 free (oi -> content );
2326- return 0 ;
2405+ return ret ;
23272406}
23282407
23292408static void populate_worktree_map (struct hashmap * map , struct worktree * * worktrees )
@@ -2376,7 +2455,6 @@ static char *get_worktree_path(const struct ref_array_item *ref)
23762455 */
23772456static int populate_value (struct ref_array_item * ref , struct strbuf * err )
23782457{
2379- struct object * obj ;
23802458 int i ;
23812459 struct object_info empty = OBJECT_INFO_INIT ;
23822460 int ahead_behind_atoms = 0 ;
@@ -2564,14 +2642,14 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
25642642
25652643
25662644 oi .oid = ref -> objectname ;
2567- if (get_object (ref , 0 , & obj , & oi , err ))
2645+ if (get_object (ref , 0 , & oi , err ))
25682646 return -1 ;
25692647
25702648 /*
25712649 * If there is no atom that wants to know about tagged
25722650 * object, we are done.
25732651 */
2574- if (!need_tagged || (obj -> type != OBJ_TAG ))
2652+ if (!need_tagged || (oi . type != OBJ_TAG ))
25752653 return 0 ;
25762654
25772655 /*
@@ -2589,7 +2667,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
25892667 }
25902668 }
25912669
2592- return get_object (ref , 1 , & obj , & oi_deref , err );
2670+ return get_object (ref , 1 , & oi_deref , err );
25932671}
25942672
25952673/*
0 commit comments