@@ -261,6 +261,12 @@ struct strbuf_list {
261261 int alloc ;
262262};
263263
264+ /*
265+ * Format the configuration key-value pair (`key_`, `value_`) and
266+ * append it into strbuf `buf`. Returns a negative value on failure,
267+ * 0 on success, 1 on a missing optional value (i.e., telling the
268+ * caller to pretend that <key_,value_> did not exist).
269+ */
264270static int format_config (const struct config_display_options * opts ,
265271 struct strbuf * buf , const char * key_ ,
266272 const char * value_ , const struct key_value_info * kvi )
@@ -299,7 +305,10 @@ static int format_config(const struct config_display_options *opts,
299305 char * v ;
300306 if (git_config_pathname (& v , key_ , value_ ) < 0 )
301307 return -1 ;
302- strbuf_addstr (buf , v );
308+ if (v )
309+ strbuf_addstr (buf , v );
310+ else
311+ return 1 ; /* :(optional)no-such-file */
303312 free ((char * )v );
304313 } else if (opts -> type == TYPE_EXPIRY_DATE ) {
305314 timestamp_t t ;
@@ -344,6 +353,7 @@ static int collect_config(const char *key_, const char *value_,
344353 struct collect_config_data * data = cb ;
345354 struct strbuf_list * values = data -> values ;
346355 const struct key_value_info * kvi = ctx -> kvi ;
356+ int status ;
347357
348358 if (!(data -> get_value_flags & GET_VALUE_KEY_REGEXP ) &&
349359 strcmp (key_ , data -> key ))
@@ -361,8 +371,15 @@ static int collect_config(const char *key_, const char *value_,
361371 ALLOC_GROW (values -> items , values -> nr + 1 , values -> alloc );
362372 strbuf_init (& values -> items [values -> nr ], 0 );
363373
364- return format_config (data -> display_opts , & values -> items [values -> nr ++ ],
365- key_ , value_ , kvi );
374+ status = format_config (data -> display_opts , & values -> items [values -> nr ++ ],
375+ key_ , value_ , kvi );
376+ if (status < 0 )
377+ return status ;
378+ if (status ) {
379+ strbuf_release (& values -> items [-- values -> nr ]);
380+ status = 0 ;
381+ }
382+ return status ;
366383}
367384
368385static int get_value (const struct config_location_options * opts ,
@@ -438,15 +455,23 @@ static int get_value(const struct config_location_options *opts,
438455 if (!values .nr && display_opts -> default_value ) {
439456 struct key_value_info kvi = KVI_INIT ;
440457 struct strbuf * item ;
458+ int status ;
441459
442460 kvi_from_param (& kvi );
443461 ALLOC_GROW (values .items , values .nr + 1 , values .alloc );
444462 item = & values .items [values .nr ++ ];
445463 strbuf_init (item , 0 );
446- if (format_config (display_opts , item , key_ ,
447- display_opts -> default_value , & kvi ) < 0 )
464+
465+ status = format_config (display_opts , item , key_ ,
466+ display_opts -> default_value , & kvi );
467+ if (status < 0 )
448468 die (_ ("failed to format default config value: %s" ),
449469 display_opts -> default_value );
470+ if (status ) {
471+ /* default was a missing optional value */
472+ values .nr -- ;
473+ strbuf_release (item );
474+ }
450475 }
451476
452477 ret = !values .nr ;
@@ -714,11 +739,13 @@ static int get_urlmatch(const struct config_location_options *opts,
714739 for_each_string_list_item (item , & values ) {
715740 struct urlmatch_current_candidate_value * matched = item -> util ;
716741 struct strbuf buf = STRBUF_INIT ;
742+ int status ;
717743
718- format_config (& display_opts , & buf , item -> string ,
719- matched -> value_is_null ? NULL : matched -> value .buf ,
720- & matched -> kvi );
721- fwrite (buf .buf , 1 , buf .len , stdout );
744+ status = format_config (& display_opts , & buf , item -> string ,
745+ matched -> value_is_null ? NULL : matched -> value .buf ,
746+ & matched -> kvi );
747+ if (!status )
748+ fwrite (buf .buf , 1 , buf .len , stdout );
722749 strbuf_release (& buf );
723750
724751 strbuf_release (& matched -> value );
0 commit comments