builtin/refs: add verify subcommand

Introduce a new subcommand "verify" in git-refs(1) to allow the user to
check the reference database consistency and also this subcommand will
be used as the entry point of checking refs for "git-fsck(1)".

Add "verbose" field into "fsck_options" to indicate whether we should
print verbose messages when checking refs and objects consistency.

Remove bit-field for "strict" field, this is because we cannot take
address of a bit-field which makes it unhandy to set member variables
when parsing the command line options.

The "git-fsck(1)" declares "fsck_options" variable with "static"
identifier which avoids complaint by the leak-checker. However, in
"git-refs verify", we need to do memory clean manually. Thus add
"fsck_options_clear" function in "fsck.c" to provide memory clean
operation.

Mentored-by: Patrick Steinhardt <ps@pks.im>
Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: shejialuo <shejialuo@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
shejialuo
2024-08-08 19:27:28 +08:00
committed by Junio C Hamano
parent ab6f79d8df
commit bf061d26c7
4 changed files with 65 additions and 1 deletions

View File

@@ -10,6 +10,7 @@ SYNOPSIS
-------- --------
[verse] [verse]
'git refs migrate' --ref-format=<format> [--dry-run] 'git refs migrate' --ref-format=<format> [--dry-run]
'git refs verify' [--strict] [--verbose]
DESCRIPTION DESCRIPTION
----------- -----------
@@ -22,6 +23,9 @@ COMMANDS
migrate:: migrate::
Migrate ref store between different formats. Migrate ref store between different formats.
verify::
Verify reference database consistency.
OPTIONS OPTIONS
------- -------
@@ -39,6 +43,15 @@ include::ref-storage-format.txt[]
can be used to double check that the migration works as expected before can be used to double check that the migration works as expected before
performing the actual migration. performing the actual migration.
The following options are specific to 'git refs verify':
--strict::
Enable stricter error checking. This will cause warnings to be
reported as errors. See linkgit:git-fsck[1].
--verbose::
When verifying the reference database consistency, be chatty.
KNOWN LIMITATIONS KNOWN LIMITATIONS
----------------- -----------------

View File

@@ -1,4 +1,6 @@
#include "builtin.h" #include "builtin.h"
#include "config.h"
#include "fsck.h"
#include "parse-options.h" #include "parse-options.h"
#include "refs.h" #include "refs.h"
#include "repository.h" #include "repository.h"
@@ -7,6 +9,9 @@
#define REFS_MIGRATE_USAGE \ #define REFS_MIGRATE_USAGE \
N_("git refs migrate --ref-format=<format> [--dry-run]") N_("git refs migrate --ref-format=<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) static int cmd_refs_migrate(int argc, const char **argv, const char *prefix)
{ {
const char * const migrate_usage[] = { const char * const migrate_usage[] = {
@@ -58,15 +63,44 @@ out:
return err; 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,
};
struct option options[] = {
OPT_BOOL(0, "verbose", &fsck_refs_options.verbose, N_("be verbose")),
OPT_BOOL(0, "strict", &fsck_refs_options.strict, N_("enable strict checking")),
OPT_END(),
};
int ret;
argc = parse_options(argc, argv, prefix, options, verify_usage, 0);
if (argc)
usage(_("'git refs verify' takes no arguments"));
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);
fsck_options_clear(&fsck_refs_options);
return ret;
}
int cmd_refs(int argc, const char **argv, const char *prefix) int cmd_refs(int argc, const char **argv, const char *prefix)
{ {
const char * const refs_usage[] = { const char * const refs_usage[] = {
REFS_MIGRATE_USAGE, REFS_MIGRATE_USAGE,
REFS_VERIFY_USAGE,
NULL, NULL,
}; };
parse_opt_subcommand_fn *fn = NULL; parse_opt_subcommand_fn *fn = NULL;
struct option opts[] = { struct option opts[] = {
OPT_SUBCOMMAND("migrate", &fn, cmd_refs_migrate), OPT_SUBCOMMAND("migrate", &fn, cmd_refs_migrate),
OPT_SUBCOMMAND("verify", &fn, cmd_refs_verify),
OPT_END(), OPT_END(),
}; };

11
fsck.c
View File

@@ -1331,6 +1331,17 @@ int fsck_finish(struct fsck_options *options)
return ret; return ret;
} }
void fsck_options_clear(struct fsck_options *options)
{
free(options->msg_type);
oidset_clear(&options->skip_oids);
oidset_clear(&options->gitmodules_found);
oidset_clear(&options->gitmodules_done);
oidset_clear(&options->gitattributes_found);
oidset_clear(&options->gitattributes_done);
kh_clear_oid_map(options->object_names);
}
int git_fsck_config(const char *var, const char *value, int git_fsck_config(const char *var, const char *value,
const struct config_context *ctx, void *cb) const struct config_context *ctx, void *cb)
{ {

8
fsck.h
View File

@@ -153,7 +153,8 @@ struct fsck_ref_report {
struct fsck_options { struct fsck_options {
fsck_walk_func walk; fsck_walk_func walk;
fsck_error error_func; fsck_error error_func;
unsigned strict:1; unsigned strict;
unsigned verbose;
enum fsck_msg_type *msg_type; enum fsck_msg_type *msg_type;
struct oidset skip_oids; struct oidset skip_oids;
struct oidset gitmodules_found; struct oidset gitmodules_found;
@@ -231,6 +232,11 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
*/ */
int fsck_finish(struct fsck_options *options); int fsck_finish(struct fsck_options *options);
/*
* Clear the fsck_options struct, freeing any allocated memory.
*/
void fsck_options_clear(struct fsck_options *options);
/* /*
* Report an error or warning for refs. * Report an error or warning for refs.
*/ */