@@ -43,6 +43,7 @@ void setup_ref_filter_porcelain_msg(void)
43
43
44
44
typedef enum { FIELD_STR , FIELD_ULONG , FIELD_TIME } cmp_type ;
45
45
typedef enum { COMPARE_EQUAL , COMPARE_UNEQUAL , COMPARE_NONE } cmp_status ;
46
+ typedef enum { SOURCE_NONE = 0 , SOURCE_OBJ , SOURCE_OTHER } info_source ;
46
47
47
48
struct align {
48
49
align_type position ;
@@ -62,6 +63,17 @@ struct refname_atom {
62
63
int lstrip , rstrip ;
63
64
};
64
65
66
+ struct expand_data {
67
+ struct object_id oid ;
68
+ enum object_type type ;
69
+ unsigned long size ;
70
+ off_t disk_size ;
71
+ struct object_id delta_base_oid ;
72
+ void * content ;
73
+
74
+ struct object_info info ;
75
+ } oi , oi_deref ;
76
+
65
77
/*
66
78
* An atom is a valid field atom listed below, possibly prefixed with
67
79
* a "*" to denote deref_tag().
@@ -75,6 +87,7 @@ struct refname_atom {
75
87
static struct used_atom {
76
88
const char * name ;
77
89
cmp_type type ;
90
+ info_source source ;
78
91
union {
79
92
char color [COLOR_MAXLEN ];
80
93
struct align align ;
@@ -202,6 +215,30 @@ static int remote_ref_atom_parser(const struct ref_format *format, struct used_a
202
215
return 0 ;
203
216
}
204
217
218
+ static int objecttype_atom_parser (const struct ref_format * format , struct used_atom * atom ,
219
+ const char * arg , struct strbuf * err )
220
+ {
221
+ if (arg )
222
+ return strbuf_addf_ret (err , -1 , _ ("%%(objecttype) does not take arguments" ));
223
+ if (* atom -> name == '*' )
224
+ oi_deref .info .typep = & oi_deref .type ;
225
+ else
226
+ oi .info .typep = & oi .type ;
227
+ return 0 ;
228
+ }
229
+
230
+ static int objectsize_atom_parser (const struct ref_format * format , struct used_atom * atom ,
231
+ const char * arg , struct strbuf * err )
232
+ {
233
+ if (arg )
234
+ return strbuf_addf_ret (err , -1 , _ ("%%(objectsize) does not take arguments" ));
235
+ if (* atom -> name == '*' )
236
+ oi_deref .info .sizep = & oi_deref .size ;
237
+ else
238
+ oi .info .sizep = & oi .size ;
239
+ return 0 ;
240
+ }
241
+
205
242
static int body_atom_parser (const struct ref_format * format , struct used_atom * atom ,
206
243
const char * arg , struct strbuf * err )
207
244
{
@@ -382,49 +419,50 @@ static int head_atom_parser(const struct ref_format *format, struct used_atom *a
382
419
383
420
static struct {
384
421
const char * name ;
422
+ info_source source ;
385
423
cmp_type cmp_type ;
386
424
int (* parser )(const struct ref_format * format , struct used_atom * atom ,
387
425
const char * arg , struct strbuf * err );
388
426
} valid_atom [] = {
389
- { "refname" , FIELD_STR , refname_atom_parser },
390
- { "objecttype" },
391
- { "objectsize" , FIELD_ULONG },
392
- { "objectname" , FIELD_STR , objectname_atom_parser },
393
- { "tree" },
394
- { "parent" },
395
- { "numparent" , FIELD_ULONG },
396
- { "object" },
397
- { "type" },
398
- { "tag" },
399
- { "author" },
400
- { "authorname" },
401
- { "authoremail" },
402
- { "authordate" , FIELD_TIME },
403
- { "committer" },
404
- { "committername" },
405
- { "committeremail" },
406
- { "committerdate" , FIELD_TIME },
407
- { "tagger" },
408
- { "taggername" },
409
- { "taggeremail" },
410
- { "taggerdate" , FIELD_TIME },
411
- { "creator" },
412
- { "creatordate" , FIELD_TIME },
413
- { "subject" , FIELD_STR , subject_atom_parser },
414
- { "body" , FIELD_STR , body_atom_parser },
415
- { "trailers" , FIELD_STR , trailers_atom_parser },
416
- { "contents" , FIELD_STR , contents_atom_parser },
417
- { "upstream" , FIELD_STR , remote_ref_atom_parser },
418
- { "push" , FIELD_STR , remote_ref_atom_parser },
419
- { "symref" , FIELD_STR , refname_atom_parser },
420
- { "flag" },
421
- { "HEAD" , FIELD_STR , head_atom_parser },
422
- { "color" , FIELD_STR , color_atom_parser },
423
- { "align" , FIELD_STR , align_atom_parser },
424
- { "end" },
425
- { "if" , FIELD_STR , if_atom_parser },
426
- { "then" },
427
- { "else" },
427
+ { "refname" , SOURCE_NONE , FIELD_STR , refname_atom_parser },
428
+ { "objecttype" , SOURCE_OTHER , FIELD_STR , objecttype_atom_parser },
429
+ { "objectsize" , SOURCE_OTHER , FIELD_ULONG , objectsize_atom_parser },
430
+ { "objectname" , SOURCE_OTHER , FIELD_STR , objectname_atom_parser },
431
+ { "tree" , SOURCE_OBJ },
432
+ { "parent" , SOURCE_OBJ },
433
+ { "numparent" , SOURCE_OBJ , FIELD_ULONG },
434
+ { "object" , SOURCE_OBJ },
435
+ { "type" , SOURCE_OBJ },
436
+ { "tag" , SOURCE_OBJ },
437
+ { "author" , SOURCE_OBJ },
438
+ { "authorname" , SOURCE_OBJ },
439
+ { "authoremail" , SOURCE_OBJ },
440
+ { "authordate" , SOURCE_OBJ , FIELD_TIME },
441
+ { "committer" , SOURCE_OBJ },
442
+ { "committername" , SOURCE_OBJ },
443
+ { "committeremail" , SOURCE_OBJ },
444
+ { "committerdate" , SOURCE_OBJ , FIELD_TIME },
445
+ { "tagger" , SOURCE_OBJ },
446
+ { "taggername" , SOURCE_OBJ },
447
+ { "taggeremail" , SOURCE_OBJ },
448
+ { "taggerdate" , SOURCE_OBJ , FIELD_TIME },
449
+ { "creator" , SOURCE_OBJ },
450
+ { "creatordate" , SOURCE_OBJ , FIELD_TIME },
451
+ { "subject" , SOURCE_OBJ , FIELD_STR , subject_atom_parser },
452
+ { "body" , SOURCE_OBJ , FIELD_STR , body_atom_parser },
453
+ { "trailers" , SOURCE_OBJ , FIELD_STR , trailers_atom_parser },
454
+ { "contents" , SOURCE_OBJ , FIELD_STR , contents_atom_parser },
455
+ { "upstream" , SOURCE_NONE , FIELD_STR , remote_ref_atom_parser },
456
+ { "push" , SOURCE_NONE , FIELD_STR , remote_ref_atom_parser },
457
+ { "symref" , SOURCE_NONE , FIELD_STR , refname_atom_parser },
458
+ { "flag" , SOURCE_NONE },
459
+ { "HEAD" , SOURCE_NONE , FIELD_STR , head_atom_parser },
460
+ { "color" , SOURCE_NONE , FIELD_STR , color_atom_parser },
461
+ { "align" , SOURCE_NONE , FIELD_STR , align_atom_parser },
462
+ { "end" , SOURCE_NONE },
463
+ { "if" , SOURCE_NONE , FIELD_STR , if_atom_parser },
464
+ { "then" , SOURCE_NONE },
465
+ { "else" , SOURCE_NONE },
428
466
};
429
467
430
468
#define REF_FORMATTING_STATE_INIT { 0, NULL }
@@ -500,6 +538,13 @@ static int parse_ref_filter_atom(const struct ref_format *format,
500
538
REALLOC_ARRAY (used_atom , used_atom_cnt );
501
539
used_atom [at ].name = xmemdupz (atom , ep - atom );
502
540
used_atom [at ].type = valid_atom [i ].cmp_type ;
541
+ used_atom [at ].source = valid_atom [i ].source ;
542
+ if (used_atom [at ].source == SOURCE_OBJ ) {
543
+ if (* atom == '*' )
544
+ oi_deref .info .contentp = & oi_deref .content ;
545
+ else
546
+ oi .info .contentp = & oi .content ;
547
+ }
503
548
if (arg ) {
504
549
arg = used_atom [at ].name + (arg - atom ) + 1 ;
505
550
if (!* arg ) {
@@ -795,25 +840,6 @@ int verify_ref_format(struct ref_format *format)
795
840
return 0 ;
796
841
}
797
842
798
- /*
799
- * Given an object name, read the object data and size, and return a
800
- * "struct object". If the object data we are returning is also borrowed
801
- * by the "struct object" representation, set *eaten as well---it is a
802
- * signal from parse_object_buffer to us not to free the buffer.
803
- */
804
- static void * get_obj (const struct object_id * oid , struct object * * obj , unsigned long * sz , int * eaten )
805
- {
806
- enum object_type type ;
807
- void * buf = read_object_file (oid , & type , sz );
808
-
809
- if (buf )
810
- * obj = parse_object_buffer (the_repository , oid , type , * sz ,
811
- buf , eaten );
812
- else
813
- * obj = NULL ;
814
- return buf ;
815
- }
816
-
817
843
static int grab_objectname (const char * name , const struct object_id * oid ,
818
844
struct atom_value * v , struct used_atom * atom )
819
845
{
@@ -834,7 +860,7 @@ static int grab_objectname(const char *name, const struct object_id *oid,
834
860
}
835
861
836
862
/* See grab_values */
837
- static void grab_common_values (struct atom_value * val , int deref , struct object * obj , void * buf , unsigned long sz )
863
+ static void grab_common_values (struct atom_value * val , int deref , struct expand_data * oi )
838
864
{
839
865
int i ;
840
866
@@ -846,13 +872,13 @@ static void grab_common_values(struct atom_value *val, int deref, struct object
846
872
if (deref )
847
873
name ++ ;
848
874
if (!strcmp (name , "objecttype" ))
849
- v -> s = type_name (obj -> type );
875
+ v -> s = type_name (oi -> type );
850
876
else if (!strcmp (name , "objectsize" )) {
851
- v -> value = sz ;
852
- v -> s = xstrfmt ("%lu" , sz );
877
+ v -> value = oi -> size ;
878
+ v -> s = xstrfmt ("%lu" , oi -> size );
853
879
}
854
880
else if (deref )
855
- grab_objectname (name , & obj -> oid , v , & used_atom [i ]);
881
+ grab_objectname (name , & oi -> oid , v , & used_atom [i ]);
856
882
}
857
883
}
858
884
@@ -1211,7 +1237,6 @@ static void fill_missing_values(struct atom_value *val)
1211
1237
*/
1212
1238
static void grab_values (struct atom_value * val , int deref , struct object * obj , void * buf , unsigned long sz )
1213
1239
{
1214
- grab_common_values (val , deref , obj , buf , sz );
1215
1240
switch (obj -> type ) {
1216
1241
case OBJ_TAG :
1217
1242
grab_tag_values (val , deref , obj , buf , sz );
@@ -1435,24 +1460,36 @@ static const char *get_refname(struct used_atom *atom, struct ref_array_item *re
1435
1460
return show_ref (& atom -> u .refname , ref -> refname );
1436
1461
}
1437
1462
1438
- static int get_object (struct ref_array_item * ref , const struct object_id * oid ,
1439
- int deref , struct object * * obj , struct strbuf * err )
1463
+ static int get_object (struct ref_array_item * ref , int deref , struct object * * obj ,
1464
+ struct expand_data * oi , struct strbuf * err )
1440
1465
{
1441
- int eaten ;
1442
- int ret = 0 ;
1443
- unsigned long size ;
1444
- void * buf = get_obj (oid , obj , & size , & eaten );
1445
- if (!buf )
1446
- ret = strbuf_addf_ret (err , -1 , _ ("missing object %s for %s" ),
1447
- oid_to_hex (oid ), ref -> refname );
1448
- else if (!* obj )
1449
- ret = strbuf_addf_ret (err , -1 , _ ("parse_object_buffer failed on %s for %s" ),
1450
- oid_to_hex (oid ), ref -> refname );
1451
- else
1452
- grab_values (ref -> value , deref , * obj , buf , size );
1466
+ int eaten = 0 ;
1467
+
1468
+ if (oi -> info .contentp ) {
1469
+ /* We need to know that to use parse_object_buffer properly */
1470
+ oi -> info .sizep = & oi -> size ;
1471
+ oi -> info .typep = & oi -> type ;
1472
+ }
1473
+ if (oid_object_info_extended (the_repository , & oi -> oid , & oi -> info ,
1474
+ OBJECT_INFO_LOOKUP_REPLACE ))
1475
+ return strbuf_addf_ret (err , -1 , _ ("missing object %s for %s" ),
1476
+ oid_to_hex (& oi -> oid ), ref -> refname );
1477
+
1478
+ if (oi -> info .contentp ) {
1479
+ * obj = parse_object_buffer (the_repository , & oi -> oid , oi -> type , oi -> size , oi -> content , & eaten );
1480
+ if (!obj ) {
1481
+ if (!eaten )
1482
+ free (oi -> content );
1483
+ return strbuf_addf_ret (err , -1 , _ ("parse_object_buffer failed on %s for %s" ),
1484
+ oid_to_hex (& oi -> oid ), ref -> refname );
1485
+ }
1486
+ grab_values (ref -> value , deref , * obj , oi -> content , oi -> size );
1487
+ }
1488
+
1489
+ grab_common_values (ref -> value , deref , oi );
1453
1490
if (!eaten )
1454
- free (buf );
1455
- return ret ;
1491
+ free (oi -> content );
1492
+ return 0 ;
1456
1493
}
1457
1494
1458
1495
/*
@@ -1462,7 +1499,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1462
1499
{
1463
1500
struct object * obj ;
1464
1501
int i ;
1465
- const struct object_id * tagged ;
1502
+ struct object_info empty = OBJECT_INFO_INIT ;
1466
1503
1467
1504
ref -> value = xcalloc (used_atom_cnt , sizeof (struct atom_value ));
1468
1505
@@ -1496,6 +1533,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1496
1533
refname = get_symref (atom , ref );
1497
1534
else if (starts_with (name , "upstream" )) {
1498
1535
const char * branch_name ;
1536
+ v -> s = "" ;
1499
1537
/* only local branches may have an upstream */
1500
1538
if (!skip_prefix (ref -> refname , "refs/heads/" ,
1501
1539
& branch_name ))
@@ -1508,6 +1546,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1508
1546
continue ;
1509
1547
} else if (atom -> u .remote_ref .push ) {
1510
1548
const char * branch_name ;
1549
+ v -> s = "" ;
1511
1550
if (!skip_prefix (ref -> refname , "refs/heads/" ,
1512
1551
& branch_name ))
1513
1552
continue ;
@@ -1548,22 +1587,26 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1548
1587
continue ;
1549
1588
} else if (starts_with (name , "align" )) {
1550
1589
v -> handler = align_atom_handler ;
1590
+ v -> s = "" ;
1551
1591
continue ;
1552
1592
} else if (!strcmp (name , "end" )) {
1553
1593
v -> handler = end_atom_handler ;
1594
+ v -> s = "" ;
1554
1595
continue ;
1555
1596
} else if (starts_with (name , "if" )) {
1556
1597
const char * s ;
1557
-
1598
+ v -> s = "" ;
1558
1599
if (skip_prefix (name , "if:" , & s ))
1559
1600
v -> s = xstrdup (s );
1560
1601
v -> handler = if_atom_handler ;
1561
1602
continue ;
1562
1603
} else if (!strcmp (name , "then" )) {
1563
1604
v -> handler = then_atom_handler ;
1605
+ v -> s = "" ;
1564
1606
continue ;
1565
1607
} else if (!strcmp (name , "else" )) {
1566
1608
v -> handler = else_atom_handler ;
1609
+ v -> s = "" ;
1567
1610
continue ;
1568
1611
} else
1569
1612
continue ;
@@ -1576,13 +1619,20 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1576
1619
1577
1620
for (i = 0 ; i < used_atom_cnt ; i ++ ) {
1578
1621
struct atom_value * v = & ref -> value [i ];
1579
- if (v -> s == NULL )
1580
- break ;
1622
+ if (v -> s == NULL && used_atom [i ].source == SOURCE_NONE )
1623
+ return strbuf_addf_ret (err , -1 , _ ("missing object %s for %s" ),
1624
+ oid_to_hex (& ref -> objectname ), ref -> refname );
1581
1625
}
1582
- if (used_atom_cnt <= i )
1626
+
1627
+ if (need_tagged )
1628
+ oi .info .contentp = & oi .content ;
1629
+ if (!memcmp (& oi .info , & empty , sizeof (empty )) &&
1630
+ !memcmp (& oi_deref .info , & empty , sizeof (empty )))
1583
1631
return 0 ;
1584
1632
1585
- if (get_object (ref , & ref -> objectname , 0 , & obj , err ))
1633
+
1634
+ oi .oid = ref -> objectname ;
1635
+ if (get_object (ref , 0 , & obj , & oi , err ))
1586
1636
return -1 ;
1587
1637
1588
1638
/*
@@ -1596,15 +1646,15 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1596
1646
* If it is a tag object, see if we use a value that derefs
1597
1647
* the object, and if we do grab the object it refers to.
1598
1648
*/
1599
- tagged = & ((struct tag * )obj )-> tagged -> oid ;
1649
+ oi_deref . oid = ((struct tag * )obj )-> tagged -> oid ;
1600
1650
1601
1651
/*
1602
1652
* NEEDSWORK: This derefs tag only once, which
1603
1653
* is good to deal with chains of trust, but
1604
1654
* is not consistent with what deref_tag() does
1605
1655
* which peels the onion to the core.
1606
1656
*/
1607
- return get_object (ref , tagged , 1 , & obj , err );
1657
+ return get_object (ref , 1 , & obj , & oi_deref , err );
1608
1658
}
1609
1659
1610
1660
/*
0 commit comments