From patchwork Mon Jul 1 15:18:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13718302 Received: from mail-pg1-f171.google.com (mail-pg1-f171.google.com [209.85.215.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 790D816C860 for ; Mon, 1 Jul 2024 15:18:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847087; cv=none; b=YgAeDg0NGSSbhdkU+RFcBSNO0dKb9ru5HZu70wMuHL19qpmywi/R/3qSOcI7AgIABjmT6pqlm2GZfWcXe0yXlAE8FBDx710MQOqs1k8WyeKuItXXhUznWQkPbPJ1EwM6JVAslzdqN1nigclnQ6IcfpNHPXjwOjlY8NrxyS7BW24= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847087; c=relaxed/simple; bh=HjxRamwIBVDBrJTCPShcqSfW/l9ZybOknzzMbo8NvQc=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=XDarlLyzWJGAL2u2iPHG3Y26dy50LHIPxMPzd8dQo2yUWjA4aWCUER1hINXDCgIJa5uPrQZqmwy9u0EuzoK8KLKQ26ZB6DFP5Pz/unalgyqtRNQF5/foVsSVS4p+/3YO9BWOB8e7HbWgeQLLCq2Ewnd2m3HSagikJuwXsxSKYNI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=frZyZ0Xx; arc=none smtp.client-ip=209.85.215.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="frZyZ0Xx" Received: by mail-pg1-f171.google.com with SMTP id 41be03b00d2f7-72c03d2926eso1652419a12.2 for ; Mon, 01 Jul 2024 08:18:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719847084; x=1720451884; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=KB31NTTQHNW1UpY1yrRGZGvafu+mlGx18fdC0Two3Xo=; b=frZyZ0Xx5ul2zDJQrOiBcWWt2jL7xjT0ZWM9+GlsNDyR0ZALo2IKfGzsoVokJWmxIP 73LUvxKt8pXCGpDK69fTuDVK6GVXe+KR3kDONU/MltWw06FYQXP7Ji2FuaBMxqITB6R0 XVbV3xhYOIL13thuiJYfhTt24F50RKY8p6Flj4MXZSTkbbnnwIg+gLuj6zPdBUKqPaFb l2oaSU9Z5DXZ0D0RCBGFPT6EWY+F8t88Gwm4nurIbWII/6lZzXZ762sOaNAr0jCveXqX jxMriPJ7YU2OSqzNl34/dyXbJSWNqsxSlXJqRGZpwqyim69XgXnsJAeNqWbrlLdXZRXO 9CYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719847084; x=1720451884; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=KB31NTTQHNW1UpY1yrRGZGvafu+mlGx18fdC0Two3Xo=; b=eI/PCIbeuE/XW0eQsteEccRsSiXbrhz9uxNzDoaBb8jfDDIHAiqnoFoMei75caluxX 8jugRaVP77Dka4XLdAvdar9h2PKu7AvQvkZEHAGO/4mmfQI6DQR1UTZKtZr6hgrmk9L0 xvO8/1ZcLX5pqPLTJId1j7sUX72Pc8ymcvgoEkXHp6Ythd30e7w41Ic3J0L+9MEkhUiv b4jsy/XA2To22SLFMzUYoY3kWOfZ5t4TN2ROc1a9zN2npk+yT47GNFkPzE8BGKpWskLG l6U3iQGv324g0c22U54gpNSaVVLvCWyAyycUbBy62KGCX0Jgi3PLAcXjx4Y2kIE4w444 Xs4A== X-Gm-Message-State: AOJu0YwWJqNEheH+CkDFgN60c0MdvFTMURcyriIlIteWEy5H8ywGinda p5JNTwlqYXLhnQhrmjKEnhYDblJWEFH7xCVv6YeA+J7DVKwfUg77co0HMA== X-Google-Smtp-Source: AGHT+IG/jMmSgBgE1vQsEeuvXbpdfneFxoUseo3OPjC+sB23LtSwCRzU8BJ5JmNNOAwK9+qU/G6tLA== X-Received: by 2002:a17:90a:1089:b0:2c8:f3b4:421 with SMTP id 98e67ed59e1d1-2c93d6edaffmr2757459a91.4.1719847083599; Mon, 01 Jul 2024 08:18:03 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2c91d3eed7csm6873716a91.55.2024.07.01.08.18.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jul 2024 08:18:02 -0700 (PDT) Date: Mon, 1 Jul 2024 23:18:00 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano , Eric Sunshine Subject: [PATCH v6 01/11] fsck: add "fsck_objects_options" to hold objects-related options Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The git-fsck(1) focuses on object database consistency check. It relies on the "fsck_options" to interact with fsck error levels. However, "fsck_options" aims at checking the object database which contains a lot of fields only related to object database. In order to add ref operations, remove the options related to objects in "fsck_options" to "fsck_objects_options" and let the "fsck_options" incorporate "fsck_objects_options". Change the macros and influenced code to adapt into the above design. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- builtin/fsck.c | 12 +++++----- builtin/index-pack.c | 4 ++-- builtin/mktag.c | 2 +- builtin/unpack-objects.c | 4 ++-- fetch-pack.c | 10 ++++---- fsck.c | 51 +++++++++++++++++++++------------------ fsck.h | 52 ++++++++++++++++++++++++---------------- object-file.c | 2 +- 8 files changed, 77 insertions(+), 60 deletions(-) diff --git a/builtin/fsck.c b/builtin/fsck.c index d13a226c2e..13b64f723f 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -42,8 +42,8 @@ static int check_full = 1; static int connectivity_only; static int check_strict; static int keep_cache_objects; -static struct fsck_options fsck_walk_options = FSCK_OPTIONS_DEFAULT; -static struct fsck_options fsck_obj_options = FSCK_OPTIONS_DEFAULT; +static struct fsck_options fsck_walk_options = FSCK_OBJECTS_OPTIONS_DEFAULT; +static struct fsck_options fsck_obj_options = FSCK_OBJECTS_OPTIONS_DEFAULT; static int errors_found; static int write_lost_and_found; static int verbose; @@ -214,7 +214,7 @@ static int mark_used(struct object *obj, enum object_type type UNUSED, static void mark_unreachable_referents(const struct object_id *oid) { - struct fsck_options options = FSCK_OPTIONS_DEFAULT; + struct fsck_options options = FSCK_OBJECTS_OPTIONS_DEFAULT; struct object *obj = lookup_object(the_repository, oid); if (!obj || !(obj->flags & HAS_OBJ)) @@ -233,7 +233,7 @@ static void mark_unreachable_referents(const struct object_id *oid) object_as_type(obj, type, 0); } - options.walk = mark_used; + options.objects_options.walk = mark_used; fsck_walk(obj, NULL, &options); if (obj->type == OBJ_TREE) free_tree_buffer((struct tree *)obj); @@ -936,8 +936,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0); - fsck_walk_options.walk = mark_object; - fsck_obj_options.walk = mark_used; + fsck_walk_options.objects_options.walk = mark_object; + fsck_obj_options.objects_options.walk = mark_used; fsck_obj_options.error_func = fsck_error_func; if (check_strict) fsck_obj_options.strict = 1; diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 856428fef9..59eb8c0355 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -127,7 +127,7 @@ static int nr_threads; static int from_stdin; static int strict; static int do_fsck_object; -static struct fsck_options fsck_options = FSCK_OPTIONS_MISSING_GITMODULES; +static struct fsck_options fsck_options = FSCK_OBJECTS_OPTIONS_MISSING_GITMODULES; static int verbose; static const char *progress_title; static int show_resolving_progress; @@ -1746,7 +1746,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) usage(index_pack_usage); disable_replace_refs(); - fsck_options.walk = mark_link; + fsck_options.objects_options.walk = mark_link; reset_pack_idx_option(&opts); opts.flags |= WRITE_REV; diff --git a/builtin/mktag.c b/builtin/mktag.c index 4767f1a97e..c6fbeb58d4 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -15,7 +15,7 @@ static char const * const builtin_mktag_usage[] = { }; static int option_strict = 1; -static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT; +static struct fsck_options fsck_options = FSCK_OBJECTS_OPTIONS_STRICT; static int mktag_fsck_error_func(struct fsck_options *o UNUSED, const struct object_id *oid UNUSED, diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index f1c85a00ae..53cff0a91c 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -25,7 +25,7 @@ static unsigned int offset, len; static off_t consumed_bytes; static off_t max_input_size; static git_hash_ctx ctx; -static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT; +static struct fsck_options fsck_options = FSCK_OBJECTS_OPTIONS_STRICT; static struct progress *progress; /* @@ -239,7 +239,7 @@ static int check_object(struct object *obj, enum object_type type, die("Whoops! Cannot find object '%s'", oid_to_hex(&obj->oid)); if (fsck_object(obj, obj_buf->buffer, obj_buf->size, &fsck_options)) die("fsck error in packed object"); - fsck_options.walk = check_object; + fsck_options.objects_options.walk = check_object; if (fsck_walk(obj, NULL, &fsck_options)) die("Error on reachable objects of %s", oid_to_hex(&obj->oid)); write_cached_object(obj, obj_buf); diff --git a/fetch-pack.c b/fetch-pack.c index 42f48fbc31..adce10fb4c 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -46,7 +46,7 @@ static int server_supports_filtering; static int advertise_sid; static struct shallow_lock shallow_lock; static const char *alternate_shallow_file; -static struct fsck_options fsck_options = FSCK_OPTIONS_MISSING_GITMODULES; +static struct fsck_options fsck_options = FSCK_OBJECTS_OPTIONS_MISSING_GITMODULES; static struct strbuf fsck_msg_types = STRBUF_INIT; static struct string_list uri_protocols = STRING_LIST_INIT_DUP; @@ -1222,7 +1222,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args, } else alternate_shallow_file = NULL; if (get_pack(args, fd, pack_lockfiles, NULL, sought, nr_sought, - &fsck_options.gitmodules_found)) + &fsck_options.objects_options.gitmodules_found)) die(_("git fetch-pack: fetch failed.")); if (fsck_finish(&fsck_options)) die("fsck failed"); @@ -1782,7 +1782,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args, if (get_pack(args, fd, pack_lockfiles, packfile_uris.nr ? &index_pack_args : NULL, - sought, nr_sought, &fsck_options.gitmodules_found)) + sought, nr_sought, + &fsck_options.objects_options.gitmodules_found)) die(_("git fetch-pack: fetch failed.")); do_check_stateless_delimiter(args->stateless_rpc, &reader); @@ -1825,7 +1826,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args, packname[the_hash_algo->hexsz] = '\0'; - parse_gitmodules_oids(cmd.out, &fsck_options.gitmodules_found); + parse_gitmodules_oids(cmd.out, + &fsck_options.objects_options.gitmodules_found); close(cmd.out); diff --git a/fsck.c b/fsck.c index e193930ae7..e9848f2678 100644 --- a/fsck.c +++ b/fsck.c @@ -259,20 +259,20 @@ static int report(struct fsck_options *options, void fsck_enable_object_names(struct fsck_options *options) { - if (!options->object_names) - options->object_names = kh_init_oid_map(); + if (!options->objects_options.object_names) + options->objects_options.object_names = kh_init_oid_map(); } const char *fsck_get_object_name(struct fsck_options *options, const struct object_id *oid) { khiter_t pos; - if (!options->object_names) + if (!options->objects_options.object_names) return NULL; - pos = kh_get_oid_map(options->object_names, *oid); - if (pos >= kh_end(options->object_names)) + pos = kh_get_oid_map(options->objects_options.object_names, *oid); + if (pos >= kh_end(options->objects_options.object_names)) return NULL; - return kh_value(options->object_names, pos); + return kh_value(options->objects_options.object_names, pos); } void fsck_put_object_name(struct fsck_options *options, @@ -284,15 +284,16 @@ void fsck_put_object_name(struct fsck_options *options, khiter_t pos; int hashret; - if (!options->object_names) + if (!options->objects_options.object_names) return; - pos = kh_put_oid_map(options->object_names, *oid, &hashret); + pos = kh_put_oid_map(options->objects_options.object_names, + *oid, &hashret); if (!hashret) return; va_start(ap, fmt); strbuf_vaddf(&buf, fmt, ap); - kh_value(options->object_names, pos) = strbuf_detach(&buf, NULL); + kh_value(options->objects_options.object_names, pos) = strbuf_detach(&buf, NULL); va_end(ap); } @@ -342,14 +343,14 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op if (name && obj) fsck_put_object_name(options, &entry.oid, "%s%s/", name, entry.path); - result = options->walk(obj, OBJ_TREE, data, options); + result = options->objects_options.walk(obj, OBJ_TREE, data, options); } else if (S_ISREG(entry.mode) || S_ISLNK(entry.mode)) { obj = (struct object *)lookup_blob(the_repository, &entry.oid); if (name && obj) fsck_put_object_name(options, &entry.oid, "%s%s", name, entry.path); - result = options->walk(obj, OBJ_BLOB, data, options); + result = options->objects_options.walk(obj, OBJ_BLOB, data, options); } else { result = error("in tree %s: entry %s has bad mode %.6o", @@ -380,7 +381,7 @@ static int fsck_walk_commit(struct commit *commit, void *data, struct fsck_optio fsck_put_object_name(options, get_commit_tree_oid(commit), "%s:", name); - result = options->walk((struct object *) repo_get_commit_tree(the_repository, commit), + result = options->objects_options.walk((struct object *) repo_get_commit_tree(the_repository, commit), OBJ_TREE, data, options); if (result < 0) return result; @@ -423,7 +424,7 @@ static int fsck_walk_commit(struct commit *commit, void *data, struct fsck_optio else fsck_put_object_name(options, oid, "%s^", name); } - result = options->walk((struct object *)parents->item, OBJ_COMMIT, data, options); + result = options->objects_options.walk((struct object *)parents->item, OBJ_COMMIT, data, options); if (result < 0) return result; if (!res) @@ -441,7 +442,7 @@ static int fsck_walk_tag(struct tag *tag, void *data, struct fsck_options *optio return -1; if (name) fsck_put_object_name(options, &tag->tagged->oid, "%s", name); - return options->walk(tag->tagged, OBJ_ANY, data, options); + return options->objects_options.walk(tag->tagged, OBJ_ANY, data, options); } int fsck_walk(struct object *obj, void *data, struct fsck_options *options) @@ -598,6 +599,7 @@ static int fsck_tree(const struct object_id *tree_oid, unsigned o_mode; const char *o_name; struct name_stack df_dup_candidates = { NULL }; + struct fsck_objects_options *objects_options = &options->objects_options; if (init_tree_desc_gently(&desc, tree_oid, buffer, size, TREE_DESC_RAW_MODES)) { @@ -628,7 +630,7 @@ static int fsck_tree(const struct object_id *tree_oid, if (is_hfs_dotgitmodules(name) || is_ntfs_dotgitmodules(name)) { if (!S_ISLNK(mode)) - oidset_insert(&options->gitmodules_found, + oidset_insert(&objects_options->gitmodules_found, entry_oid); else retval += report(options, @@ -639,7 +641,7 @@ static int fsck_tree(const struct object_id *tree_oid, if (is_hfs_dotgitattributes(name) || is_ntfs_dotgitattributes(name)) { if (!S_ISLNK(mode)) - oidset_insert(&options->gitattributes_found, + oidset_insert(&objects_options->gitattributes_found, entry_oid); else retval += report(options, tree_oid, OBJ_TREE, @@ -666,7 +668,7 @@ static int fsck_tree(const struct object_id *tree_oid, has_dotgit |= is_ntfs_dotgit(backslash); if (is_ntfs_dotgitmodules(backslash)) { if (!S_ISLNK(mode)) - oidset_insert(&options->gitmodules_found, + oidset_insert(&objects_options->gitmodules_found, entry_oid); else retval += report(options, tree_oid, OBJ_TREE, @@ -1107,11 +1109,11 @@ static int fsck_blob(const struct object_id *oid, const char *buf, if (object_on_skiplist(options, oid)) return 0; - if (oidset_contains(&options->gitmodules_found, oid)) { + if (oidset_contains(&options->objects_options.gitmodules_found, oid)) { struct config_options config_opts = { 0 }; struct fsck_gitmodules_data data; - oidset_insert(&options->gitmodules_done, oid); + oidset_insert(&options->objects_options.gitmodules_done, oid); if (!buf) { /* @@ -1137,10 +1139,10 @@ static int fsck_blob(const struct object_id *oid, const char *buf, ret |= data.ret; } - if (oidset_contains(&options->gitattributes_found, oid)) { + if (oidset_contains(&options->objects_options.gitattributes_found, oid)) { const char *ptr; - oidset_insert(&options->gitattributes_done, oid); + oidset_insert(&options->objects_options.gitattributes_done, oid); if (!buf || size > ATTR_MAX_FILE_SIZE) { /* @@ -1255,12 +1257,15 @@ static int fsck_blobs(struct oidset *blobs_found, struct oidset *blobs_done, int fsck_finish(struct fsck_options *options) { + struct fsck_objects_options *objects_options = &options->objects_options; int ret = 0; - ret |= fsck_blobs(&options->gitmodules_found, &options->gitmodules_done, + ret |= fsck_blobs(&objects_options->gitmodules_found, + &objects_options->gitmodules_done, FSCK_MSG_GITMODULES_MISSING, FSCK_MSG_GITMODULES_BLOB, options, ".gitmodules"); - ret |= fsck_blobs(&options->gitattributes_found, &options->gitattributes_done, + ret |= fsck_blobs(&objects_options->gitattributes_found, + &objects_options->gitattributes_done, FSCK_MSG_GITATTRIBUTES_MISSING, FSCK_MSG_GITATTRIBUTES_BLOB, options, ".gitattributes"); diff --git a/fsck.h b/fsck.h index 6085a384f6..37b6f6676f 100644 --- a/fsck.h +++ b/fsck.h @@ -131,12 +131,8 @@ int fsck_error_cb_print_missing_gitmodules(struct fsck_options *o, enum fsck_msg_id msg_id, const char *message); -struct fsck_options { +struct fsck_objects_options { fsck_walk_func walk; - fsck_error error_func; - unsigned strict:1; - enum fsck_msg_type *msg_type; - struct oidset skiplist; struct oidset gitmodules_found; struct oidset gitmodules_done; struct oidset gitattributes_found; @@ -144,29 +140,43 @@ struct fsck_options { kh_oid_map_t *object_names; }; -#define FSCK_OPTIONS_DEFAULT { \ +struct fsck_options { + unsigned strict:1; + enum fsck_msg_type *msg_type; + struct oidset skiplist; + fsck_error error_func; + struct fsck_objects_options objects_options; +}; + +#define FSCK_OBJECTS_OPTIONS_DEFAULT { \ .skiplist = OIDSET_INIT, \ - .gitmodules_found = OIDSET_INIT, \ - .gitmodules_done = OIDSET_INIT, \ - .gitattributes_found = OIDSET_INIT, \ - .gitattributes_done = OIDSET_INIT, \ - .error_func = fsck_error_function \ + .error_func = fsck_error_function, \ + .objects_options = { \ + .gitmodules_found = OIDSET_INIT, \ + .gitmodules_done = OIDSET_INIT, \ + .gitattributes_found = OIDSET_INIT, \ + .gitattributes_done = OIDSET_INIT, \ + } \ } -#define FSCK_OPTIONS_STRICT { \ +#define FSCK_OBJECTS_OPTIONS_STRICT { \ .strict = 1, \ - .gitmodules_found = OIDSET_INIT, \ - .gitmodules_done = OIDSET_INIT, \ - .gitattributes_found = OIDSET_INIT, \ - .gitattributes_done = OIDSET_INIT, \ .error_func = fsck_error_function, \ + .objects_options = { \ + .gitmodules_found = OIDSET_INIT, \ + .gitmodules_done = OIDSET_INIT, \ + .gitattributes_found = OIDSET_INIT, \ + .gitattributes_done = OIDSET_INIT, \ + } \ } -#define FSCK_OPTIONS_MISSING_GITMODULES { \ +#define FSCK_OBJECTS_OPTIONS_MISSING_GITMODULES { \ .strict = 1, \ - .gitmodules_found = OIDSET_INIT, \ - .gitmodules_done = OIDSET_INIT, \ - .gitattributes_found = OIDSET_INIT, \ - .gitattributes_done = OIDSET_INIT, \ .error_func = fsck_error_cb_print_missing_gitmodules, \ + .objects_options = { \ + .gitmodules_found = OIDSET_INIT, \ + .gitmodules_done = OIDSET_INIT, \ + .gitattributes_found = OIDSET_INIT, \ + .gitattributes_done = OIDSET_INIT, \ + } \ } /* descend in all linked child objects diff --git a/object-file.c b/object-file.c index d3cf4b8b2e..4e10dd9804 100644 --- a/object-file.c +++ b/object-file.c @@ -2507,7 +2507,7 @@ static int index_mem(struct index_state *istate, } } if (flags & HASH_FORMAT_CHECK) { - struct fsck_options opts = FSCK_OPTIONS_DEFAULT; + struct fsck_options opts = FSCK_OBJECTS_OPTIONS_DEFAULT; opts.strict = 1; opts.error_func = hash_format_check_report; From patchwork Mon Jul 1 15:19:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13718303 Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1B55B16C86C for ; Mon, 1 Jul 2024 15:19:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847151; cv=none; b=VvEBIE5gV7MvWgZrqBU7Jo4rxK7HZGVCOlqDC8wlwqScwpg4gkejdl5ig0dBoGdCejuUAo3cSkGhrgESE1xRi/xhAqieW21oJG3HVFxWNKiSpYEaJ634H/y7p/25GV0qCYwQl9Nk+WKTuHahuqai7ar19wEgJd7AziKf24vdQM4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847151; c=relaxed/simple; bh=dsaTLS3fn+VIVojIl7dTSvZY6EgnBwo84f4JcqcZMm4=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=lUz/YE8jHicQqNnRM/ZyXhxJPyAuRGbGKSGfbuRSNzPVXDgM4SQZ62iLZTNWwaNQeLJi99Rz3zzxqdbmnuVF7xHba4sIaIjP1nP/2Gv4c4v7mXezTW7vNkhuM+ZVV+k+iCKmgfX1m5HfIwkDU98WupGk0VO3udnzvPyPqmBPb6M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=fWyhOxRq; arc=none smtp.client-ip=209.85.210.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fWyhOxRq" Received: by mail-pf1-f171.google.com with SMTP id d2e1a72fcca58-706683e5249so1913348b3a.2 for ; Mon, 01 Jul 2024 08:19:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719847149; x=1720451949; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=UnbI6Cvo/G3iaJXJWddJFkMbbVKogedsLKFcUq0PrK4=; b=fWyhOxRqa2AA8Gg8H0NOS0Z4NFkgcls3ACBzMexx2QilfWoBa3LU9p2MY2N7yXAguv 463eUMH4wMyH43kzUz90N5VcX3T3m6VOKdNsWSO4xqqpocMEfSZCCIjkOFhQ+oECbhsF RfjAXx5FI1prgNRBLdr+bIOvkAqZ7VNrFElst+bM/DOODBuyifLgzmZDSq6ESrvWorDa zIa04fMg5MeJZXS9ao9e29wus9UZ0Uik8eYG/qijBR6edQHKCCQfajoIw5cur7ndVXIc OXPPsvxAeM7Paglad2QRV4aG4kNmT8JDWLf09O7yQI89Lk4sAo/eWJmZBG8C5+WOhsuL Gqog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719847149; x=1720451949; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=UnbI6Cvo/G3iaJXJWddJFkMbbVKogedsLKFcUq0PrK4=; b=GNW2l45vS3AHYHQYnmxTi56b+MciMqvWRPs5pCgSSFzaLsnYeZwxobDKf3j5iPqHRL 09yz08NE1LmwBFgrMJc+YFEygS097KRGHTE/Xu44GA9nKiw0u1Wb5RtA006GIAM9lhO8 sPTf0Cd0vG15IWTkQHDL9QBKUjzX8Yr64grN1azfAKn7pTJx3JKQLNYcfA8ylM8hVVkA FoaFsCkHwPF+EexWXheqlRIY7CwLGrZGNDj14mn+OzPbkq3o5rG8h0REKVQdSXS7YEP+ xnbbPkc0HO/N3zzyFCVOBYEEPXMtgjaZ3EJrpZUkbvk1eqGxO0sb6CY0v7bTcbgJVDBJ yFAQ== X-Gm-Message-State: AOJu0YyvZ59j234bxVFxkSuFkQbYR7GkX3eqNDq7HZQYvsYwO4FA0HP0 hhF5mo/x0WXn+qPOticxL3fzlQSL2H6AhSSDCFbXY1zNn/+Gae9BXCCNCQ== X-Google-Smtp-Source: AGHT+IFDLIWNOCMlnoV1Xub7b4x/V9Fp6P3Wb60k/DEFr+lFuXU5wag+sLOrd0107iNWgHQb0QmXIQ== X-Received: by 2002:a05:6a00:218e:b0:706:5f74:b97b with SMTP id d2e1a72fcca58-70aaaf10da2mr4134991b3a.23.1719847148828; Mon, 01 Jul 2024 08:19:08 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-708024694basm6628151b3a.51.2024.07.01.08.19.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jul 2024 08:19:08 -0700 (PDT) Date: Mon, 1 Jul 2024 23:19:05 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano , Eric Sunshine Subject: [GSoC][PATCH v6 02/11] fsck: rename "skiplist" to "oid_skiplist" Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Because we introduce ref consistency check. The original "skiplist" is a common option which is set up during handling user configs. To avoid causing ambiguity, rename "skiplist" to "oid_skiplist". Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- fsck.c | 4 ++-- fsck.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fsck.c b/fsck.c index e9848f2678..04d0aa1766 100644 --- a/fsck.c +++ b/fsck.c @@ -203,7 +203,7 @@ void fsck_set_msg_types(struct fsck_options *options, const char *values) if (!strcmp(buf, "skiplist")) { if (equal == len) die("skiplist requires a path"); - oidset_parse_file(&options->skiplist, buf + equal + 1); + oidset_parse_file(&options->oid_skiplist, buf + equal + 1); buf += len + 1; continue; } @@ -220,7 +220,7 @@ void fsck_set_msg_types(struct fsck_options *options, const char *values) static int object_on_skiplist(struct fsck_options *opts, const struct object_id *oid) { - return opts && oid && oidset_contains(&opts->skiplist, oid); + return opts && oid && oidset_contains(&opts->oid_skiplist, oid); } __attribute__((format (printf, 5, 6))) diff --git a/fsck.h b/fsck.h index 37b6f6676f..0c581ef082 100644 --- a/fsck.h +++ b/fsck.h @@ -143,13 +143,13 @@ struct fsck_objects_options { struct fsck_options { unsigned strict:1; enum fsck_msg_type *msg_type; - struct oidset skiplist; + struct oidset oid_skiplist; fsck_error error_func; struct fsck_objects_options objects_options; }; #define FSCK_OBJECTS_OPTIONS_DEFAULT { \ - .skiplist = OIDSET_INIT, \ + .oid_skiplist = OIDSET_INIT, \ .error_func = fsck_error_function, \ .objects_options = { \ .gitmodules_found = OIDSET_INIT, \ From patchwork Mon Jul 1 15:19:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13718304 Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B92F16D4D4 for ; Mon, 1 Jul 2024 15:19:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847172; cv=none; b=LVpTDPUbGIwJEBaGSMIdKjWYInnZQ6r3/EyTrjDWkVWSA1EiqRi2ps3cYW26uoTeWsAvMdwhhFyAbI9XWsH80qlOMwbD3xd9oP+4DSpkG9NMaabtyFO4v0O1b2QgF0k00glFU4xpiEMvBhZ9gCHPju1nuufGFxfpl+td5y7emoc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847172; c=relaxed/simple; bh=LyT/a3fNobFZ/qBtr1Ep/9gNuj8Pn3GRv5NlobbiPBc=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=tGBeDQpQobdipBvxRDU9gmm+yd3LxGJ8DGgfqL4olW/byu+dHxttnEheelsiUGIZFLrMRubcFjWFT6EH5hwWLXkfPQJ+WDepLPVdERsKhC434krC9Q4/x3MZDx9B5ca9f1lcn0eqRHVCnSHQdHcli+RS76ySr/np5k/RFT6GVb0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=d2HW6pHn; arc=none smtp.client-ip=209.85.214.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="d2HW6pHn" Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-1fa75f53f42so14193835ad.0 for ; Mon, 01 Jul 2024 08:19:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719847170; x=1720451970; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=yTnAk1FJCenoFnbILdZkpFlp775NAM+IjbM/MigQhes=; b=d2HW6pHngdUOaiq0wOIOh0Z2iJs8jpRczTY/+tTWGNLMv5iomYjPgkdrcTKy4e+q++ mKc6E2RNGBrRPjc0dfjQ1ku19roNNynl5IHFhyC/+SuPaHxWgtFt+q4VF3q6lMvrWcln v4NkHPLREZOaXXVMCyHzT1BhAXdgtw9WTnA2MB/OqF3+eSt43eSMccZarVFph4LB4lCH aEpuxaLisExRU4ThROtq6uMWgmXDBhP96VPc71TNxmV8jII3MCOkV96aD1ykS2nSALHZ 3FgNwSiHYtmO/jt/DQlfoT6vjL5wyC984hG5Fw+IvBEfUcYUhq7Bw94gYgpv0osEWcGx GpmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719847170; x=1720451970; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=yTnAk1FJCenoFnbILdZkpFlp775NAM+IjbM/MigQhes=; b=i2pS0mAwuyixXwkInigXRFtRWb35W98M3qcv58Wb2FLxfIHGsSZgRBI2gAQfKWTdjX 2zGzvZyHSAB4r9q3y49AMMc9cS6nSQmAh4i1z9E7LTdYy4e0axhbJOoYk72vpb+u5XSt VGOZHUfaJj2DPEhZPtOTtDlnfkE97zaFuW/ctJvJy/IGAcTmTZH0O6Excw+SaT5Rsq7A 0f7zqtQZP5IcuAB170BVG0HcTZH+B4+eTpzTxxpo9zrBZ9wruvVh5+8tEE6WsJJ8QK/j gnaEZXHqCOdHzOPjBTVIKnN/hKgrdMl8B3qO8kKew+3YHbDkZDwYQUCdOP4r4hapGAXR 9x4Q== X-Gm-Message-State: AOJu0YzdiTYjwkKpxLsVLYOi8wziyArtKsnkW+4Rpnyl9Tie26OP5MdC rBYuqoP7wJYRB61+xUwepoj3RFO7I8QM2OI7La1j5jqOwCZRElKiUDsN9g== X-Google-Smtp-Source: AGHT+IE8R5h+DMqXX4+Z891cNcN3ANrmqkF41kIzqPIiT9w71B/4oK4+OrlS7H9oPmUtceAlOCJQ5w== X-Received: by 2002:a17:903:22c6:b0:1f8:36f1:ac5a with SMTP id d9443c01a7336-1fadbce7b72mr38931415ad.44.1719847170102; Mon, 01 Jul 2024 08:19:30 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fac155c382sm66321885ad.189.2024.07.01.08.19.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jul 2024 08:19:29 -0700 (PDT) Date: Mon, 1 Jul 2024 23:19:26 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano , Eric Sunshine Subject: [GSoC][PATCH v6 03/11] fsck: add "fsck_refs_options" into "fsck_options" Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Introduce "fsck_refs_options" to represent the refs-related options. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- fsck.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fsck.h b/fsck.h index 0c581ef082..ff7281b410 100644 --- a/fsck.h +++ b/fsck.h @@ -131,6 +131,10 @@ int fsck_error_cb_print_missing_gitmodules(struct fsck_options *o, enum fsck_msg_id msg_id, const char *message); +struct fsck_refs_options { + unsigned verbose:1; +}; + struct fsck_objects_options { fsck_walk_func walk; struct oidset gitmodules_found; @@ -146,6 +150,7 @@ struct fsck_options { struct oidset oid_skiplist; fsck_error error_func; struct fsck_objects_options objects_options; + struct fsck_refs_options refs_options; }; #define FSCK_OBJECTS_OPTIONS_DEFAULT { \ From patchwork Mon Jul 1 15:19:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13718305 Received: from mail-pg1-f169.google.com (mail-pg1-f169.google.com [209.85.215.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5198C16CD1A for ; Mon, 1 Jul 2024 15:19:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847190; cv=none; b=fLaShz0xO57eyrEro2C9dNoPjXnpzxrNFTHBgJx6o57lzgHrg2i4Q97mT1RBk36zfxazPkJJKGD0WB9vV8iCmQyV06uY5SQKM1aWP7jLiTO3L7OWgylV94Xn0P+pR1Vs0ZE4jYkb32oEvIiU1Py56Vp10e4AKo8G0y+kIS7MbXQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847190; c=relaxed/simple; bh=BC4WA+tPwl9oS1bBchJ2+WRcWp9izVr2vtdCx4yUBiI=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=AHfAj4SqlZuLBdnPv0JALRr9Ci+m11AJWFLlEdE3qpP++VSaErL/my6e07Iw4/T1iaEpxHWlQ4y2d3M0CDKiWIz5rIFPPo5UFQClBSmiiz4t65cFbehJEqdAZfpMOU3KudtSnj1ozkl8Rd0hCynoxpKxlc5BN7Mgfll7h4KmwXY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=TPmBsPqs; arc=none smtp.client-ip=209.85.215.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="TPmBsPqs" Received: by mail-pg1-f169.google.com with SMTP id 41be03b00d2f7-710437d0affso1663071a12.3 for ; Mon, 01 Jul 2024 08:19:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719847187; x=1720451987; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=MIjXo17y2I60tynB0XPFRXKG2SwN0ybS3ex43NXPyQQ=; b=TPmBsPqsRlp9gmG8lreTAY1glEeuy/D8tX8/0gBZKjyZBN8P2A9tSPSRA6EUEnaB2y f02/p82TIFOogAzqg2OP7eysD+36VLok64GPZvAglNe3P+BC6lnOvGA40AYxWJVTd7IG Wzd5j8lo21wJUwWLhSWrSusG9F1RgFYQnxZ71vwoZ2aP8rVIkEnW/8T+Rq0KR8MRgwva u9ptVl4aad764y2r4C+0uzvPj7RFqWtcychgM6ASuOYnIipVPXYh3nFmYV+AUfuAkDPc IkMOBd7bm552PxPA7CWIi4SFpf1DGDeTtWdCQwg/cMpLFSJqx1XowCJsV9xC1z0E7K2h RGYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719847187; x=1720451987; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=MIjXo17y2I60tynB0XPFRXKG2SwN0ybS3ex43NXPyQQ=; b=rD1Hka57SSfi0okJsYAh9k/1sxzMEKpsUZ3/yYDrNaPqqV7zdGGVe02buXB7zk58Mu /cayj/JxLspSAyUTKP2wVaoU9jQCl9S4RfLACSapzmeZzHrQz3xyRXRbNiKf1TTdLjVi zcVZTgvToVH0UNIfTA5gHoZLbq5bse3j9MZmIkDseOQ0Qem+YLmfBiknxGJ8FhUa+6qc jsCDraxwYqLfaG7Hx7W0jS9WEJUzZp4p0Rzf0f7sz/6X5i7qLrku8r1pbCG2Gar4Nn39 KTpv+ckt9265gNRSrBCfoj4b6extFmWlZZZMMcWEoxOKPIKx/3OPE5uMf1eEAW5jZeDM EW+w== X-Gm-Message-State: AOJu0Yxi8LywMI0Nt8xVQ6vjVB/XAuAvNUuTPeOsJcaXwsENgKMEnugH ALmNTYUxeqYl/XiJiPrEUSa0/iqIaVaGimhu6baig6DN+VFJDD1TmY6zvw== X-Google-Smtp-Source: AGHT+IFdjtSiACX3puVY4tO84RDdIjdvKthBup+cV7mVc327w4ZS77Eoy+PXStrZ8xeiWVMK1+mhbA== X-Received: by 2002:a05:6a21:999e:b0:1be:c42f:be42 with SMTP id adf61e73a8af0-1bef61019f4mr5917217637.19.1719847185412; Mon, 01 Jul 2024 08:19:45 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fac1538e49sm66118855ad.145.2024.07.01.08.19.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jul 2024 08:19:44 -0700 (PDT) Date: Mon, 1 Jul 2024 23:19:42 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano , Eric Sunshine Subject: [GSoC][PATCH v6 04/11] fsck: add a unified interface for reporting fsck messages Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The static function "report" provided by "fsck.c" aims at reporting the problems related to object database which cannot be reused for refs. In order to provide a unified interface which can report either objects or refs, create a new function "vfsck_report" by adding "checked_ref_name" parameter following the "report" prototype. However, instead of using "...", provide "va_list" to allow more flexibility. The "vfsck_report" function will use "error_func" registered in "fsck_options" function to report customized messages. Change "error_func" prototype to align with the "vfsck_report". Change "report" function to make it use "vfsck_report" to report objects-related messages. Add a new function called "fsck_refs_report" to use "vfsck_report" to report refs-related messages. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- builtin/fsck.c | 15 ++++----- builtin/mktag.c | 1 + fsck.c | 81 ++++++++++++++++++++++++++++++++++++------------- fsck.h | 40 +++++++++++++++--------- object-file.c | 11 ++++--- 5 files changed, 101 insertions(+), 47 deletions(-) diff --git a/builtin/fsck.c b/builtin/fsck.c index 13b64f723f..cdf2218dfd 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -89,12 +89,13 @@ static int objerror(struct object *obj, const char *err) return -1; } -static int fsck_error_func(struct fsck_options *o UNUSED, - const struct object_id *oid, - enum object_type object_type, - enum fsck_msg_type msg_type, - enum fsck_msg_id msg_id UNUSED, - const char *message) +static int fsck_objects_error_func(struct fsck_options *o UNUSED, + const struct object_id *oid, + enum object_type object_type, + const char *checked_ref_name UNUSED, + enum fsck_msg_type msg_type, + enum fsck_msg_id msg_id UNUSED, + const char *message) { switch (msg_type) { case FSCK_WARN: @@ -938,7 +939,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) fsck_walk_options.objects_options.walk = mark_object; fsck_obj_options.objects_options.walk = mark_used; - fsck_obj_options.error_func = fsck_error_func; + fsck_obj_options.error_func = fsck_objects_error_func; if (check_strict) fsck_obj_options.strict = 1; diff --git a/builtin/mktag.c b/builtin/mktag.c index c6fbeb58d4..d8e4b91134 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -20,6 +20,7 @@ static struct fsck_options fsck_options = FSCK_OBJECTS_OPTIONS_STRICT; static int mktag_fsck_error_func(struct fsck_options *o UNUSED, const struct object_id *oid UNUSED, enum object_type object_type UNUSED, + const char *checked_ref_name UNUSED, enum fsck_msg_type msg_type, enum fsck_msg_id msg_id UNUSED, const char *message) diff --git a/fsck.c b/fsck.c index 04d0aa1766..31ae8d57ce 100644 --- a/fsck.c +++ b/fsck.c @@ -223,12 +223,18 @@ static int object_on_skiplist(struct fsck_options *opts, return opts && oid && oidset_contains(&opts->oid_skiplist, oid); } -__attribute__((format (printf, 5, 6))) -static int report(struct fsck_options *options, - const struct object_id *oid, enum object_type object_type, - enum fsck_msg_id msg_id, const char *fmt, ...) +/* + * Provide a unified interface for either fscking refs or objects. + * It will get the current msg error type and call the error_func callback + * which is registered in the "fsck_options" struct. + */ +static int vfsck_report(struct fsck_options *options, + const struct object_id *oid, + enum object_type object_type, + const char *checked_ref_name, + enum fsck_msg_id msg_id, const char *fmt, va_list ap) { - va_list ap; + va_list ap_copy; struct strbuf sb = STRBUF_INIT; enum fsck_msg_type msg_type = fsck_msg_type(msg_id, options); int result; @@ -247,9 +253,9 @@ static int report(struct fsck_options *options, prepare_msg_ids(); strbuf_addf(&sb, "%s: ", msg_id_info[msg_id].camelcased); - va_start(ap, fmt); - strbuf_vaddf(&sb, fmt, ap); - result = options->error_func(options, oid, object_type, + va_copy(ap_copy, ap); + strbuf_vaddf(&sb, fmt, ap_copy); + result = options->error_func(options, oid, object_type, checked_ref_name, msg_type, msg_id, sb.buf); strbuf_release(&sb); va_end(ap); @@ -257,6 +263,36 @@ static int report(struct fsck_options *options, return result; } +__attribute__((format (printf, 5, 6))) +static int report(struct fsck_options *options, + const struct object_id *oid, enum object_type object_type, + enum fsck_msg_id msg_id, const char *fmt, ...) +{ + va_list ap; + int result; + va_start(ap, fmt); + result = vfsck_report(options, oid, object_type, NULL, + msg_id, fmt, ap); + va_end(ap); + return result; +} + + + +int fsck_refs_report(struct fsck_options *options, + const struct object_id *oid, + const char *checked_ref_name, + enum fsck_msg_id msg_id, const char *fmt, ...) +{ + va_list ap; + int result; + va_start(ap, fmt); + result = vfsck_report(options, oid, OBJ_NONE, + checked_ref_name, msg_id, fmt, ap); + va_end(ap); + return result; +} + void fsck_enable_object_names(struct fsck_options *options) { if (!options->objects_options.object_names) @@ -1199,12 +1235,13 @@ int fsck_buffer(const struct object_id *oid, enum object_type type, type); } -int fsck_error_function(struct fsck_options *o, - const struct object_id *oid, - enum object_type object_type UNUSED, - enum fsck_msg_type msg_type, - enum fsck_msg_id msg_id UNUSED, - const char *message) +int fsck_objects_error_function(struct fsck_options *o, + const struct object_id *oid, + enum object_type object_type UNUSED, + const char *checked_ref_name UNUSED, + enum fsck_msg_type msg_type, + enum fsck_msg_id msg_id UNUSED, + const char *message) { if (msg_type == FSCK_WARN) { warning("object %s: %s", fsck_describe_object(o, oid), message); @@ -1305,16 +1342,18 @@ int git_fsck_config(const char *var, const char *value, * Custom error callbacks that are used in more than one place. */ -int fsck_error_cb_print_missing_gitmodules(struct fsck_options *o, - const struct object_id *oid, - enum object_type object_type, - enum fsck_msg_type msg_type, - enum fsck_msg_id msg_id, - const char *message) +int fsck_objects_error_cb_print_missing_gitmodules(struct fsck_options *o, + const struct object_id *oid, + enum object_type object_type, + const char *checked_ref_name, + enum fsck_msg_type msg_type, + enum fsck_msg_id msg_id, + const char *message) { if (msg_id == FSCK_MSG_GITMODULES_MISSING) { puts(oid_to_hex(oid)); return 0; } - return fsck_error_function(o, oid, object_type, msg_type, msg_id, message); + return fsck_objects_error_function(o, oid, object_type, checked_ref_name, + msg_type, msg_id, message); } diff --git a/fsck.h b/fsck.h index ff7281b410..e611b3b65b 100644 --- a/fsck.h +++ b/fsck.h @@ -114,22 +114,27 @@ int is_valid_msg_type(const char *msg_id, const char *msg_type); typedef int (*fsck_walk_func)(struct object *obj, enum object_type object_type, void *data, struct fsck_options *options); -/* callback for fsck_object, type is FSCK_ERROR or FSCK_WARN */ +/* + * callback function for reporting errors when checking either objects or refs + */ typedef int (*fsck_error)(struct fsck_options *o, const struct object_id *oid, enum object_type object_type, + const char *checked_ref_name, enum fsck_msg_type msg_type, enum fsck_msg_id msg_id, const char *message); -int fsck_error_function(struct fsck_options *o, - const struct object_id *oid, enum object_type object_type, - enum fsck_msg_type msg_type, enum fsck_msg_id msg_id, - const char *message); -int fsck_error_cb_print_missing_gitmodules(struct fsck_options *o, - const struct object_id *oid, - enum object_type object_type, - enum fsck_msg_type msg_type, - enum fsck_msg_id msg_id, - const char *message); +int fsck_objects_error_function(struct fsck_options *o, + const struct object_id *oid, enum object_type object_type, + const char *checked_ref_name, + enum fsck_msg_type msg_type, enum fsck_msg_id msg_id, + const char *message); +int fsck_objects_error_cb_print_missing_gitmodules(struct fsck_options *o, + const struct object_id *oid, + enum object_type object_type, + const char *checked_ref_name, + enum fsck_msg_type msg_type, + enum fsck_msg_id msg_id, + const char *message); struct fsck_refs_options { unsigned verbose:1; @@ -155,7 +160,7 @@ struct fsck_options { #define FSCK_OBJECTS_OPTIONS_DEFAULT { \ .oid_skiplist = OIDSET_INIT, \ - .error_func = fsck_error_function, \ + .error_func = fsck_objects_error_function, \ .objects_options = { \ .gitmodules_found = OIDSET_INIT, \ .gitmodules_done = OIDSET_INIT, \ @@ -165,7 +170,7 @@ struct fsck_options { } #define FSCK_OBJECTS_OPTIONS_STRICT { \ .strict = 1, \ - .error_func = fsck_error_function, \ + .error_func = fsck_objects_error_function, \ .objects_options = { \ .gitmodules_found = OIDSET_INIT, \ .gitmodules_done = OIDSET_INIT, \ @@ -175,7 +180,7 @@ struct fsck_options { } #define FSCK_OBJECTS_OPTIONS_MISSING_GITMODULES { \ .strict = 1, \ - .error_func = fsck_error_cb_print_missing_gitmodules, \ + .error_func = fsck_objects_error_cb_print_missing_gitmodules, \ .objects_options = { \ .gitmodules_found = OIDSET_INIT, \ .gitmodules_done = OIDSET_INIT, \ @@ -224,6 +229,13 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer, */ int fsck_finish(struct fsck_options *options); +__attribute__((format (printf, 5, 6))) +int fsck_refs_report(struct fsck_options *options, + const struct object_id *oid, + const char *checked_ref_name, + enum fsck_msg_id msg_id, + const char *fmt, ...); + /* * Subsystem for storing human-readable names for each object. * diff --git a/object-file.c b/object-file.c index 4e10dd9804..a681087625 100644 --- a/object-file.c +++ b/object-file.c @@ -2473,11 +2473,12 @@ int repo_has_object_file(struct repository *r, * give more context. */ static int hash_format_check_report(struct fsck_options *opts UNUSED, - const struct object_id *oid UNUSED, - enum object_type object_type UNUSED, - enum fsck_msg_type msg_type UNUSED, - enum fsck_msg_id msg_id UNUSED, - const char *message) + const struct object_id *oid UNUSED, + enum object_type object_type UNUSED, + const char *ref_checked_name UNUSED, + enum fsck_msg_type msg_type UNUSED, + enum fsck_msg_id msg_id UNUSED, + const char *message) { error(_("object fails fsck: %s"), message); return 1; From patchwork Mon Jul 1 15:19:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13718306 Received: from mail-pg1-f171.google.com (mail-pg1-f171.google.com [209.85.215.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 70E5E15EFB6 for ; Mon, 1 Jul 2024 15:20:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847205; cv=none; b=JuBNrMqf3WJOi0WS6xe6fmnmv48fRvX1+M066ufjOu/Uzsn/bBCkTOClqrRNEHzQlW8ORXPsBo6iLnS06DqA8lqLSAu2pLUxUgkSVH3Pzd/LfU3d4hGeAXoI73J1BqHOKquPXKjKudPOq3cJyw3P3DvYXriuuJ0vEqksDc854LU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847205; c=relaxed/simple; bh=gOOYUXUXMC/TJqZqn98LPak7tNYuDPhFNAt56MaQdJc=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=oJO0IDt7dWuiTQm18PAxf6U4cVtYtWIo7YX8R05Pm6FqQEpGuAfhdE7AkT7BuAcRaCRv1+4gLEm3VW99G4CytHiuxLO4fq0z3sKJdB72arGRRBy92gJ6ozmjH+AzzhYD4l6ST0zH3SevPFaHhkqoubR6T92aQtnD1bORP0QXvu0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=UEcM4WoL; arc=none smtp.client-ip=209.85.215.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UEcM4WoL" Received: by mail-pg1-f171.google.com with SMTP id 41be03b00d2f7-7201cb6cae1so1515003a12.2 for ; Mon, 01 Jul 2024 08:20:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719847203; x=1720452003; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=Q/iWgs0hBMPDgOBUfW+8UyV5H1//6gIpwQ6qwzn9IC4=; b=UEcM4WoLa+aJl/dC1uG6p+4qTvnpU7TQvWDmLnt+eRz2YXXCbpfn+eO4TjP2xgBhDv v4eT/BN0rVH36aLBDHbgWerNbPKjg0pV3gZWAgngvtNhBfNGhsn3IHVrzU+l7/dtDDNh ODc7M1DG8jK7k/z3uHPxjK8JSrJKHbnkkeOkbvXajiIBwqgJmN5NxOvXva8qZrJJeqFf 9Ys5ZgeACKJjy+55uS70CkpXZx6EklitkcI4MQzUiJC5hV4lLGWcmVxOQOBTyBHGxvVI A9ncftfhuBaeTNqEHBcz0PASnuA1GQJKWeD/TPpXYKj7lJDFLwvXb2f7UyLZq9NlbE9d WRgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719847203; x=1720452003; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Q/iWgs0hBMPDgOBUfW+8UyV5H1//6gIpwQ6qwzn9IC4=; b=X3apYsY7uZ+GQsJmSbY23kP83cqSoUvzt/3g8iMPFBQ0L6r1Kz7c6yMdy0xQZQdXfv aIJ3zUzbYKwgOSfX0PSZp21rLN6MrRQ972yPgB+QEO1+VV9clnbxVVTK3M2q5mNM3zMs Mxt3X/H3lWilEYr3DHxWWQsC/ryVs4qaKhzViK/LWbMY/Z07dB9zsmBvUH8vQHL4b70P K6h/NYYBLKyH9BWH4woI9207W/16kacJz5Y+iq/5z3Z+NSjpbipBe9hlRF4DRKEbjoWT 4JqLPGPXhwtvupQ6WlL5mC8vcI3bgRyjyz/HciW1m/FQzx5ELG2iKNJrvtO043IQWG2h cjhQ== X-Gm-Message-State: AOJu0Yyt6MFmQtQrUkC9A8sVSBxJEuBThwhX8SH7RwpoS0mmm0pA3oFo sfWW5/7ayii7+Ue9rw8v0m6zkWPLlXcqP0EI7mnUGIap/jE0fA2XuT8iwg== X-Google-Smtp-Source: AGHT+IGG5W0/syRA6ZbbjmKSOk6s4J759Mx9mMwOGDL/WrmcFyhmdqPEZvYDL27CN977TZKRSTSgSg== X-Received: by 2002:a05:6a20:a106:b0:1bd:2a6f:511b with SMTP id adf61e73a8af0-1bef613f40fmr5747078637.20.1719847203063; Mon, 01 Jul 2024 08:20:03 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fac10c8d83sm66175375ad.16.2024.07.01.08.20.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jul 2024 08:20:02 -0700 (PDT) Date: Mon, 1 Jul 2024 23:19:59 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano , Eric Sunshine Subject: [GSoC][PATCH v6 05/11] fsck: add "fsck_refs_options" initialization macros Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Add "FSCK_REFS_OPTIONS_DEFAULT" and "FSCK_REFS_OPTIONS_STRICT" macros to create the refs options easily. Add refs-specific "error_func" callback "fsck_refs_error_function". "fsck_refs_error_function" will use the "oid" parameter. When the caller passed the oid, it will use "oid_to_hex" to get the corresponding hex value to report to the user. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- fsck.c | 22 ++++++++++++++++++++++ fsck.h | 14 ++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/fsck.c b/fsck.c index 31ae8d57ce..ea00fb4790 100644 --- a/fsck.c +++ b/fsck.c @@ -1251,6 +1251,28 @@ int fsck_objects_error_function(struct fsck_options *o, return 1; } +int fsck_refs_error_function(struct fsck_options *options UNUSED, + const struct object_id *oid, + enum object_type object_type UNUSED, + const char *checked_ref_name, + enum fsck_msg_type msg_type, + enum fsck_msg_id msg_id UNUSED, + const char *message) +{ + static struct strbuf sb = STRBUF_INIT; + + strbuf_addstr(&sb, checked_ref_name); + if (oid) + strbuf_addf(&sb, " -> (%s)", oid_to_hex(oid)); + + if (msg_type == FSCK_WARN) { + warning("%s: %s", sb.buf, message); + return 0; + } + error("%s: %s", sb.buf, message); + return 1; +} + 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 e611b3b65b..887fe2969f 100644 --- a/fsck.h +++ b/fsck.h @@ -135,6 +135,13 @@ int fsck_objects_error_cb_print_missing_gitmodules(struct fsck_options *o, enum fsck_msg_type msg_type, enum fsck_msg_id msg_id, const char *message); +int fsck_refs_error_function(struct fsck_options *options, + const struct object_id *oid, + enum object_type object_type, + const char *checked_ref_name, + enum fsck_msg_type msg_type, + enum fsck_msg_id msg_id, + const char *message); struct fsck_refs_options { unsigned verbose:1; @@ -188,6 +195,13 @@ struct fsck_options { .gitattributes_done = OIDSET_INIT, \ } \ } +#define FSCK_REFS_OPTIONS_DEFAULT { \ + .error_func = fsck_refs_error_function, \ +} +#define FSCK_REFS_OPTIONS_STRICT { \ + .strict = 1, \ + .error_func = fsck_refs_error_function, \ +} /* descend in all linked child objects * the return value is: From patchwork Mon Jul 1 15:20:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13718307 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A2E3016132E for ; Mon, 1 Jul 2024 15:20:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847233; cv=none; b=rCA4PUD2jFqXuRRmUhV9eTDOJADBYg0oJSG1ve/NqZmDMHYnY1WzbacoErCvmmhOEJfrMeAhSY86RYkJOkaKALzYqOqOJEZ9HkKVXhNrYsxneKmuvqhxouHoMBBdQJRHmdsytG6u7+nKK4MuKXW0XmZSkVt6O64XjwucpL5Zygs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847233; c=relaxed/simple; bh=q1jCNftq4YTPKr5sLAfTsKnpyXKs0d3GZMiEyFdxMSQ=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=EFRZ0GRgsFnC2zi7KvSxuQHaWsStux1wvJvU+Ley9HFqm538rwY+UzQtl4aRkzoh1iilUD51nppD3F3VIq4ysY/AEWJGBbvSu70yaWrmEJMrZk3Wnw4luLbo8V6B5ZSkUC6dDd/5NEQvCeHKOM5+nrsJR8tiVqCLCXp3bVOdqxc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BNqTQpJf; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BNqTQpJf" Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-1f9a78c6c5dso17253255ad.1 for ; Mon, 01 Jul 2024 08:20:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719847229; x=1720452029; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=6pVT582GTNgvgnQMaIjHrnyoLGIiXPzJZByiO0e5MAk=; b=BNqTQpJfPriiXBfeJivVq/QhheRowiNcjygHYFX5pmSAKvgyu/myIubXecfOYhY8kL Cdl5UXWUD2t3MFpQdd9RD91zyluGh7DpCGc/fRPsii0aZaNQd6p5HquBVWRfg6pT+v0z /RfXTI6ZUIPQqdgv564wYq+Q7GO0SYznLYqNISU96YuFdfWVTvtdhb+RRuCBDz4q2DcM rTHbTeAjDy7ihi+loSu1JIvEr15lXwhyTnaG7i7OBOvp9LOz07ixhSXpnNej/gmUYbJP DnUhcx6TE8ZtdkDnb904n5oWSmhrLuX+Z7lgLC1cMd8WogCKFfvrm9QNLqhofduMXZEo pU/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719847229; x=1720452029; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=6pVT582GTNgvgnQMaIjHrnyoLGIiXPzJZByiO0e5MAk=; b=H6QrzrnxzDb+kIUlAxG4fzGcWALpLIudZ5UuLFRy9g+pQPu9j58objR7nl+Bxd5Tk1 67uLuzT/q6WbMuMadnFWMEOAa4mM2e8qyeidgC3DH5ctbtPTdSQ12cX15O/gHmE6W73p fZfPmrkZ2bFZfhInndfyvy9WUKMQ62pGL2MVh7AYEW1VLoZsCfX3z/Nmff7o8+funq7A XijRY5uKjfH/9fHvam+18KvkN9pwx5OxYvsHujZdg5ulBpk0pdtTbWqSNBb2DCn/wSDD ecvYJliPYr1gMKHEojmzN7/tCbGtAEDjQ5wzy31Qt4wKmya77usEQt1tgC1ZAxVp14Ow 6JFw== X-Gm-Message-State: AOJu0Yz7f3lz2aZX9TBwtuaEKcHr8Q6gXSuAGXJsBWecWEgd6ZuNghSq xTAg1+9fXh2ec8kdXfObYfuuPamKYp4uybuYpItd9mVChQZbNo6dtWnxvA== X-Google-Smtp-Source: AGHT+IH+qqnc8e68kdNguzQp1S7y4QMTZLuzfsSymdpVpZ13D7qXA0px3FPZid6BX7hCMDB5VOWRuw== X-Received: by 2002:a17:902:e885:b0:1fa:8f64:8afd with SMTP id d9443c01a7336-1fadbc73cadmr34787495ad.11.1719847229501; Mon, 01 Jul 2024 08:20:29 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fac1535b6esm65789155ad.156.2024.07.01.08.20.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jul 2024 08:20:29 -0700 (PDT) Date: Mon, 1 Jul 2024 23:20:26 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano , Eric Sunshine Subject: [GSoC][PATCH v6 06/11] refs: set up ref consistency check infrastructure Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The interfaces defined in the `ref_storage_be` are carefully structured in semantic. It's organized as the five parts: 1. The name and the initialization interfaces. 2. The ref transaction interfaces. 3. The ref internal interfaces (pack, rename and copy). 4. The ref filesystem interfaces. 5. The reflog related interfaces. To keep consistent with the git-fsck(1), add a new interface named "fsck_refs_fn" to the end of "ref_storage_be". This semantic cannot be grouped into any above five categories. Explicitly add blank line to make it different from others. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- refs.c | 5 +++++ refs.h | 8 ++++++++ refs/debug.c | 11 +++++++++++ refs/files-backend.c | 15 ++++++++++++++- refs/packed-backend.c | 8 ++++++++ refs/refs-internal.h | 6 ++++++ refs/reftable-backend.c | 8 ++++++++ 7 files changed, 60 insertions(+), 1 deletion(-) diff --git a/refs.c b/refs.c index dd0d9c360f..5f17de38e2 100644 --- a/refs.c +++ b/refs.c @@ -316,6 +316,11 @@ int check_refname_format(const char *refname, int flags) return check_or_sanitize_refname(refname, flags, NULL); } +int refs_fsck(struct ref_store *refs, struct fsck_options *o) +{ + return refs->be->fsck(refs, o); +} + void sanitize_refname_component(const char *refname, struct strbuf *out) { if (check_or_sanitize_refname(refname, REFNAME_ALLOW_ONELEVEL, out)) diff --git a/refs.h b/refs.h index df8cbf6124..946e929af9 100644 --- a/refs.h +++ b/refs.h @@ -3,6 +3,7 @@ #include "commit.h" +struct fsck_options; struct object_id; struct ref_store; struct repository; @@ -547,6 +548,13 @@ int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_dat */ int check_refname_format(const char *refname, int flags); +/* + * Check the reference database for consistency. Return 0 if refs and + * reflogs are consistent, and non-zero otherwise. The errors will be + * written to stderr. + */ +int refs_fsck(struct ref_store *refs, struct fsck_options *o); + /* * Apply the rules from check_refname_format, but mutate the result until it * is acceptable, and place the result in "out". diff --git a/refs/debug.c b/refs/debug.c index 547d9245b9..45e2e784a0 100644 --- a/refs/debug.c +++ b/refs/debug.c @@ -419,6 +419,15 @@ static int debug_reflog_expire(struct ref_store *ref_store, const char *refname, return res; } +static int debug_fsck(struct ref_store *ref_store, + struct fsck_options *o) +{ + struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store; + int res = drefs->refs->be->fsck(drefs->refs, o); + trace_printf_key(&trace_refs, "fsck: %d\n", res); + return res; +} + struct ref_storage_be refs_be_debug = { .name = "debug", .init = NULL, @@ -451,4 +460,6 @@ struct ref_storage_be refs_be_debug = { .create_reflog = debug_create_reflog, .delete_reflog = debug_delete_reflog, .reflog_expire = debug_reflog_expire, + + .fsck = debug_fsck, }; diff --git a/refs/files-backend.c b/refs/files-backend.c index 44c5c3b201..817813e723 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3406,6 +3406,17 @@ static int files_ref_store_remove_on_disk(struct ref_store *ref_store, return ret; } +static int files_fsck(struct ref_store *ref_store, + struct fsck_options *o) +{ + int ret; + struct files_ref_store *refs = + files_downcast(ref_store, REF_STORE_READ, "fsck"); + + ret = refs->packed_ref_store->be->fsck(refs->packed_ref_store, o); + return ret; +} + struct ref_storage_be refs_be_files = { .name = "files", .init = files_ref_store_init, @@ -3432,5 +3443,7 @@ struct ref_storage_be refs_be_files = { .reflog_exists = files_reflog_exists, .create_reflog = files_create_reflog, .delete_reflog = files_delete_reflog, - .reflog_expire = files_reflog_expire + .reflog_expire = files_reflog_expire, + + .fsck = files_fsck, }; diff --git a/refs/packed-backend.c b/refs/packed-backend.c index c4c1e36aa2..ad3e8fb1d1 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -1733,6 +1733,12 @@ static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_s return empty_ref_iterator_begin(); } +static int packed_fsck(struct ref_store *ref_store, + struct fsck_options *o) +{ + return 0; +} + struct ref_storage_be refs_be_packed = { .name = "packed", .init = packed_ref_store_init, @@ -1760,4 +1766,6 @@ struct ref_storage_be refs_be_packed = { .create_reflog = NULL, .delete_reflog = NULL, .reflog_expire = NULL, + + .fsck = packed_fsck, }; diff --git a/refs/refs-internal.h b/refs/refs-internal.h index fa975d69aa..a905e187cd 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -4,6 +4,7 @@ #include "refs.h" #include "iterator.h" +struct fsck_options; struct ref_transaction; /* @@ -650,6 +651,9 @@ typedef int read_raw_ref_fn(struct ref_store *ref_store, const char *refname, typedef int read_symbolic_ref_fn(struct ref_store *ref_store, const char *refname, struct strbuf *referent); +typedef int fsck_fn(struct ref_store *ref_store, + struct fsck_options *o); + struct ref_storage_be { const char *name; ref_store_init_fn *init; @@ -677,6 +681,8 @@ struct ref_storage_be { create_reflog_fn *create_reflog; delete_reflog_fn *delete_reflog; reflog_expire_fn *reflog_expire; + + fsck_fn *fsck; }; extern struct ref_storage_be refs_be_files; diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 7d872a32ac..7f07de8d45 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -2292,6 +2292,12 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, return ret; } +static int reftable_be_fsck(struct ref_store *ref_store, + struct fsck_options *o) +{ + return 0; +} + struct ref_storage_be refs_be_reftable = { .name = "reftable", .init = reftable_be_init, @@ -2319,4 +2325,6 @@ struct ref_storage_be refs_be_reftable = { .create_reflog = reftable_be_create_reflog, .delete_reflog = reftable_be_delete_reflog, .reflog_expire = reftable_be_reflog_expire, + + .fsck = reftable_be_fsck, }; From patchwork Mon Jul 1 15:20:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13718308 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5080F15A84A for ; Mon, 1 Jul 2024 15:20:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847253; cv=none; b=d3y9aClMWMDPfGaIjCxcyWBIMpuEQAjwwu9iQeZ/PG7WesFmN07K7G9IHafi4JUXHO9AHlTrv3zAE7GPhkxFtCl8rHWWZWYGfPX34Y94gAsGr9eTxdsHjC5s3isYOM+4TxTa1PvJ2hHsrvpmxqCMS1pUFuNSK+3dwzO0P9AYo2o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847253; c=relaxed/simple; bh=N+5AK2TMcZvgnkSoO5vGTo33oNwPi/2ZyJpiTQorZyk=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=KxwgEilXm1ZONvEq3Ay/H9ljI6T5m7rLwKgJBPzvLViSLrE9iWupJP1il4/51ov4L8GFnhJWaUc1ixcWuQmtDFQH5/bUAXXANGWyIOWKadtRsD8pFF7PY252BuCn5gN9O/TuOheRk0RWga+FqMjfQBKFlKKDLIx8tgm52EsOmRk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=T2dtSkRx; arc=none smtp.client-ip=209.85.214.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="T2dtSkRx" Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-1f9aa039327so17084575ad.2 for ; Mon, 01 Jul 2024 08:20:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719847251; x=1720452051; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=QjsZoLtXp2baCjFDVQFv5b+O8fbHb6Fh+G4q54LKTlY=; b=T2dtSkRxQ1SvZpnhhRLfjmmH8YZJle+j5As/ZYyHiHbMP8Te8c2sVlN3XK2dzITJlH P7R8N37RnYiRrkMjwrVtEgstPzhGtNBteZsmsiA1YmlIB1N2PYx4pAsmCysucwJgoqM3 D7kbPFqF5T53bNvNpsVHu4YZAhfImM8K0cOIiUxCbvSawl+eq6fJocMPLMf8kkYn4EYh m4OuK8iWTaz3UeNN3J709bIoXA8OnzGBav46pDrkBCBOnLRUfRrPIyw9ZzqDQQvJqW9O h2xY4POsN4pdguJsa8k4F0vojoiDXBkJf4nMGerAev4YJP7L8ozYaJtGC2pZ1Gy00ewB SPtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719847251; x=1720452051; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=QjsZoLtXp2baCjFDVQFv5b+O8fbHb6Fh+G4q54LKTlY=; b=Fjjilm4KVp5xwLSeKY6yjxOxKihiQMcmYkOyHXKb8ziWIqoo8h3KuWscWpsocNPxzU x5cYJTyJnjBRdt6lBVjpD91mpADcSpbP+ZYczFioY3zzBsMu+p/Pu2ykPqm14UoPIx4m gm8gzS0gypSiTqp2k9gQ4dsiw2/iW6rmCSleYw8rXpZZrIFMXAsx8ejpotG4+rLrIL5Z kV9CQ4W0nlsOLTEorcFTutiJCovcjXtWKKwg2Xf/v3QdnVqNHc/AuvuB9HrZBiRbRdvB mMyPKOr6SdrXZ183+MtdK5F/kchEE+zZpaeZOPSRi74AUWv+KiaF7Mggt9lUsLodTDeL fjMQ== X-Gm-Message-State: AOJu0YxAHDiEQcL0SQwVi84muFG1a9FH9Qr+g4+qXVt6bUc8/EsSLilU gS35IV5wfiR2PUBuWvPxHqpQSbTuozgxGTu2b7qYvVW31x+J6i1ckR1CRQ== X-Google-Smtp-Source: AGHT+IG11I4zYm482sHnlxp0vjVOpzZ8G/ozLM4z0uQQ+TqDDAIw60umwwzx23lHWnGsdDIX3ywxbg== X-Received: by 2002:a17:902:e74d:b0:1f7:2135:ce6d with SMTP id d9443c01a7336-1fadbc746a8mr36568885ad.18.1719847251021; Mon, 01 Jul 2024 08:20:51 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fac10e2197sm66199865ad.63.2024.07.01.08.20.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jul 2024 08:20:50 -0700 (PDT) Date: Mon, 1 Jul 2024 23:20:48 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano , Eric Sunshine Subject: [GSoC][PATCH v6 07/11] builtin/refs: add verify subcommand Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Introduce a new subcommand "verify" in git-refs(1) to allow the user to check the reference database consistency. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- Documentation/git-refs.txt | 13 +++++++++++ builtin/refs.c | 44 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/Documentation/git-refs.txt b/Documentation/git-refs.txt index 5b99e04385..1244a85b64 100644 --- a/Documentation/git-refs.txt +++ b/Documentation/git-refs.txt @@ -10,6 +10,7 @@ SYNOPSIS -------- [verse] 'git refs migrate' --ref-format= [--dry-run] +'git refs verify' [--strict] [--verbose] DESCRIPTION ----------- @@ -22,6 +23,9 @@ COMMANDS migrate:: Migrate ref store between different formats. +verify:: + Verify reference database consistency. + OPTIONS ------- @@ -39,6 +43,15 @@ include::ref-storage-format.txt[] can be used to double check that the migration works as expected before performing the actual migration. +The following options are specific to 'git refs verify': + +--strict:: + Enable more strict checking, every WARN severity for the `Fsck Messages` + be seen as ERROR. See linkgit:git-fsck[1]. + +--verbose:: + When verifying the reference database consistency, be chatty. + KNOWN LIMITATIONS ----------------- diff --git a/builtin/refs.c b/builtin/refs.c index 46dcd150d4..34371573f7 100644 --- a/builtin/refs.c +++ b/builtin/refs.c @@ -1,4 +1,6 @@ #include "builtin.h" +#include "config.h" +#include "fsck.h" #include "parse-options.h" #include "refs.h" #include "repository.h" @@ -7,6 +9,9 @@ #define REFS_MIGRATE_USAGE \ N_("git refs migrate --ref-format= [--dry-run]") +#define REFS_VERIFY_USAGE \ + N_("git refs verify [--strict] [--verbose]") + static int cmd_refs_migrate(int argc, const char **argv, const char *prefix) { const char * const migrate_usage[] = { @@ -58,15 +63,54 @@ static int cmd_refs_migrate(int argc, const char **argv, const char *prefix) return err; } +static int cmd_refs_verify(int argc, const char **argv, const char *prefix) +{ + struct fsck_options fsck_refs_options = FSCK_REFS_OPTIONS_DEFAULT; + const char * const verify_usage[] = { + REFS_VERIFY_USAGE, + NULL, + }; + unsigned int verbose = 0, strict = 0; + struct option options[] = { + OPT__VERBOSE(&verbose, N_("be verbose")), + OPT_BOOL(0, "strict", &strict, N_("enable strict checking")), + OPT_END(), + }; + int ret = 0; + + argc = parse_options(argc, argv, prefix, options, verify_usage, 0); + if (argc) + usage(_("too many arguments")); + + if (verbose) + fsck_refs_options.refs_options.verbose = 1; + if (strict) + fsck_refs_options.strict = 1; + + git_config(git_fsck_config, &fsck_refs_options); + prepare_repo_settings(the_repository); + + ret = refs_fsck(get_main_ref_store(the_repository), &fsck_refs_options); + + /* + * Explicitly free the allocated array and "oid_skiplist" + */ + free(fsck_refs_options.msg_type); + oidset_clear(&fsck_refs_options.oid_skiplist); + return ret; +} + int cmd_refs(int argc, const char **argv, const char *prefix) { const char * const refs_usage[] = { REFS_MIGRATE_USAGE, + REFS_VERIFY_USAGE, NULL, }; parse_opt_subcommand_fn *fn = NULL; struct option opts[] = { OPT_SUBCOMMAND("migrate", &fn, cmd_refs_migrate), + OPT_SUBCOMMAND("verify", &fn, cmd_refs_verify), OPT_END(), }; From patchwork Mon Jul 1 15:21:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13718309 Received: from mail-pl1-f181.google.com (mail-pl1-f181.google.com [209.85.214.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7A06A15A84A for ; Mon, 1 Jul 2024 15:21:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847276; cv=none; b=tf5Yj5BLTYr7MAg1U7sNAgo7M73AwqjARo3ddCOeQPgcntpIhmFrt7hM7LNwTJJgoTJWJYeKtKhyaPqzYw/56POrVTVyhSpXf7BXLt41hcruwO15/oCESOHygM45tCDVM1WiprKwzn3ZxrCyMN/kf9pD3vuPZoBCF2OR6KJFocY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847276; c=relaxed/simple; bh=0479d8Robjnw9VfgGsAQjtWbMj7HQSHTxjLgP1mruuI=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=inCwLguGR0GSzH+FM/Q0kweeLYxyGwwSWaaeLY8WYC4oAW14AXeMItq81sDxCehRSDxHUDXN7SHnRQqm92pTFinWqbfwFxD2NSiUiDAd1+GQh7Rv1lLhXFRViGKV92vZzq/dm6d7FN9sfZiflJIl7khtMNiPMNStZFPfR6S28MY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=THUwV3Vb; arc=none smtp.client-ip=209.85.214.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="THUwV3Vb" Received: by mail-pl1-f181.google.com with SMTP id d9443c01a7336-1fa3bdd91c1so23881955ad.2 for ; Mon, 01 Jul 2024 08:21:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719847274; x=1720452074; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=F34P474Se0eWjNRjL0aCCuMLLmdx/sNHOXqR74pYVWw=; b=THUwV3Vb5DlFV7LQoyeoUsPtVny7+iouuNafzfsNJY4WKxgtl8RmGs0DInVy/ezGET ioBQhC1naZuTdlIgj3Cx2s2Q/4L4g9Dkrra+7gEZmg5KM+N199DoqfqJhLZIALLNVYVL NqjufZIhjUwBkHq22ZKmT3hmTC8xUgFNRUIh6UXCKSxcdYRh1M0/aB7ciVhQEMP8aORI vN7J4PoFhP1wHSUetEjpb9+35lyoGdOOs7iT7N9rTqgf+fMelbCBMx3iE0UuQ5Nmp0Xt e+IGxuuzDPjOUKRgnkGY1RaAs+tqfsWfwvPHHU+KBo4dN1TqALfUKifVSZOHIX7MeO8O 3CiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719847274; x=1720452074; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=F34P474Se0eWjNRjL0aCCuMLLmdx/sNHOXqR74pYVWw=; b=dC6V2otM09MqBpQeh+Fr3LirbNBuUli4RPo5QJdfcmdVgvGp7TgeVIu6DgYHKEUCKr dvHf0ZuGfepGRUuwma5zOPxTXjA4QAlZZ+n8vWXyYvCnR10Iw4kQvGQBekUrJoCXQcBt T4H7OiogU7M2u9uskaUN4C81BcvnqHg/WkdGQ2jKkZe01ip7NqHhv+k1mdCdlCR1LBQS d8y0lx69QwxY2B4/QuAb/yz+jPy/99LiFDjJRMc1g+5gh0RTRKv30phXOWSA5Stk8fZP zSzHer317DbS1rp8/tyCsuAWh84U/iBbkpdBoMAZHeNYweFbCna8NInJbFslmM4s+aTz r+Xw== X-Gm-Message-State: AOJu0Yyve9TlXujmfcSCn9Q5+7YVrrifUcF8Et66ejyq4+SOHbwAE0s3 luzP7XmoMM6gKoM/qaH8Id47F3UF0Ynw5eOHpR+NtQZRUMegLCoz9ZgDMw== X-Google-Smtp-Source: AGHT+IFD3fBZwEz5tbeB4T9i92loWzlUg1IAU/mXJ2ju7T0QNbWYk6eoVJwNtzIZY5PvLRQLgH6oAA== X-Received: by 2002:a17:902:6546:b0:1fa:1599:385b with SMTP id d9443c01a7336-1fadbc74913mr45877385ad.22.1719847274260; Mon, 01 Jul 2024 08:21:14 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fac10d1c78sm67594695ad.23.2024.07.01.08.21.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jul 2024 08:21:13 -0700 (PDT) Date: Mon, 1 Jul 2024 23:21:11 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano , Eric Sunshine Subject: [GSoC][PATCH v6 08/11] builtin/fsck: add `git-refs verify` child process Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Introduce a new function "fsck_refs" that initializes and runs a child process to execute the "git-refs verify" command. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- builtin/fsck.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/builtin/fsck.c b/builtin/fsck.c index cdf2218dfd..aea635ea00 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -897,6 +897,21 @@ static int check_pack_rev_indexes(struct repository *r, int show_progress) return res; } +static void fsck_refs(void) +{ + struct child_process refs_verify = CHILD_PROCESS_INIT; + child_process_init(&refs_verify); + refs_verify.git_cmd = 1; + strvec_pushl(&refs_verify.args, "refs", "verify", NULL); + if (verbose) + strvec_push(&refs_verify.args, "--verbose"); + if (check_strict) + strvec_push(&refs_verify.args, "--strict"); + + if (run_command(&refs_verify)) + errors_found |= ERROR_REFS; +} + static char const * const fsck_usage[] = { N_("git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n" " [--[no-]full] [--strict] [--verbose] [--lost-found]\n" @@ -1066,6 +1081,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) check_connectivity(); + fsck_refs(); + if (the_repository->settings.core_commit_graph) { struct child_process commit_graph_verify = CHILD_PROCESS_INIT; From patchwork Mon Jul 1 15:21:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13718310 Received: from mail-pf1-f179.google.com (mail-pf1-f179.google.com [209.85.210.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5322116B74C for ; Mon, 1 Jul 2024 15:21:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847293; cv=none; b=Ln4VQ3Mf+eebirrqV87XTw3NWlcEFi+nPPHKfsxOgptVBzgEBZ8xKrgwp+wwuc2BZc67ujCCOpRTtjRZteErxUDqVuQMmLUgHu4MU5MYlgtwJcrWbZ7SMrqqyK46HyY0YSHGOvhm9t7ZGgpVAHeZBk82jxeglLIfwEkGSPkKSB8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847293; c=relaxed/simple; bh=H8bBaD/r5g0bhNAZPhyLDYGLSqu4f8FUd6DfqlOnvWU=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=DFyx2NkM1M27mFmfeFrWyakL1ZUblKGXUQrYODTzQJvJSSW/IY9R+gP1FSJrkVgeXGliO0XxgNtu8LYZLJLWRGsbM+37+OnZfK1AU/4eIyY84hRRfF0bBBsG3+MEmXSFj6feEH3jdTQwkZsoyVfxtoF46uOAjR60FhKZNij5MgY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=EysWk4dK; arc=none smtp.client-ip=209.85.210.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="EysWk4dK" Received: by mail-pf1-f179.google.com with SMTP id d2e1a72fcca58-70aaab1cb72so1717466b3a.0 for ; Mon, 01 Jul 2024 08:21:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719847291; x=1720452091; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=Jc2x0qPO2Bx2OyST5S83PSXATgDjPMUKdU5k8F+AbBY=; b=EysWk4dKAqjpeM/IsC5S40jDWiH0aRhTr/9lnWcnh0V86zA3j6qUA4Xtk7dpL63LxZ VK4uRrer5n1ViAMZ44l5/h8E4YRDd+zRe0+S0kef2YzZi/S23GwzT0qhbK/7/s2sn4sS 3vHwH8P2CTZd+3SJNKlOeEnT9TMS48hjnFi6g0kvvYTlx/yGzQ+vrqOd1GEhjzrpzoIl i7k1e+I+QcfQJLXAPJbXVDbzWZFfG9YEYAXLxpi2IwJ750gs1YVD6bjCBizh8lrDivmM tMgspAzZfl1UfnSoDSQ/yL8Bpzcv0T8z2/KzrxypsjYs6E+ufiD1kjFDaw8mmMUxXr7K LssQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719847291; x=1720452091; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Jc2x0qPO2Bx2OyST5S83PSXATgDjPMUKdU5k8F+AbBY=; b=okaSGphsIWPnYQtJYyWSlI53U1x7pfW1LepDsJShgLo/VxmmxEtPNfjX3BiwPfaO1A zAS4ozRrhaE48Zz3s7wrJiz6xjVYHHXmXlQyjayPBpkSOFMQfDo9nXbQ9ixpVhyoXKk8 TKsLYFUnUWr66P7gQWir0xNoAAqahLQ+MyoxJSbjm/TFVsrJ+TZntQu9PFQN6K8z9dJA bn+g6X9sMmsbhQf4abvzsbc9ij0nM+MKKy2EFlZnzgD+8kWYb0S3BpTBYp+2iuAry88v UhoQqP4qGqLGtpKsmySzKn+8lxHrrywaTQyLn6iaXrf1aWwN0hNXYmuPX42iOvCM4Px/ VEsA== X-Gm-Message-State: AOJu0YziSMtXpp4CUtOeXhwBHR+jVLWAzE2qlVTdvGlN8t9sy93bHJf1 6w3Deyy2WfXb8OstTqCza/NIFAp+pE5Pj3osjgruodtNPMj+7/Q+0qmOQQ== X-Google-Smtp-Source: AGHT+IHHIVw/jNOVoUeDyTSep8/rE4cw/Ua2+QE/letwea+7rCdQbH3MOjytWYl0UtjA1nQfhfgEQw== X-Received: by 2002:a05:6a20:7490:b0:1be:d745:66bc with SMTP id adf61e73a8af0-1bef610a18fmr9884718637.15.1719847290882; Mon, 01 Jul 2024 08:21:30 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fac1598bf9sm65967635ad.276.2024.07.01.08.21.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jul 2024 08:21:30 -0700 (PDT) Date: Mon, 1 Jul 2024 23:21:28 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano , Eric Sunshine Subject: [GSoC][PATCH v6 09/11] files-backend: add unified interface for refs scanning Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: For refs and reflogs, we need to scan its corresponding directories to check every regular file or symbolic link which shares the same pattern. Introduce a unified interface for scanning directories for files-backend. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- refs/files-backend.c | 77 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index 817813e723..744ee5c5db 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -4,6 +4,7 @@ #include "../gettext.h" #include "../hash.h" #include "../hex.h" +#include "../fsck.h" #include "../refs.h" #include "refs-internal.h" #include "ref-cache.h" @@ -3406,6 +3407,78 @@ static int files_ref_store_remove_on_disk(struct ref_store *ref_store, return ret; } +/* + * For refs and reflogs, they share a unified interface when scanning + * the whole directory. This function is used as the callback for each + * regular file or symlink in the directory. + */ +typedef int (*files_fsck_refs_fn)(struct fsck_options *o, + const char *gitdir, + const char *refs_check_dir, + struct dir_iterator *iter); + +static int files_fsck_refs_dir(struct ref_store *ref_store, + struct fsck_options *o, + const char *refs_check_dir, + files_fsck_refs_fn *fsck_refs_fns) +{ + const char *gitdir = ref_store->gitdir; + struct strbuf sb = STRBUF_INIT; + struct dir_iterator *iter; + int iter_status; + int ret = 0; + + strbuf_addf(&sb, "%s/%s", gitdir, refs_check_dir); + + iter = dir_iterator_begin(sb.buf, 0); + + if (!iter) { + ret = error_errno("cannot open directory %s", sb.buf); + goto out; + } + + while ((iter_status = dir_iterator_advance(iter)) == ITER_OK) { + if (S_ISDIR(iter->st.st_mode)) { + continue; + } else if (S_ISREG(iter->st.st_mode) || + S_ISLNK(iter->st.st_mode)) { + if (o->refs_options.verbose) + fprintf_ln(stderr, "Checking %s/%s", + refs_check_dir, iter->relative_path); + for (size_t i = 0; fsck_refs_fns[i]; i++) { + if (fsck_refs_fns[i](o, gitdir, refs_check_dir, iter)) + ret = -1; + } + } else { + ret = error(_("unexpected file type for '%s'"), + iter->basename); + } + } + + if (iter_status != ITER_DONE) + ret = error(_("failed to iterate over '%s'"), sb.buf); + +out: + strbuf_release(&sb); + return ret; +} + +static int files_fsck_refs(struct ref_store *ref_store, + struct fsck_options *o) +{ + int ret; + files_fsck_refs_fn fsck_refs_fns[]= { + NULL + }; + + if (o->refs_options.verbose) + fprintf_ln(stderr, "Checking references consistency"); + + ret = files_fsck_refs_dir(ref_store, o, "refs", fsck_refs_fns); + + return ret; +} + static int files_fsck(struct ref_store *ref_store, struct fsck_options *o) { @@ -3413,7 +3486,9 @@ static int files_fsck(struct ref_store *ref_store, struct files_ref_store *refs = files_downcast(ref_store, REF_STORE_READ, "fsck"); - ret = refs->packed_ref_store->be->fsck(refs->packed_ref_store, o); + ret = refs->packed_ref_store->be->fsck(refs->packed_ref_store, o) + | files_fsck_refs(ref_store, o); + return ret; } From patchwork Mon Jul 1 15:21:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13718312 Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32FA716C86A for ; Mon, 1 Jul 2024 15:21:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847311; cv=none; b=a932XRQ/GR6VbPSFY797bdHMhctrMvCCpOuGz2Tw0NT1M8SjfiB9Zq1bnLwxlAyhFNwrfHYjdyFcGp+vlXPGvSxlnY0H1e3B9njx+o4UZf8Gmpj/VJOznSlU/vZOV5UTU/ymcdnE4ZXPLj7c2gCjicvw1d+40Wtj7ruyLYucS0M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847311; c=relaxed/simple; bh=mj88k9N0NQkleeLlacpl6N5NZ8Gjp45b0pVjdau+Vlo=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=lUm7ZKne7i0dtagvoSL0gkSA/kCR3GQFbjJ5EE4W2IW6+SsC/No+Y8xtYAYfj7lPYBmXdLCtLyxfbCvU42vRxQWp5yDfcPPIpPnlKd/tUlgp3SdNV9SM/eEJlufRDBxKkf2x25lWiEbwMXgSKjbH5rI9/1sYIKuKR1dG0uowI+o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Jn2vha91; arc=none smtp.client-ip=209.85.214.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Jn2vha91" Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-1fab03d2f23so22472635ad.0 for ; Mon, 01 Jul 2024 08:21:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719847309; x=1720452109; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=nBTR/RgY/U4kT2X1MYEXOGnYJS09sheHjAc9ipwJTJU=; b=Jn2vha91dj7clxZ1L/QeIc61E6CDwc+tZS1DipovlDmrNgPKUcMPLDKiJ/WMim3xfb ioA6nolXwk659k0l8Ciycz4c1FyPLWkKoN9qc/209exEu9cTrcQgeV9KJT+L6IBlNyd8 BEKqQTEqMB0XIWKr1S1RTZiceuVukTca6IDwT1+z34DV1Tg4S7SrLlpMKPJbhaJzpBml zdLZCK+Nbb9hycLvsvTrjkXz42tyU+DzFxdWp7jjON36IyVnUbaYQBU7HaWuWre+TV6d +q/3QImoGwMVS0X6179rGz58h6oe5xRH6rxRF4/6XKoTOJxhRYmW6Ac/LqkjtX1qBKII fd2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719847309; x=1720452109; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=nBTR/RgY/U4kT2X1MYEXOGnYJS09sheHjAc9ipwJTJU=; b=cm6aE8pM69ljV0KZLcq/BSwOGDPDyiphBCnIUlo1v/oXkDJcsBTzg5ssO7gocBjqdr +VyaWjvJhBA2/oS5j33o/vOvBvZUmxRh7soDkD/CIFf18OIeUQschAvx8dVBuKYNmOVg 45KgzjLOohkzvbuK23VSmBtC/xu61dFuvQZfkYKWLoGzNZTcjXbosvc45t952IZuGY4w 2+ygTpIo608qSMsZEyMYJX7kAh2c67da/aCMwCXI545y1VUcr8WtCl3kjMUeP1W3Qlx7 13RJl1oNyUV5lXB2Fo85YCsje71dqoneaf+k3XK9F5SMkeNvkf1Cpo+aYgIT4PaNjq+l c0iA== X-Gm-Message-State: AOJu0YyY0IwWd6s3nbva/J/e+eN6Cpm9thnBIvD/yWE51k8J1fbARy9t eiypFOESFfMkKbHo45AJqrw48EvrUUwEeOsCe5PYImiExocdGK+IUllCVA== X-Google-Smtp-Source: AGHT+IFAwPqWbeEOiNROaa/PNzQxid0rrI8VpjQSvXE7yopC2wXULDzUcIEAkuO2BaZZFIbFYZlyVg== X-Received: by 2002:a17:902:784c:b0:1f7:2091:978 with SMTP id d9443c01a7336-1fadbcaaf4dmr21524235ad.37.1719847308442; Mon, 01 Jul 2024 08:21:48 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1facec847a6sm58440575ad.291.2024.07.01.08.21.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jul 2024 08:21:47 -0700 (PDT) Date: Mon, 1 Jul 2024 23:21:45 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano , Eric Sunshine Subject: [GSoC][PATCH v6 10/11] fsck: add ref name check for files backend Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The git-fsck(1) only implicitly checks the reference, it does not fully check refs with bad format name such as standalone "@" and name ending with ".lock". In order to provide such checks, add a new fsck message id "badRefName" with default ERROR type. Use existing "check_refname_format" to explicit check the ref name. And add a new unit test to verify the functionality. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- Documentation/fsck-msgids.txt | 3 + fsck.h | 1 + refs/files-backend.c | 20 +++++++ t/t0602-reffiles-fsck.sh | 101 ++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100755 t/t0602-reffiles-fsck.sh diff --git a/Documentation/fsck-msgids.txt b/Documentation/fsck-msgids.txt index f643585a34..dab4012246 100644 --- a/Documentation/fsck-msgids.txt +++ b/Documentation/fsck-msgids.txt @@ -19,6 +19,9 @@ `badParentSha1`:: (ERROR) A commit object has a bad parent sha1. +`badRefName`:: + (ERROR) A ref has a bad name. + `badTagName`:: (INFO) A tag has an invalid format. diff --git a/fsck.h b/fsck.h index 887fe2969f..fb035d5457 100644 --- a/fsck.h +++ b/fsck.h @@ -31,6 +31,7 @@ enum fsck_msg_type { FUNC(BAD_NAME, ERROR) \ FUNC(BAD_OBJECT_SHA1, ERROR) \ FUNC(BAD_PARENT_SHA1, ERROR) \ + FUNC(BAD_REF_NAME, ERROR) \ FUNC(BAD_TIMEZONE, ERROR) \ FUNC(BAD_TREE, ERROR) \ FUNC(BAD_TREE_SHA1, ERROR) \ diff --git a/refs/files-backend.c b/refs/files-backend.c index 744ee5c5db..3badec62ce 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3417,6 +3417,25 @@ typedef int (*files_fsck_refs_fn)(struct fsck_options *o, const char *refs_check_dir, struct dir_iterator *iter); +static int files_fsck_refs_name(struct fsck_options *o, + const char *gitdir UNUSED, + const char *refs_check_dir, + struct dir_iterator *iter) +{ + struct strbuf sb = STRBUF_INIT; + int ret = 0; + + if (check_refname_format(iter->basename, REFNAME_ALLOW_ONELEVEL)) { + strbuf_addf(&sb, "%s/%s", refs_check_dir, iter->relative_path); + ret = fsck_refs_report(o, NULL, sb.buf, + FSCK_MSG_BAD_REF_NAME, + "invalid refname format"); + } + + strbuf_release(&sb); + return ret; +} + static int files_fsck_refs_dir(struct ref_store *ref_store, struct fsck_options *o, const char *refs_check_dir, @@ -3468,6 +3487,7 @@ static int files_fsck_refs(struct ref_store *ref_store, { int ret; files_fsck_refs_fn fsck_refs_fns[]= { + files_fsck_refs_name, NULL }; diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh new file mode 100755 index 0000000000..b2db58d2c6 --- /dev/null +++ b/t/t0602-reffiles-fsck.sh @@ -0,0 +1,101 @@ +#!/bin/sh + +test_description='Test reffiles backend consistency check' + +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +GIT_TEST_DEFAULT_REF_FORMAT=files +export GIT_TEST_DEFAULT_REF_FORMAT + +. ./test-lib.sh + +test_expect_success 'ref name should be checked' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + ( + cd repo && + git commit --allow-empty -m initial && + git checkout -b branch-1 && + git tag tag-1 && + git commit --allow-empty -m second && + git checkout -b branch-2 && + git tag tag-2 && + git tag multi_hierarchy/tag-2 + ) && + ( + cd repo && + cp $branch_dir_prefix/branch-1 $branch_dir_prefix/.branch-1 && + test_must_fail git fsck 2>err && + cat >expect <<-EOF && + error: refs/heads/.branch-1: badRefName: invalid refname format + EOF + rm $branch_dir_prefix/.branch-1 && + test_cmp expect err + ) && + ( + cd repo && + cp $tag_dir_prefix/tag-1 $tag_dir_prefix/tag-1.lock && + test_must_fail git fsck 2>err && + cat >expect <<-EOF && + error: refs/tags/tag-1.lock: badRefName: invalid refname format + EOF + rm $tag_dir_prefix/tag-1.lock && + test_cmp expect err + ) && + ( + cd repo && + cp $branch_dir_prefix/branch-1 $branch_dir_prefix/@ && + test_must_fail git fsck 2>err && + cat >expect <<-EOF && + error: refs/heads/@: badRefName: invalid refname format + EOF + rm $branch_dir_prefix/@ && + test_cmp expect err + ) && + ( + cd repo && + cp $tag_dir_prefix/multi_hierarchy/tag-2 $tag_dir_prefix/multi_hierarchy/@ && + test_must_fail git fsck 2>err && + cat >expect <<-EOF && + error: refs/tags/multi_hierarchy/@: badRefName: invalid refname format + EOF + rm $tag_dir_prefix/multi_hierarchy/@ && + test_cmp expect err + ) +' + +test_expect_success 'ref name check should be adapted into fsck messages' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + ( + cd repo && + git commit --allow-empty -m initial && + git checkout -b branch-1 && + git tag tag-1 && + git commit --allow-empty -m second && + git checkout -b branch-2 && + git tag tag-2 + ) && + ( + cd repo && + cp $branch_dir_prefix/branch-1 $branch_dir_prefix/.branch-1 && + git -c fsck.badRefName=warn fsck 2>err && + cat >expect <<-EOF && + warning: refs/heads/.branch-1: badRefName: invalid refname format + EOF + rm $branch_dir_prefix/.branch-1 && + test_cmp expect err + ) && + ( + cd repo && + cp $branch_dir_prefix/branch-1 $branch_dir_prefix/@ && + git -c fsck.badRefName=ignore fsck 2>err && + test_must_be_empty err + ) +' + +test_done From patchwork Mon Jul 1 15:22:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13718313 Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E230D522F for ; Mon, 1 Jul 2024 15:22:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847326; cv=none; b=k6A6IydSJ3aFX18L47oYcKTvkCnJzoy/Xg9CpdPV0hV9b9U50SM3sS6w5M7UjDqizqm1y1py1E2Rfmm/4du76SkgZKFCF34vxbUZDTLHP6yMDjOFYrOh81nwda/v7zvnxc4jo7lxAwrDeWdvhSfNb8cYgHdbAnHJKd2Uy3qSlVk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719847326; c=relaxed/simple; bh=SqTItkjmekIOyp5DaL56mhZHJkpIwtCUkKKnj6vZ+xs=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=us0y2JjDg4GgOl+Ld4emqHuFV1VQnVyqdqKx2stg+jamgATIwtx+boi8xMCqjphM1W2bz9GeSGvpDm890m/odGr98jdbjPtdLTZr3fHcmOINj3VbZim6avI09zj2pzAjkHphwRLoYWkxdLTrx+gWGsPLoWVXXyw9C8WJjSjUAjs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=fE9fnNxa; arc=none smtp.client-ip=209.85.214.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fE9fnNxa" Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-1f9de13d6baso17627695ad.2 for ; Mon, 01 Jul 2024 08:22:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719847324; x=1720452124; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=kKYmFaFaNwF/SbSNB59CXwWZggZFY5tVe7Ok7TSKDKo=; b=fE9fnNxaCpUTHGgGAC+jFxMt3EPrpVvn4jq9a5++heCYptwYpPsjDPtEjvgK2QfLwf 733JPdp5j7yslu6tIeWw065FExK0CCkdg4D//BojVMNlqe6tr6gpojRC/0qjOJtyexqz t97gqspGLVI7Ial7JtC/5ZoPfLCeyIefg4N6fIjcNKLX2JfDcxKwe5wzaZWkMsMgv1ny BfLyBIROM7HRfUADDLGgc6N5ulRuyVfaQEwI9ZXeQBUV2ScmZeRkrJGgYKjsK0Y3ICRF UboUKTeFRTv8rrkh4h42UOk1EA9L9RqPCcWiELivQ86LMxMdN13sHNcfdF26QGPeP35H CVZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719847324; x=1720452124; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=kKYmFaFaNwF/SbSNB59CXwWZggZFY5tVe7Ok7TSKDKo=; b=G5QfP9Y73x3n9kirUlfFBGBBlYd0xoBK2bHA5suafMbf+mnrKZ9fyYeFSpq1b3uskn Yydu1WyB2J4Nvpxz55pVhMdCh6UAqVUUU9DOcY4R89oJJ8+Rjjf24kPaBT48PpL7XXrh 5GObKuizZC/+PQ1M7+V0280XdWB12roT69lJUfRoawn8qkr5WGzO53Vbv/IJ0QXF6Igm ccOb9btPb1D+6Wk0vpzFWYM+nW4fM9XU3wp8SU8kzm1huU8UCNO37XybTH4Jmk30IJD9 ykNUr05FhtN86jZV0FUv4GIoA1nrp0VFP4YMeW9b7tvE2QOnCC4mgZIvYaofHu/0rATv quiQ== X-Gm-Message-State: AOJu0Yy8AzLLKirc3yPjDhvxCxi1zbXcQ/AfP0cilN8Tc416g0T3dvu/ tsFIq88ieCChqnP5ChShm3TsM8YLny/czKTq8jHnO9IYlqWbel1QJgHbNw== X-Google-Smtp-Source: AGHT+IFedyLNJ1uClMLKgpxp+VPUWwimsSzw69A8m0+O9RZ37eGfPBdpHP14ojEvoAUtPSLdebe0VA== X-Received: by 2002:a17:903:988:b0:1fa:aa62:8b5c with SMTP id d9443c01a7336-1fadbc9eadfmr38245365ad.29.1719847323620; Mon, 01 Jul 2024 08:22:03 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fac10e2725sm67731065ad.70.2024.07.01.08.22.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jul 2024 08:22:03 -0700 (PDT) Date: Mon, 1 Jul 2024 23:22:00 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano , Eric Sunshine Subject: [GSoC][PATCH v6 11/11] fsck: add ref content check for files backend Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Enhance the git-fsck(1) command by adding a check for reference content in the files backend. The new functionality ensures that symrefs, real symbolic link and regular refs are validated correctly. In order to check the trailing content of the regular refs, add a new parameter `trailing` to `parse_loose_ref_contents`. For symrefs, `parse_loose_ref_contents` will set the "referent". However, symbolic link could be either absolute or relative. Use "strbuf_add_real_path" to read the symbolic link and convert the relative path to absolute path. Then use "skip_prefix" to make it align with symref "referent". Thus, the symrefs and symbolic links could share the same interface. Add a new function "files_fsck_symref_target" which aims at checking the following things: 1. whether the pointee is under the `refs/` directory. 2. whether the pointee name is correct. 3. whether the pointee path is a wrong type in filesystem. Last, add the following FSCK MESSAGEs: 1. "badRefContent(ERROR)": A ref has a bad content 2. "badSymrefPointee(ERROR)": The pointee of a symref is bad. 3. "trailingRefContent(WARN)": A ref content has trailing contents. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- Documentation/fsck-msgids.txt | 9 +++ fsck.h | 3 + refs.c | 2 +- refs/files-backend.c | 145 +++++++++++++++++++++++++++++++++- refs/refs-internal.h | 5 +- t/t0602-reffiles-fsck.sh | 110 ++++++++++++++++++++++++++ 6 files changed, 269 insertions(+), 5 deletions(-) diff --git a/Documentation/fsck-msgids.txt b/Documentation/fsck-msgids.txt index dab4012246..b1630a478b 100644 --- a/Documentation/fsck-msgids.txt +++ b/Documentation/fsck-msgids.txt @@ -19,9 +19,15 @@ `badParentSha1`:: (ERROR) A commit object has a bad parent sha1. +`badRefContent`:: + (ERROR) A ref has a bad content. + `badRefName`:: (ERROR) A ref has a bad name. +`badSymrefPointee`:: + (ERROR) The pointee of a symref is bad. + `badTagName`:: (INFO) A tag has an invalid format. @@ -167,6 +173,9 @@ `nullSha1`:: (WARN) Tree contains entries pointing to a null sha1. +`trailingRefContent`:: + (WARN) A ref content has trailing contents. + `treeNotSorted`:: (ERROR) A tree is not properly sorted. diff --git a/fsck.h b/fsck.h index fb035d5457..e917b221f6 100644 --- a/fsck.h +++ b/fsck.h @@ -32,6 +32,8 @@ enum fsck_msg_type { FUNC(BAD_OBJECT_SHA1, ERROR) \ FUNC(BAD_PARENT_SHA1, ERROR) \ FUNC(BAD_REF_NAME, ERROR) \ + FUNC(BAD_REF_CONTENT, ERROR) \ + FUNC(BAD_SYMREF_POINTEE, ERROR) \ FUNC(BAD_TIMEZONE, ERROR) \ FUNC(BAD_TREE, ERROR) \ FUNC(BAD_TREE_SHA1, ERROR) \ @@ -72,6 +74,7 @@ enum fsck_msg_type { FUNC(HAS_DOTDOT, WARN) \ FUNC(HAS_DOTGIT, WARN) \ FUNC(NULL_SHA1, WARN) \ + FUNC(TRAILING_REF_CONTENT, WARN) \ FUNC(ZERO_PADDED_FILEMODE, WARN) \ FUNC(NUL_IN_COMMIT, WARN) \ FUNC(LARGE_PATHNAME, WARN) \ diff --git a/refs.c b/refs.c index 5f17de38e2..4e94f92997 100644 --- a/refs.c +++ b/refs.c @@ -1758,7 +1758,7 @@ static int refs_read_special_head(struct ref_store *ref_store, } result = parse_loose_ref_contents(content.buf, oid, referent, type, - failure_errno); + failure_errno, NULL); done: strbuf_release(&full_path); diff --git a/refs/files-backend.c b/refs/files-backend.c index 3badec62ce..21a9a80d39 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1,4 +1,5 @@ #include "../git-compat-util.h" +#include "../abspath.h" #include "../copy.h" #include "../environment.h" #include "../gettext.h" @@ -551,7 +552,7 @@ static int read_ref_internal(struct ref_store *ref_store, const char *refname, strbuf_rtrim(&sb_contents); buf = sb_contents.buf; - ret = parse_loose_ref_contents(buf, oid, referent, type, &myerr); + ret = parse_loose_ref_contents(buf, oid, referent, type, &myerr, NULL); out: if (ret && !myerr) @@ -587,7 +588,7 @@ static int files_read_symbolic_ref(struct ref_store *ref_store, const char *refn int parse_loose_ref_contents(const char *buf, struct object_id *oid, struct strbuf *referent, unsigned int *type, - int *failure_errno) + int *failure_errno, const char **trailing) { const char *p; if (skip_prefix(buf, "ref:", &buf)) { @@ -609,6 +610,10 @@ int parse_loose_ref_contents(const char *buf, struct object_id *oid, *failure_errno = EINVAL; return -1; } + + if (trailing) + *trailing = p; + return 0; } @@ -3436,6 +3441,141 @@ static int files_fsck_refs_name(struct fsck_options *o, return ret; } +/* + * Check the symref "pointee_name" and "pointee_path". The caller should + * make sure that "pointee_path" is absolute. For symbolic ref, "pointee_name" + * would be the content after "refs:". For symblic link, "pointee_name" would + * be the relative path agaignst "gitdir". + */ +static int files_fsck_symref_target(struct fsck_options *o, + const char *refname, + const char *pointee_name, + const char *pointee_path) +{ + const char *p = NULL; + struct stat st; + int ret = 0; + + if (!skip_prefix(pointee_name, "refs/", &p)) { + + ret = fsck_refs_report(o, NULL, refname, + FSCK_MSG_BAD_SYMREF_POINTEE, + "point to target out of refs hierarchy"); + goto out; + } + + if (check_refname_format(pointee_name, 0)) { + ret = fsck_refs_report(o, NULL, refname, + FSCK_MSG_BAD_SYMREF_POINTEE, + "point to invalid refname"); + } + + if (lstat(pointee_path, &st) < 0) + goto out; + + if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) { + ret = fsck_refs_report(o, NULL, refname, + FSCK_MSG_BAD_SYMREF_POINTEE, + "point to invalid target"); + goto out; + } +out: + return ret; +} + +static int files_fsck_refs_content(struct fsck_options *o, + const char *gitdir, + const char *refs_check_dir, + struct dir_iterator *iter) +{ + struct strbuf pointee_path = STRBUF_INIT, + ref_content = STRBUF_INIT, + abs_gitdir = STRBUF_INIT, + referent = STRBUF_INIT, + refname = STRBUF_INIT; + const char *trailing = NULL; + int failure_errno = 0; + unsigned int type = 0; + struct object_id oid; + int ret = 0; + + strbuf_addf(&refname, "%s/%s", refs_check_dir, iter->relative_path); + + /* + * If the file is a symlink, we need to only check the connectivity + * of the destination object. + */ + if (S_ISLNK(iter->st.st_mode)) { + const char *pointee_name = NULL; + + strbuf_add_real_path(&pointee_path, iter->path.buf); + + strbuf_add_absolute_path(&abs_gitdir, gitdir); + strbuf_normalize_path(&abs_gitdir); + if (!is_dir_sep(abs_gitdir.buf[abs_gitdir.len - 1])) + strbuf_addch(&abs_gitdir, '/'); + + if (!skip_prefix(pointee_path.buf, + abs_gitdir.buf, &pointee_name)) { + ret = fsck_refs_report(o, NULL, refname.buf, + FSCK_MSG_BAD_SYMREF_POINTEE, + "point to target outside gitdir"); + goto clean; + } + + ret = files_fsck_symref_target(o, refname.buf, pointee_name, + pointee_path.buf); + goto clean; + } + + if (strbuf_read_file(&ref_content, iter->path.buf, 0) < 0) { + ret = error_errno(_("%s/%s: unable to read the ref"), + refs_check_dir, iter->relative_path); + goto clean; + } + + if (parse_loose_ref_contents(ref_content.buf, &oid, + &referent, &type, + &failure_errno, &trailing)) { + ret = fsck_refs_report(o, NULL, refname.buf, + FSCK_MSG_BAD_REF_CONTENT, + "invalid ref content"); + goto clean; + } + + /* + * If the ref is a symref, we need to check the destination name and + * connectivity. + */ + if (referent.len && (type & REF_ISSYMREF)) { + strbuf_addf(&pointee_path, "%s/%s", gitdir, referent.buf); + strbuf_rtrim(&referent); + + ret = files_fsck_symref_target(o, refname.buf, referent.buf, + pointee_path.buf); + goto clean; + } else { + /* + * Only regular refs could have a trailing garbage. Should + * be reported as a warning. + */ + if (trailing && (*trailing != '\0' && *trailing != '\n')) { + ret = fsck_refs_report(o, NULL, refname.buf, + FSCK_MSG_TRAILING_REF_CONTENT, + "trailing garbage in ref"); + goto clean; + } + } + +clean: + strbuf_release(&abs_gitdir); + strbuf_release(&pointee_path); + strbuf_release(&refname); + strbuf_release(&ref_content); + strbuf_release(&referent); + return ret; +} + static int files_fsck_refs_dir(struct ref_store *ref_store, struct fsck_options *o, const char *refs_check_dir, @@ -3488,6 +3628,7 @@ static int files_fsck_refs(struct ref_store *ref_store, int ret; files_fsck_refs_fn fsck_refs_fns[]= { files_fsck_refs_name, + files_fsck_refs_content, NULL }; diff --git a/refs/refs-internal.h b/refs/refs-internal.h index a905e187cd..2fabf41d14 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -709,11 +709,12 @@ struct ref_store { /* * Parse contents of a loose ref file. *failure_errno maybe be set to EINVAL for - * invalid contents. + * invalid contents. Also *trailing is set to the first character after the + * refname or NULL if the referent is not empty. */ int parse_loose_ref_contents(const char *buf, struct object_id *oid, struct strbuf *referent, unsigned int *type, - int *failure_errno); + int *failure_errno, const char **trailing); /* * Fill in the generic part of refs and add it to our collection of diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh index b2db58d2c6..35bf40ee64 100755 --- a/t/t0602-reffiles-fsck.sh +++ b/t/t0602-reffiles-fsck.sh @@ -98,4 +98,114 @@ test_expect_success 'ref name check should be adapted into fsck messages' ' ) ' +test_expect_success 'regular ref content should be checked' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + ( + cd repo && + git commit --allow-empty -m initial && + git checkout -b branch-1 && + git tag tag-1 && + git commit --allow-empty -m second && + git checkout -b branch-2 && + git tag tag-2 && + git checkout -b a/b/tag-2 + ) && + ( + cd repo && + printf "%s garbage" "$(git rev-parse branch-1)" > $branch_dir_prefix/branch-1-garbage && + git fsck 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-1-garbage: trailingRefContent: trailing garbage in ref + EOF + rm $branch_dir_prefix/branch-1-garbage && + test_cmp expect err + ) && + ( + cd repo && + printf "%s garbage" "$(git rev-parse tag-1)" > $tag_dir_prefix/tag-1-garbage && + test_must_fail git -c fsck.trailingRefContent=error fsck 2>err && + cat >expect <<-EOF && + error: refs/tags/tag-1-garbage: trailingRefContent: trailing garbage in ref + EOF + rm $tag_dir_prefix/tag-1-garbage && + test_cmp expect err + ) && + ( + cd repo && + printf "%s " "$(git rev-parse tag-2)" > $tag_dir_prefix/tag-2-garbage && + git fsck 2>err && + cat >expect <<-EOF && + warning: refs/tags/tag-2-garbage: trailingRefContent: trailing garbage in ref + EOF + rm $tag_dir_prefix/tag-2-garbage && + test_cmp expect err + ) && + ( + cd repo && + printf "xfsazqfxcadas" > $tag_dir_prefix/tag-2-bad && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/tags/tag-2-bad: badRefContent: invalid ref content + EOF + rm $tag_dir_prefix/tag-2-bad && + test_cmp expect err + ) && + ( + cd repo && + printf "xfsazqfxcadas" > $branch_dir_prefix/a/b/branch-2-bad && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/a/b/branch-2-bad: badRefContent: invalid ref content + EOF + rm $branch_dir_prefix/a/b/branch-2-bad && + test_cmp expect err + ) +' + +test_expect_success 'symbolic ref content should be checked' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + ( + cd repo && + git commit --allow-empty -m initial && + git checkout -b branch-1 && + git tag tag-1 + ) && + ( + cd repo && + printf "ref: refs/heads/.branch" > $branch_dir_prefix/branch-2-bad && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/branch-2-bad: badSymrefPointee: point to invalid refname + EOF + rm $branch_dir_prefix/branch-2-bad && + test_cmp expect err + ) && + ( + cd repo && + printf "ref: refs/heads" > $branch_dir_prefix/branch-2-bad && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/branch-2-bad: badSymrefPointee: point to invalid target + EOF + rm $branch_dir_prefix/branch-2-bad && + test_cmp expect err + ) && + ( + cd repo && + printf "ref: logs/maint-v2.45" > $branch_dir_prefix/branch-2-bad && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/branch-2-bad: badSymrefPointee: point to target out of refs hierarchy + EOF + rm $branch_dir_prefix/branch-2-bad && + test_cmp expect err + ) +' + test_done