diff --git a/fsck.c b/fsck.c index 3614aa56a3..e16c892f6a 100644 --- a/fsck.c +++ b/fsck.c @@ -280,6 +280,19 @@ static int report(struct fsck_options *options, return result; } +int fsck_report_ref(struct fsck_options *options, + struct fsck_ref_report *report, + enum fsck_msg_id msg_id, + const char *fmt, ...) +{ + va_list ap; + int result; + va_start(ap, fmt); + result = fsck_vreport(options, report, msg_id, fmt, ap); + va_end(ap); + return result; +} + void fsck_enable_object_names(struct fsck_options *options) { if (!options->object_names) @@ -1237,6 +1250,32 @@ int fsck_objects_error_function(struct fsck_options *o, return 1; } +int fsck_refs_error_function(struct fsck_options *options UNUSED, + void *fsck_report, + enum fsck_msg_type msg_type, + enum fsck_msg_id msg_id UNUSED, + const char *message) +{ + struct fsck_ref_report *report = fsck_report; + struct strbuf sb = STRBUF_INIT; + int ret = 0; + + strbuf_addstr(&sb, report->path); + + if (report->oid) + strbuf_addf(&sb, " -> (%s)", oid_to_hex(report->oid)); + else if (report->referent) + strbuf_addf(&sb, " -> (%s)", report->referent); + + if (msg_type == FSCK_WARN) + warning("%s: %s", sb.buf, message); + else + ret = error("%s: %s", sb.buf, message); + + strbuf_release(&sb); + return ret; +} + static int fsck_blobs(struct oidset *blobs_found, struct oidset *blobs_done, enum fsck_msg_id msg_missing, enum fsck_msg_id msg_type, struct fsck_options *options, const char *blob_type) diff --git a/fsck.h b/fsck.h index 3b80d02506..2002590f60 100644 --- a/fsck.h +++ b/fsck.h @@ -133,11 +133,23 @@ int fsck_objects_error_cb_print_missing_gitmodules(struct fsck_options *o, enum fsck_msg_id msg_id, const char *message); +int fsck_refs_error_function(struct fsck_options *options, + void *fsck_report, + enum fsck_msg_type msg_type, + enum fsck_msg_id msg_id, + const char *message); + struct fsck_object_report { const struct object_id *oid; enum object_type object_type; }; +struct fsck_ref_report { + const char *path; + const struct object_id *oid; + const char *referent; +}; + struct fsck_options { fsck_walk_func walk; fsck_error error_func; @@ -175,6 +187,9 @@ struct fsck_options { .gitattributes_done = OIDSET_INIT, \ .error_func = fsck_objects_error_cb_print_missing_gitmodules, \ } +#define FSCK_REFS_OPTIONS_DEFAULT { \ + .error_func = fsck_refs_error_function, \ +} /* descend in all linked child objects * the return value is: @@ -216,6 +231,16 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer, */ int fsck_finish(struct fsck_options *options); +/* + * Report an error or warning for refs. + */ +__attribute__((format (printf, 4, 5))) +int fsck_report_ref(struct fsck_options *options, + struct fsck_ref_report *report, + enum fsck_msg_id msg_id, + const char *fmt, ...); + + /* * Subsystem for storing human-readable names for each object. *