builtin/cat-file: introduce function to report object status

We have multiple callsites that report the status of an object, for example when the objec tis missing or its name is ambiguous. We're about to add a couple more such callsites to report on "excluded" objects. Prepare for this by introducing a new function `report_object_status()` that encapsulates the functionality. Note that this function also flushes stdout, which is a requirement so that request-response style batched modes can learn about the status before proceeding to the next object. We already flush correctly at all existing callsites, even though the flush in `batch_one_object()` only comes after the switch statement. That flush is now redundant, and we could in theory deduplicate it by moving it into all branches that don't use `report_object_status()`. But that doesn't quite feel sensible: - The duplicate flush should ultimately just be a no-op for us and thus shouldn't impact performance significantly. - By keeping the flush in `report_object_status()` we ensure that all future callers get semantics correct. So let's just be pragmatic and live with the duplicated flush. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Apr 2, 2025 at 13:13 UTC 1914ae0d706f7811eb9f293ae14ca9eb4f25fcca
1 file changed +13 -5
builtin/cat-file.c
+13 -5
@@ -455,6 +455,16 @@ static void print_default_format(struct strbuf *scratch, struct expand_data *dat
455 (uintmax_t)data->size, opt->output_delim);
456 }
457
458 +static void report_object_status(struct batch_options *opt,
459 + const char *obj_name,
460 + const struct object_id *oid,
461 + const char *status)
462 +{
463 + printf("%s %s%c", obj_name ? obj_name : oid_to_hex(oid),
464 + status, opt->output_delim);
465 + fflush(stdout);
466 +}
467 +
468 /*
469 * If "pack" is non-NULL, then "offset" is the byte offset within the pack from
470 * which the object may be accessed (though note that we may also rely on
@@ -481,9 +491,7 @@ static void batch_object_write(const char *obj_name,
491 &data->oid, &data->info,
492 OBJECT_INFO_LOOKUP_REPLACE);
493 if (ret < 0) {
484 - printf("%s missing%c",
485 - obj_name ? obj_name : oid_to_hex(&data->oid), opt->output_delim);
486 - fflush(stdout);
494 + report_object_status(opt, obj_name, &data->oid, "missing");
495 return;
496 }
497
@@ -535,10 +543,10 @@ static void batch_one_object(const char *obj_name,
543 if (result != FOUND) {
544 switch (result) {
545 case MISSING_OBJECT:
538 - printf("%s missing%c", obj_name, opt->output_delim);
546 + report_object_status(opt, obj_name, &data->oid, "missing");
547 break;
548 case SHORT_NAME_AMBIGUOUS:
541 - printf("%s ambiguous%c", obj_name, opt->output_delim);
549 + report_object_status(opt, obj_name, &data->oid, "ambiguous");
550 break;
551 case DANGLING_SYMLINK:
552 printf("dangling %"PRIuMAX"%c%s%c",