mirror of
https://github.com/git-for-windows/git.git
synced 2026-04-09 15:01:59 -05:00
Merge branch 'ps/fsck-wo-the-repository'
Internals of "git fsck" have been refactored to not depend on the global `the_repository` variable. * ps/fsck-wo-the-repository: builtin/fsck: stop using `the_repository` in error reporting builtin/fsck: stop using `the_repository` when marking objects builtin/fsck: stop using `the_repository` when checking packed objects builtin/fsck: stop using `the_repository` with loose objects builtin/fsck: stop using `the_repository` when checking reflogs builtin/fsck: stop using `the_repository` when checking refs builtin/fsck: stop using `the_repository` when snapshotting refs builtin/fsck: fix trivial dependence on `the_repository` fsck: drop USE_THE_REPOSITORY fsck: store repository in fsck options fsck: initialize fsck options via a function fetch-pack: move fsck options into function scope
This commit is contained in:
273
builtin/fsck.c
273
builtin/fsck.c
@@ -1,4 +1,3 @@
|
||||
#define USE_THE_REPOSITORY_VARIABLE
|
||||
#include "builtin.h"
|
||||
#include "gettext.h"
|
||||
#include "hex.h"
|
||||
@@ -42,8 +41,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;
|
||||
static struct fsck_options fsck_obj_options;
|
||||
static int errors_found;
|
||||
static int write_lost_and_found;
|
||||
static int verbose;
|
||||
@@ -66,14 +65,14 @@ static const char *describe_object(const struct object_id *oid)
|
||||
return fsck_describe_object(&fsck_walk_options, oid);
|
||||
}
|
||||
|
||||
static const char *printable_type(const struct object_id *oid,
|
||||
static const char *printable_type(struct repository *repo,
|
||||
const struct object_id *oid,
|
||||
enum object_type type)
|
||||
{
|
||||
const char *ret;
|
||||
|
||||
if (type == OBJ_NONE)
|
||||
type = odb_read_object_info(the_repository->objects,
|
||||
oid, NULL);
|
||||
type = odb_read_object_info(repo->objects, oid, NULL);
|
||||
|
||||
ret = type_name(type);
|
||||
if (!ret)
|
||||
@@ -82,17 +81,17 @@ static const char *printable_type(const struct object_id *oid,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int objerror(struct object *obj, const char *err)
|
||||
static int objerror(struct repository *repo, struct object *obj, const char *err)
|
||||
{
|
||||
errors_found |= ERROR_OBJECT;
|
||||
/* TRANSLATORS: e.g. error in tree 01bfda: <more explanation> */
|
||||
fprintf_ln(stderr, _("error in %s %s: %s"),
|
||||
printable_type(&obj->oid, obj->type),
|
||||
printable_type(repo, &obj->oid, obj->type),
|
||||
describe_object(&obj->oid), err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int fsck_objects_error_func(struct fsck_options *o UNUSED,
|
||||
static int fsck_objects_error_func(struct fsck_options *o,
|
||||
void *fsck_report,
|
||||
enum fsck_msg_type msg_type,
|
||||
enum fsck_msg_id msg_id UNUSED,
|
||||
@@ -106,13 +105,13 @@ static int fsck_objects_error_func(struct fsck_options *o UNUSED,
|
||||
case FSCK_WARN:
|
||||
/* TRANSLATORS: e.g. warning in tree 01bfda: <more explanation> */
|
||||
fprintf_ln(stderr, _("warning in %s %s: %s"),
|
||||
printable_type(oid, object_type),
|
||||
printable_type(o->repo, oid, object_type),
|
||||
describe_object(oid), message);
|
||||
return 0;
|
||||
case FSCK_ERROR:
|
||||
/* TRANSLATORS: e.g. error in tree 01bfda: <more explanation> */
|
||||
fprintf_ln(stderr, _("error in %s %s: %s"),
|
||||
printable_type(oid, object_type),
|
||||
printable_type(o->repo, oid, object_type),
|
||||
describe_object(oid), message);
|
||||
return 1;
|
||||
default:
|
||||
@@ -124,7 +123,7 @@ static int fsck_objects_error_func(struct fsck_options *o UNUSED,
|
||||
static struct object_array pending;
|
||||
|
||||
static int mark_object(struct object *obj, enum object_type type,
|
||||
void *data, struct fsck_options *options UNUSED)
|
||||
void *data, struct fsck_options *options)
|
||||
{
|
||||
struct object *parent = data;
|
||||
|
||||
@@ -136,7 +135,7 @@ static int mark_object(struct object *obj, enum object_type type,
|
||||
if (!obj) {
|
||||
/* ... these references to parent->fld are safe here */
|
||||
printf_ln(_("broken link from %7s %s"),
|
||||
printable_type(&parent->oid, parent->type),
|
||||
printable_type(options->repo, &parent->oid, parent->type),
|
||||
describe_object(&parent->oid));
|
||||
printf_ln(_("broken link from %7s %s"),
|
||||
(type == OBJ_ANY ? _("unknown") : type_name(type)),
|
||||
@@ -147,13 +146,13 @@ static int mark_object(struct object *obj, enum object_type type,
|
||||
|
||||
if (type != OBJ_ANY && obj->type != type)
|
||||
/* ... and the reference to parent is safe here */
|
||||
objerror(parent, _("wrong object type in link"));
|
||||
objerror(options->repo, parent, _("wrong object type in link"));
|
||||
|
||||
if (obj->flags & REACHABLE)
|
||||
return 0;
|
||||
obj->flags |= REACHABLE;
|
||||
|
||||
if (is_promisor_object(the_repository, &obj->oid))
|
||||
if (is_promisor_object(options->repo, &obj->oid))
|
||||
/*
|
||||
* Further recursion does not need to be performed on this
|
||||
* object since it is a promisor object (so it does not need to
|
||||
@@ -162,13 +161,13 @@ static int mark_object(struct object *obj, enum object_type type,
|
||||
return 0;
|
||||
|
||||
if (!(obj->flags & HAS_OBJ)) {
|
||||
if (parent && !odb_has_object(the_repository->objects, &obj->oid,
|
||||
if (parent && !odb_has_object(options->repo->objects, &obj->oid,
|
||||
HAS_OBJECT_RECHECK_PACKED)) {
|
||||
printf_ln(_("broken link from %7s %s\n"
|
||||
" to %7s %s"),
|
||||
printable_type(&parent->oid, parent->type),
|
||||
printable_type(options->repo, &parent->oid, parent->type),
|
||||
describe_object(&parent->oid),
|
||||
printable_type(&obj->oid, obj->type),
|
||||
printable_type(options->repo, &obj->oid, obj->type),
|
||||
describe_object(&obj->oid));
|
||||
errors_found |= ERROR_REACHABLE;
|
||||
}
|
||||
@@ -181,7 +180,7 @@ static int mark_object(struct object *obj, enum object_type type,
|
||||
|
||||
static void mark_object_reachable(struct object *obj)
|
||||
{
|
||||
mark_object(obj, OBJ_ANY, NULL, NULL);
|
||||
mark_object(obj, OBJ_ANY, NULL, &fsck_walk_options);
|
||||
}
|
||||
|
||||
static int traverse_one_object(struct object *obj)
|
||||
@@ -195,13 +194,13 @@ static int traverse_one_object(struct object *obj)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int traverse_reachable(void)
|
||||
static int traverse_reachable(struct repository *repo)
|
||||
{
|
||||
struct progress *progress = NULL;
|
||||
unsigned int nr = 0;
|
||||
int result = 0;
|
||||
if (show_progress)
|
||||
progress = start_delayed_progress(the_repository,
|
||||
progress = start_delayed_progress(repo,
|
||||
_("Checking connectivity"), 0);
|
||||
while (pending.nr) {
|
||||
result |= traverse_one_object(object_array_pop(&pending));
|
||||
@@ -222,10 +221,11 @@ static int mark_used(struct object *obj, enum object_type type UNUSED,
|
||||
|
||||
static int mark_unreachable_referents(const struct object_id *oid,
|
||||
struct object_info *oi UNUSED,
|
||||
void *data UNUSED)
|
||||
void *data)
|
||||
{
|
||||
struct fsck_options options = FSCK_OPTIONS_DEFAULT;
|
||||
struct object *obj = lookup_object(the_repository, oid);
|
||||
struct repository *repo = data;
|
||||
struct fsck_options options;
|
||||
struct object *obj = lookup_object(data, oid);
|
||||
|
||||
if (!obj || !(obj->flags & HAS_OBJ))
|
||||
return 0; /* not part of our original set */
|
||||
@@ -237,12 +237,13 @@ static int mark_unreachable_referents(const struct object_id *oid,
|
||||
* (and we want to avoid parsing blobs).
|
||||
*/
|
||||
if (obj->type == OBJ_NONE) {
|
||||
enum object_type type = odb_read_object_info(the_repository->objects,
|
||||
enum object_type type = odb_read_object_info(repo->objects,
|
||||
&obj->oid, NULL);
|
||||
if (type > 0)
|
||||
object_as_type(obj, type, 0);
|
||||
}
|
||||
|
||||
fsck_options_init(&options, repo, FSCK_OPTIONS_DEFAULT);
|
||||
options.walk = mark_used;
|
||||
fsck_walk(obj, NULL, &options);
|
||||
if (obj->type == OBJ_TREE)
|
||||
@@ -254,7 +255,7 @@ static int mark_unreachable_referents(const struct object_id *oid,
|
||||
/*
|
||||
* Check a single reachable object
|
||||
*/
|
||||
static void check_reachable_object(struct object *obj)
|
||||
static void check_reachable_object(struct repository *repo, struct object *obj)
|
||||
{
|
||||
/*
|
||||
* We obviously want the object to be parsed,
|
||||
@@ -262,12 +263,12 @@ static void check_reachable_object(struct object *obj)
|
||||
* do a full fsck
|
||||
*/
|
||||
if (!(obj->flags & HAS_OBJ)) {
|
||||
if (is_promisor_object(the_repository, &obj->oid))
|
||||
if (is_promisor_object(repo, &obj->oid))
|
||||
return;
|
||||
if (has_object_pack(the_repository, &obj->oid))
|
||||
if (has_object_pack(repo, &obj->oid))
|
||||
return; /* it is in pack - forget about it */
|
||||
printf_ln(_("missing %s %s"),
|
||||
printable_type(&obj->oid, obj->type),
|
||||
printable_type(repo, &obj->oid, obj->type),
|
||||
describe_object(&obj->oid));
|
||||
errors_found |= ERROR_REACHABLE;
|
||||
return;
|
||||
@@ -277,7 +278,7 @@ static void check_reachable_object(struct object *obj)
|
||||
/*
|
||||
* Check a single unreachable object
|
||||
*/
|
||||
static void check_unreachable_object(struct object *obj)
|
||||
static void check_unreachable_object(struct repository *repo, struct object *obj)
|
||||
{
|
||||
/*
|
||||
* Missing unreachable object? Ignore it. It's not like
|
||||
@@ -294,7 +295,7 @@ static void check_unreachable_object(struct object *obj)
|
||||
*/
|
||||
if (show_unreachable) {
|
||||
printf_ln(_("unreachable %s %s"),
|
||||
printable_type(&obj->oid, obj->type),
|
||||
printable_type(repo, &obj->oid, obj->type),
|
||||
describe_object(&obj->oid));
|
||||
return;
|
||||
}
|
||||
@@ -314,22 +315,22 @@ static void check_unreachable_object(struct object *obj)
|
||||
if (!(obj->flags & USED)) {
|
||||
if (show_dangling)
|
||||
printf_ln(_("dangling %s %s"),
|
||||
printable_type(&obj->oid, obj->type),
|
||||
printable_type(repo, &obj->oid, obj->type),
|
||||
describe_object(&obj->oid));
|
||||
if (write_lost_and_found) {
|
||||
char *filename = repo_git_path(the_repository, "lost-found/%s/%s",
|
||||
char *filename = repo_git_path(repo, "lost-found/%s/%s",
|
||||
obj->type == OBJ_COMMIT ? "commit" : "other",
|
||||
describe_object(&obj->oid));
|
||||
FILE *f;
|
||||
|
||||
if (safe_create_leading_directories_const(the_repository, filename)) {
|
||||
if (safe_create_leading_directories_const(repo, filename)) {
|
||||
error(_("could not create lost-found"));
|
||||
free(filename);
|
||||
return;
|
||||
}
|
||||
f = xfopen(filename, "w");
|
||||
if (obj->type == OBJ_BLOB) {
|
||||
if (odb_stream_blob_to_fd(the_repository->objects, fileno(f),
|
||||
if (odb_stream_blob_to_fd(repo->objects, fileno(f),
|
||||
&obj->oid, NULL, 1))
|
||||
die_errno(_("could not write '%s'"), filename);
|
||||
} else
|
||||
@@ -349,23 +350,23 @@ static void check_unreachable_object(struct object *obj)
|
||||
*/
|
||||
}
|
||||
|
||||
static void check_object(struct object *obj)
|
||||
static void check_object(struct repository *repo, struct object *obj)
|
||||
{
|
||||
if (verbose)
|
||||
fprintf_ln(stderr, _("Checking %s"), describe_object(&obj->oid));
|
||||
|
||||
if (obj->flags & REACHABLE)
|
||||
check_reachable_object(obj);
|
||||
check_reachable_object(repo, obj);
|
||||
else
|
||||
check_unreachable_object(obj);
|
||||
check_unreachable_object(repo, obj);
|
||||
}
|
||||
|
||||
static void check_connectivity(void)
|
||||
static void check_connectivity(struct repository *repo)
|
||||
{
|
||||
int i, max;
|
||||
|
||||
/* Traverse the pending reachable objects */
|
||||
traverse_reachable();
|
||||
traverse_reachable(repo);
|
||||
|
||||
/*
|
||||
* With --connectivity-only, we won't have actually opened and marked
|
||||
@@ -383,24 +384,25 @@ static void check_connectivity(void)
|
||||
* and ignore any that weren't present in our earlier
|
||||
* traversal.
|
||||
*/
|
||||
odb_for_each_object(the_repository->objects, NULL,
|
||||
mark_unreachable_referents, NULL, 0);
|
||||
odb_for_each_object(repo->objects, NULL,
|
||||
mark_unreachable_referents, repo, 0);
|
||||
}
|
||||
|
||||
/* Look up all the requirements, warn about missing objects.. */
|
||||
max = get_max_object_index(the_repository);
|
||||
max = get_max_object_index(repo);
|
||||
if (verbose)
|
||||
fprintf_ln(stderr, _("Checking connectivity (%d objects)"), max);
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
struct object *obj = get_indexed_object(the_repository, i);
|
||||
struct object *obj = get_indexed_object(repo, i);
|
||||
|
||||
if (obj)
|
||||
check_object(obj);
|
||||
check_object(repo, obj);
|
||||
}
|
||||
}
|
||||
|
||||
static int fsck_obj(struct object *obj, void *buffer, unsigned long size)
|
||||
static int fsck_obj(struct repository *repo,
|
||||
struct object *obj, void *buffer, unsigned long size)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -410,11 +412,11 @@ static int fsck_obj(struct object *obj, void *buffer, unsigned long size)
|
||||
|
||||
if (verbose)
|
||||
fprintf_ln(stderr, _("Checking %s %s"),
|
||||
printable_type(&obj->oid, obj->type),
|
||||
printable_type(repo, &obj->oid, obj->type),
|
||||
describe_object(&obj->oid));
|
||||
|
||||
if (fsck_walk(obj, NULL, &fsck_obj_options))
|
||||
objerror(obj, _("broken links"));
|
||||
objerror(repo, obj, _("broken links"));
|
||||
err = fsck_object(obj, buffer, size, &fsck_obj_options);
|
||||
if (err)
|
||||
goto out;
|
||||
@@ -432,7 +434,7 @@ static int fsck_obj(struct object *obj, void *buffer, unsigned long size)
|
||||
|
||||
if (show_tags && tag->tagged) {
|
||||
printf_ln(_("tagged %s %s (%s) in %s"),
|
||||
printable_type(&tag->tagged->oid, tag->tagged->type),
|
||||
printable_type(repo, &tag->tagged->oid, tag->tagged->type),
|
||||
describe_object(&tag->tagged->oid),
|
||||
tag->tag,
|
||||
describe_object(&tag->object.oid));
|
||||
@@ -446,15 +448,16 @@ out:
|
||||
}
|
||||
|
||||
static int fsck_obj_buffer(const struct object_id *oid, enum object_type type,
|
||||
unsigned long size, void *buffer, int *eaten)
|
||||
unsigned long size, void *buffer, int *eaten, void *cb_data)
|
||||
{
|
||||
struct repository *repo = cb_data;
|
||||
struct object *obj;
|
||||
|
||||
/*
|
||||
* Note, buffer may be NULL if type is OBJ_BLOB. See
|
||||
* verify_packfile(), data_valid variable for details.
|
||||
*/
|
||||
struct object *obj;
|
||||
obj = parse_object_buffer(the_repository, oid, type, size, buffer,
|
||||
eaten);
|
||||
obj = parse_object_buffer(repo, oid, type, size, buffer, eaten);
|
||||
if (!obj) {
|
||||
errors_found |= ERROR_OBJECT;
|
||||
return error(_("%s: object corrupt or missing"),
|
||||
@@ -462,18 +465,19 @@ static int fsck_obj_buffer(const struct object_id *oid, enum object_type type,
|
||||
}
|
||||
obj->flags &= ~(REACHABLE | SEEN);
|
||||
obj->flags |= HAS_OBJ;
|
||||
return fsck_obj(obj, buffer, size);
|
||||
return fsck_obj(repo, obj, buffer, size);
|
||||
}
|
||||
|
||||
static int default_refs;
|
||||
|
||||
static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
|
||||
timestamp_t timestamp)
|
||||
static void fsck_handle_reflog_oid(struct repository *repo,
|
||||
const char *refname, struct object_id *oid,
|
||||
timestamp_t timestamp)
|
||||
{
|
||||
struct object *obj;
|
||||
|
||||
if (!is_null_oid(oid)) {
|
||||
obj = lookup_object(the_repository, oid);
|
||||
obj = lookup_object(repo, oid);
|
||||
if (obj && (obj->flags & HAS_OBJ)) {
|
||||
if (timestamp)
|
||||
fsck_put_object_name(&fsck_walk_options, oid,
|
||||
@@ -481,7 +485,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
|
||||
refname, timestamp);
|
||||
obj->flags |= USED;
|
||||
mark_object_reachable(obj);
|
||||
} else if (!is_promisor_object(the_repository, oid)) {
|
||||
} else if (!is_promisor_object(repo, oid)) {
|
||||
error(_("%s: invalid reflog entry %s"),
|
||||
refname, oid_to_hex(oid));
|
||||
errors_found |= ERROR_REACHABLE;
|
||||
@@ -493,8 +497,10 @@ static int fsck_handle_reflog_ent(const char *refname,
|
||||
struct object_id *ooid, struct object_id *noid,
|
||||
const char *email UNUSED,
|
||||
timestamp_t timestamp, int tz UNUSED,
|
||||
const char *message UNUSED, void *cb_data UNUSED)
|
||||
const char *message UNUSED, void *cb_data)
|
||||
{
|
||||
struct repository *repo = cb_data;
|
||||
|
||||
if (now && timestamp > now)
|
||||
return 0;
|
||||
|
||||
@@ -502,19 +508,20 @@ static int fsck_handle_reflog_ent(const char *refname,
|
||||
fprintf_ln(stderr, _("Checking reflog %s->%s"),
|
||||
oid_to_hex(ooid), oid_to_hex(noid));
|
||||
|
||||
fsck_handle_reflog_oid(refname, ooid, 0);
|
||||
fsck_handle_reflog_oid(refname, noid, timestamp);
|
||||
fsck_handle_reflog_oid(repo, refname, ooid, 0);
|
||||
fsck_handle_reflog_oid(repo, refname, noid, timestamp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsck_handle_reflog(const char *logname, void *cb_data)
|
||||
{
|
||||
struct strbuf refname = STRBUF_INIT;
|
||||
struct worktree *wt = cb_data;
|
||||
|
||||
strbuf_worktree_ref(cb_data, &refname, logname);
|
||||
refs_for_each_reflog_ent(get_main_ref_store(the_repository),
|
||||
strbuf_worktree_ref(wt, &refname, logname);
|
||||
refs_for_each_reflog_ent(get_main_ref_store(wt->repo),
|
||||
refname.buf, fsck_handle_reflog_ent,
|
||||
NULL);
|
||||
wt->repo);
|
||||
strbuf_release(&refname);
|
||||
return 0;
|
||||
}
|
||||
@@ -532,14 +539,20 @@ struct snapshot {
|
||||
/* TODO: Consider also snapshotting the index of each worktree. */
|
||||
};
|
||||
|
||||
struct snapshot_ref_data {
|
||||
struct repository *repo;
|
||||
struct snapshot *snap;
|
||||
};
|
||||
|
||||
static int snapshot_ref(const struct reference *ref, void *cb_data)
|
||||
{
|
||||
struct snapshot *snap = cb_data;
|
||||
struct snapshot_ref_data *data = cb_data;
|
||||
struct snapshot *snap = data->snap;
|
||||
struct object *obj;
|
||||
|
||||
obj = parse_object(the_repository, ref->oid);
|
||||
obj = parse_object(data->repo, ref->oid);
|
||||
if (!obj) {
|
||||
if (is_promisor_object(the_repository, ref->oid)) {
|
||||
if (is_promisor_object(data->repo, ref->oid)) {
|
||||
/*
|
||||
* Increment default_refs anyway, because this is a
|
||||
* valid ref.
|
||||
@@ -567,11 +580,12 @@ static int snapshot_ref(const struct reference *ref, void *cb_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsck_handle_ref(const struct reference *ref, void *cb_data UNUSED)
|
||||
static int fsck_handle_ref(const struct reference *ref, void *cb_data)
|
||||
{
|
||||
struct repository *repo = cb_data;
|
||||
struct object *obj;
|
||||
|
||||
obj = parse_object(the_repository, ref->oid);
|
||||
obj = parse_object(repo, ref->oid);
|
||||
obj->flags |= USED;
|
||||
fsck_put_object_name(&fsck_walk_options,
|
||||
ref->oid, "%s", ref->name);
|
||||
@@ -580,11 +594,16 @@ static int fsck_handle_ref(const struct reference *ref, void *cb_data UNUSED)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snapshot_refs(struct snapshot *snap, int argc, const char **argv)
|
||||
static void snapshot_refs(struct repository *repo,
|
||||
struct snapshot *snap, int argc, const char **argv)
|
||||
{
|
||||
struct refs_for_each_ref_options opts = {
|
||||
.flags = REFS_FOR_EACH_INCLUDE_BROKEN,
|
||||
};
|
||||
struct snapshot_ref_data data = {
|
||||
.repo = repo,
|
||||
.snap = snap,
|
||||
};
|
||||
struct worktree **worktrees, **p;
|
||||
const char *head_points_at;
|
||||
struct object_id head_oid;
|
||||
@@ -592,13 +611,13 @@ static void snapshot_refs(struct snapshot *snap, int argc, const char **argv)
|
||||
for (int i = 0; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
struct object_id oid;
|
||||
if (!repo_get_oid(the_repository, arg, &oid)) {
|
||||
if (!repo_get_oid(repo, arg, &oid)) {
|
||||
struct reference ref = {
|
||||
.name = arg,
|
||||
.oid = &oid,
|
||||
};
|
||||
|
||||
snapshot_ref(&ref, snap);
|
||||
snapshot_ref(&ref, &data);
|
||||
continue;
|
||||
}
|
||||
error(_("invalid parameter: expected sha1, got '%s'"), arg);
|
||||
@@ -610,8 +629,8 @@ static void snapshot_refs(struct snapshot *snap, int argc, const char **argv)
|
||||
return;
|
||||
}
|
||||
|
||||
refs_for_each_ref_ext(get_main_ref_store(the_repository),
|
||||
snapshot_ref, snap, &opts);
|
||||
refs_for_each_ref_ext(get_main_ref_store(repo),
|
||||
snapshot_ref, &data, &opts);
|
||||
|
||||
worktrees = get_worktrees();
|
||||
for (p = worktrees; *p; p++) {
|
||||
@@ -620,7 +639,7 @@ static void snapshot_refs(struct snapshot *snap, int argc, const char **argv)
|
||||
|
||||
strbuf_worktree_ref(wt, &refname, "HEAD");
|
||||
|
||||
head_points_at = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
|
||||
head_points_at = refs_resolve_ref_unsafe(get_main_ref_store(repo),
|
||||
refname.buf, 0, &head_oid, NULL);
|
||||
|
||||
if (head_points_at && !is_null_oid(&head_oid)) {
|
||||
@@ -629,7 +648,7 @@ static void snapshot_refs(struct snapshot *snap, int argc, const char **argv)
|
||||
.oid = &head_oid,
|
||||
};
|
||||
|
||||
snapshot_ref(&ref, snap);
|
||||
snapshot_ref(&ref, &data);
|
||||
}
|
||||
strbuf_release(&refname);
|
||||
|
||||
@@ -653,7 +672,7 @@ static void free_snapshot_refs(struct snapshot *snap)
|
||||
free(snap->ref);
|
||||
}
|
||||
|
||||
static void process_refs(struct snapshot *snap)
|
||||
static void process_refs(struct repository *repo, struct snapshot *snap)
|
||||
{
|
||||
struct worktree **worktrees, **p;
|
||||
|
||||
@@ -662,7 +681,7 @@ static void process_refs(struct snapshot *snap)
|
||||
.name = snap->ref[i].refname,
|
||||
.oid = &snap->ref[i].oid,
|
||||
};
|
||||
fsck_handle_ref(&ref, NULL);
|
||||
fsck_handle_ref(&ref, repo);
|
||||
}
|
||||
|
||||
if (include_reflogs) {
|
||||
@@ -694,27 +713,28 @@ static void process_refs(struct snapshot *snap)
|
||||
}
|
||||
}
|
||||
|
||||
struct for_each_loose_cb
|
||||
{
|
||||
struct for_each_loose_cb {
|
||||
struct repository *repo;
|
||||
struct progress *progress;
|
||||
};
|
||||
|
||||
static int fsck_loose(const struct object_id *oid, const char *path,
|
||||
void *data UNUSED)
|
||||
void *cb_data)
|
||||
{
|
||||
struct for_each_loose_cb *data = cb_data;
|
||||
struct object *obj;
|
||||
enum object_type type = OBJ_NONE;
|
||||
unsigned long size;
|
||||
void *contents = NULL;
|
||||
int eaten;
|
||||
struct object_info oi = OBJECT_INFO_INIT;
|
||||
struct object_id real_oid = *null_oid(the_hash_algo);
|
||||
struct object_id real_oid = *null_oid(data->repo->hash_algo);
|
||||
int err = 0;
|
||||
|
||||
oi.sizep = &size;
|
||||
oi.typep = &type;
|
||||
|
||||
if (read_loose_object(the_repository, path, oid, &real_oid, &contents, &oi) < 0) {
|
||||
if (read_loose_object(data->repo, path, oid, &real_oid, &contents, &oi) < 0) {
|
||||
if (contents && !oideq(&real_oid, oid))
|
||||
err = error(_("%s: hash-path mismatch, found at: %s"),
|
||||
oid_to_hex(&real_oid), path);
|
||||
@@ -731,7 +751,7 @@ static int fsck_loose(const struct object_id *oid, const char *path,
|
||||
if (!contents && type != OBJ_BLOB)
|
||||
BUG("read_loose_object streamed a non-blob");
|
||||
|
||||
obj = parse_object_buffer(the_repository, oid, type, size,
|
||||
obj = parse_object_buffer(data->repo, oid, type, size,
|
||||
contents, &eaten);
|
||||
|
||||
if (!obj) {
|
||||
@@ -745,7 +765,7 @@ static int fsck_loose(const struct object_id *oid, const char *path,
|
||||
|
||||
obj->flags &= ~(REACHABLE | SEEN);
|
||||
obj->flags |= HAS_OBJ;
|
||||
if (fsck_obj(obj, contents, size))
|
||||
if (fsck_obj(data->repo, obj, contents, size))
|
||||
errors_found |= ERROR_OBJECT;
|
||||
|
||||
if (!eaten)
|
||||
@@ -769,10 +789,11 @@ static int fsck_subdir(unsigned int nr, const char *path UNUSED, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fsck_source(struct odb_source *source)
|
||||
static void fsck_source(struct repository *repo, struct odb_source *source)
|
||||
{
|
||||
struct progress *progress = NULL;
|
||||
struct for_each_loose_cb cb_data = {
|
||||
.repo = source->odb->repo,
|
||||
.progress = progress,
|
||||
};
|
||||
|
||||
@@ -780,7 +801,7 @@ static void fsck_source(struct odb_source *source)
|
||||
fprintf_ln(stderr, _("Checking object directory"));
|
||||
|
||||
if (show_progress)
|
||||
progress = start_progress(the_repository,
|
||||
progress = start_progress(repo,
|
||||
_("Checking object directories"), 256);
|
||||
|
||||
for_each_loose_file_in_source(source, fsck_loose,
|
||||
@@ -789,7 +810,7 @@ static void fsck_source(struct odb_source *source)
|
||||
stop_progress(&progress);
|
||||
}
|
||||
|
||||
static int fsck_cache_tree(struct cache_tree *it, const char *index_path)
|
||||
static int fsck_cache_tree(struct repository *repo, struct cache_tree *it, const char *index_path)
|
||||
{
|
||||
int i;
|
||||
int err = 0;
|
||||
@@ -798,7 +819,7 @@ static int fsck_cache_tree(struct cache_tree *it, const char *index_path)
|
||||
fprintf_ln(stderr, _("Checking cache tree of %s"), index_path);
|
||||
|
||||
if (0 <= it->entry_count) {
|
||||
struct object *obj = parse_object(the_repository, &it->oid);
|
||||
struct object *obj = parse_object(repo, &it->oid);
|
||||
if (!obj) {
|
||||
error(_("%s: invalid sha1 pointer in cache-tree of %s"),
|
||||
oid_to_hex(&it->oid), index_path);
|
||||
@@ -809,10 +830,10 @@ static int fsck_cache_tree(struct cache_tree *it, const char *index_path)
|
||||
fsck_put_object_name(&fsck_walk_options, &it->oid, ":");
|
||||
mark_object_reachable(obj);
|
||||
if (obj->type != OBJ_TREE)
|
||||
err |= objerror(obj, _("non-tree in cache-tree"));
|
||||
err |= objerror(repo, obj, _("non-tree in cache-tree"));
|
||||
}
|
||||
for (i = 0; i < it->subtree_nr; i++)
|
||||
err |= fsck_cache_tree(it->down[i]->cache_tree, index_path);
|
||||
err |= fsck_cache_tree(repo, it->down[i]->cache_tree, index_path);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -838,7 +859,7 @@ static int fsck_resolve_undo(struct index_state *istate,
|
||||
if (!ru->mode[i] || !S_ISREG(ru->mode[i]))
|
||||
continue;
|
||||
|
||||
obj = parse_object(the_repository, &ru->oid[i]);
|
||||
obj = parse_object(istate->repo, &ru->oid[i]);
|
||||
if (!obj) {
|
||||
error(_("%s: invalid sha1 pointer in resolve-undo of %s"),
|
||||
oid_to_hex(&ru->oid[i]),
|
||||
@@ -870,7 +891,7 @@ static void fsck_index(struct index_state *istate, const char *index_path,
|
||||
mode = istate->cache[i]->ce_mode;
|
||||
if (S_ISGITLINK(mode))
|
||||
continue;
|
||||
blob = lookup_blob(the_repository,
|
||||
blob = lookup_blob(istate->repo,
|
||||
&istate->cache[i]->oid);
|
||||
if (!blob)
|
||||
continue;
|
||||
@@ -883,15 +904,16 @@ static void fsck_index(struct index_state *istate, const char *index_path,
|
||||
mark_object_reachable(obj);
|
||||
}
|
||||
if (istate->cache_tree)
|
||||
fsck_cache_tree(istate->cache_tree, index_path);
|
||||
fsck_cache_tree(istate->repo, istate->cache_tree, index_path);
|
||||
fsck_resolve_undo(istate, index_path);
|
||||
}
|
||||
|
||||
static int mark_object_for_connectivity(const struct object_id *oid,
|
||||
struct object_info *oi UNUSED,
|
||||
void *cb_data UNUSED)
|
||||
void *cb_data)
|
||||
{
|
||||
struct object *obj = lookup_unknown_object(the_repository, oid);
|
||||
struct repository *repo = cb_data;
|
||||
struct object *obj = lookup_unknown_object(repo, oid);
|
||||
obj->flags |= HAS_OBJ;
|
||||
return 0;
|
||||
}
|
||||
@@ -906,7 +928,7 @@ static int check_pack_rev_indexes(struct repository *r, int show_progress)
|
||||
if (show_progress) {
|
||||
repo_for_each_pack(r, p)
|
||||
pack_count++;
|
||||
progress = start_delayed_progress(the_repository,
|
||||
progress = start_delayed_progress(r,
|
||||
"Verifying reverse pack-indexes", pack_count);
|
||||
pack_count = 0;
|
||||
}
|
||||
@@ -986,7 +1008,7 @@ static struct option fsck_opts[] = {
|
||||
int cmd_fsck(int argc,
|
||||
const char **argv,
|
||||
const char *prefix,
|
||||
struct repository *repo UNUSED)
|
||||
struct repository *repo)
|
||||
{
|
||||
struct odb_source *source;
|
||||
struct snapshot snap = {
|
||||
@@ -1004,7 +1026,10 @@ int cmd_fsck(int argc,
|
||||
|
||||
argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0);
|
||||
|
||||
fsck_options_init(&fsck_walk_options, repo, FSCK_OPTIONS_DEFAULT);
|
||||
fsck_walk_options.walk = mark_object;
|
||||
|
||||
fsck_options_init(&fsck_obj_options, repo, FSCK_OPTIONS_DEFAULT);
|
||||
fsck_obj_options.walk = mark_used;
|
||||
fsck_obj_options.error_func = fsck_objects_error_func;
|
||||
if (check_strict)
|
||||
@@ -1023,11 +1048,11 @@ int cmd_fsck(int argc,
|
||||
if (name_objects)
|
||||
fsck_enable_object_names(&fsck_walk_options);
|
||||
|
||||
repo_config(the_repository, git_fsck_config, &fsck_obj_options);
|
||||
prepare_repo_settings(the_repository);
|
||||
repo_config(repo, git_fsck_config, &fsck_obj_options);
|
||||
prepare_repo_settings(repo);
|
||||
|
||||
if (check_references)
|
||||
fsck_refs(the_repository);
|
||||
fsck_refs(repo);
|
||||
|
||||
/*
|
||||
* Take a snapshot of the refs before walking objects to avoid looking
|
||||
@@ -1035,18 +1060,18 @@ int cmd_fsck(int argc,
|
||||
* objects. We can still walk over new objects that are added during the
|
||||
* execution of fsck but won't miss any objects that were reachable.
|
||||
*/
|
||||
snapshot_refs(&snap, argc, argv);
|
||||
snapshot_refs(repo, &snap, argc, argv);
|
||||
|
||||
/* Ensure we get a "fresh" view of the odb */
|
||||
odb_reprepare(the_repository->objects);
|
||||
odb_reprepare(repo->objects);
|
||||
|
||||
if (connectivity_only) {
|
||||
odb_for_each_object(the_repository->objects, NULL,
|
||||
mark_object_for_connectivity, NULL, 0);
|
||||
odb_for_each_object(repo->objects, NULL,
|
||||
mark_object_for_connectivity, repo, 0);
|
||||
} else {
|
||||
odb_prepare_alternates(the_repository->objects);
|
||||
for (source = the_repository->objects->sources; source; source = source->next)
|
||||
fsck_source(source);
|
||||
odb_prepare_alternates(repo->objects);
|
||||
for (source = repo->objects->sources; source; source = source->next)
|
||||
fsck_source(repo, source);
|
||||
|
||||
if (check_full) {
|
||||
struct packed_git *p;
|
||||
@@ -1054,20 +1079,20 @@ int cmd_fsck(int argc,
|
||||
struct progress *progress = NULL;
|
||||
|
||||
if (show_progress) {
|
||||
repo_for_each_pack(the_repository, p) {
|
||||
repo_for_each_pack(repo, p) {
|
||||
if (open_pack_index(p))
|
||||
continue;
|
||||
total += p->num_objects;
|
||||
}
|
||||
|
||||
progress = start_progress(the_repository,
|
||||
progress = start_progress(repo,
|
||||
_("Checking objects"), total);
|
||||
}
|
||||
|
||||
repo_for_each_pack(the_repository, p) {
|
||||
repo_for_each_pack(repo, p) {
|
||||
/* verify gives error messages itself */
|
||||
if (verify_pack(the_repository,
|
||||
p, fsck_obj_buffer,
|
||||
if (verify_pack(repo,
|
||||
p, fsck_obj_buffer, repo,
|
||||
progress, count))
|
||||
errors_found |= ERROR_PACK;
|
||||
count += p->num_objects;
|
||||
@@ -1080,7 +1105,7 @@ int cmd_fsck(int argc,
|
||||
}
|
||||
|
||||
/* Process the snapshotted refs and the reflogs. */
|
||||
process_refs(&snap);
|
||||
process_refs(repo, &snap);
|
||||
|
||||
/* If not given any explicit objects, process index files too. */
|
||||
if (!argc)
|
||||
@@ -1100,7 +1125,7 @@ int cmd_fsck(int argc,
|
||||
for (p = worktrees; *p; p++) {
|
||||
struct worktree *wt = *p;
|
||||
struct index_state istate =
|
||||
INDEX_STATE_INIT(the_repository);
|
||||
INDEX_STATE_INIT(repo);
|
||||
char *path, *wt_gitdir;
|
||||
|
||||
/*
|
||||
@@ -1121,17 +1146,17 @@ int cmd_fsck(int argc,
|
||||
free_worktrees(worktrees);
|
||||
}
|
||||
|
||||
errors_found |= check_pack_rev_indexes(the_repository, show_progress);
|
||||
if (verify_bitmap_files(the_repository))
|
||||
errors_found |= check_pack_rev_indexes(repo, show_progress);
|
||||
if (verify_bitmap_files(repo))
|
||||
errors_found |= ERROR_BITMAP;
|
||||
|
||||
check_connectivity();
|
||||
check_connectivity(repo);
|
||||
|
||||
if (the_repository->settings.core_commit_graph) {
|
||||
if (repo->settings.core_commit_graph) {
|
||||
struct child_process commit_graph_verify = CHILD_PROCESS_INIT;
|
||||
|
||||
odb_prepare_alternates(the_repository->objects);
|
||||
for (source = the_repository->objects->sources; source; source = source->next) {
|
||||
odb_prepare_alternates(repo->objects);
|
||||
for (source = repo->objects->sources; source; source = source->next) {
|
||||
child_process_init(&commit_graph_verify);
|
||||
commit_graph_verify.git_cmd = 1;
|
||||
strvec_pushl(&commit_graph_verify.args, "commit-graph",
|
||||
@@ -1145,11 +1170,11 @@ int cmd_fsck(int argc,
|
||||
}
|
||||
}
|
||||
|
||||
if (the_repository->settings.core_multi_pack_index) {
|
||||
if (repo->settings.core_multi_pack_index) {
|
||||
struct child_process midx_verify = CHILD_PROCESS_INIT;
|
||||
|
||||
odb_prepare_alternates(the_repository->objects);
|
||||
for (source = the_repository->objects->sources; source; source = source->next) {
|
||||
odb_prepare_alternates(repo->objects);
|
||||
for (source = repo->objects->sources; source; source = source->next) {
|
||||
child_process_init(&midx_verify);
|
||||
midx_verify.git_cmd = 1;
|
||||
strvec_pushl(&midx_verify.args, "multi-pack-index",
|
||||
|
||||
@@ -136,7 +136,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;
|
||||
static int verbose;
|
||||
static const char *progress_title;
|
||||
static int show_resolving_progress;
|
||||
@@ -1908,6 +1908,8 @@ int cmd_index_pack(int argc,
|
||||
show_usage_if_asked(argc, argv, index_pack_usage);
|
||||
|
||||
disable_replace_refs();
|
||||
|
||||
fsck_options_init(&fsck_options, the_repository, FSCK_OPTIONS_MISSING_GITMODULES);
|
||||
fsck_options.walk = mark_link;
|
||||
|
||||
reset_pack_idx_option(&opts);
|
||||
|
||||
@@ -16,7 +16,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;
|
||||
|
||||
static int mktag_fsck_error_func(struct fsck_options *o UNUSED,
|
||||
void *fsck_report UNUSED,
|
||||
@@ -75,7 +75,7 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
|
||||
int cmd_mktag(int argc,
|
||||
const char **argv,
|
||||
const char *prefix,
|
||||
struct repository *repo UNUSED)
|
||||
struct repository *repo)
|
||||
{
|
||||
static struct option builtin_mktag_options[] = {
|
||||
OPT_BOOL(0, "strict", &option_strict,
|
||||
@@ -94,6 +94,7 @@ int cmd_mktag(int argc,
|
||||
if (strbuf_read(&buf, 0, 0) < 0)
|
||||
die_errno(_("could not read from stdin"));
|
||||
|
||||
fsck_options_init(&fsck_options, repo, FSCK_OPTIONS_STRICT);
|
||||
fsck_options.error_func = mktag_fsck_error_func;
|
||||
fsck_set_msg_type_from_ids(&fsck_options, FSCK_MSG_EXTRA_HEADER_ENTRY,
|
||||
FSCK_WARN);
|
||||
|
||||
@@ -78,9 +78,9 @@ out:
|
||||
}
|
||||
|
||||
static int cmd_refs_verify(int argc, const char **argv, const char *prefix,
|
||||
struct repository *repo UNUSED)
|
||||
struct repository *repo)
|
||||
{
|
||||
struct fsck_options fsck_refs_options = FSCK_REFS_OPTIONS_DEFAULT;
|
||||
struct fsck_options fsck_refs_options;
|
||||
struct worktree **worktrees;
|
||||
const char * const verify_usage[] = {
|
||||
REFS_VERIFY_USAGE,
|
||||
@@ -93,6 +93,8 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix,
|
||||
};
|
||||
int ret = 0;
|
||||
|
||||
fsck_options_init(&fsck_refs_options, repo, FSCK_OPTIONS_REFS);
|
||||
|
||||
argc = parse_options(argc, argv, prefix, options, verify_usage, 0);
|
||||
if (argc)
|
||||
usage(_("'git refs verify' takes no arguments"));
|
||||
|
||||
@@ -29,7 +29,7 @@ static unsigned int offset, len;
|
||||
static off_t consumed_bytes;
|
||||
static off_t max_input_size;
|
||||
static struct git_hash_ctx ctx;
|
||||
static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
|
||||
static struct fsck_options fsck_options;
|
||||
static struct progress *progress;
|
||||
|
||||
/*
|
||||
@@ -613,7 +613,7 @@ static void unpack_all(void)
|
||||
int cmd_unpack_objects(int argc,
|
||||
const char **argv,
|
||||
const char *prefix UNUSED,
|
||||
struct repository *repo UNUSED)
|
||||
struct repository *repo)
|
||||
{
|
||||
int i;
|
||||
struct object_id oid;
|
||||
@@ -627,6 +627,8 @@ int cmd_unpack_objects(int argc,
|
||||
|
||||
show_usage_if_asked(argc, argv, unpack_usage);
|
||||
|
||||
fsck_options_init(&fsck_options, repo, FSCK_OPTIONS_STRICT);
|
||||
|
||||
for (i = 1 ; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
|
||||
|
||||
@@ -51,7 +51,6 @@ 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 strbuf fsck_msg_types = STRBUF_INIT;
|
||||
static struct string_list uri_protocols = STRING_LIST_INIT_DUP;
|
||||
|
||||
@@ -1096,6 +1095,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
|
||||
struct shallow_info *si,
|
||||
struct string_list *pack_lockfiles)
|
||||
{
|
||||
struct fsck_options fsck_options = { 0 };
|
||||
struct repository *r = the_repository;
|
||||
struct ref *ref = copy_ref_list(orig_ref);
|
||||
struct object_id oid;
|
||||
@@ -1224,6 +1224,8 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
|
||||
alternate_shallow_file = setup_temporary_shallow(si->shallow);
|
||||
} else
|
||||
alternate_shallow_file = NULL;
|
||||
|
||||
fsck_options_init(&fsck_options, the_repository, FSCK_OPTIONS_MISSING_GITMODULES);
|
||||
if (get_pack(args, fd, pack_lockfiles, NULL, sought, nr_sought,
|
||||
&fsck_options.gitmodules_found))
|
||||
die(_("git fetch-pack: fetch failed."));
|
||||
@@ -1231,6 +1233,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
|
||||
die("fsck failed");
|
||||
|
||||
all_done:
|
||||
fsck_options_clear(&fsck_options);
|
||||
if (negotiator)
|
||||
negotiator->release(negotiator);
|
||||
return ref;
|
||||
@@ -1650,6 +1653,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
|
||||
struct string_list *pack_lockfiles)
|
||||
{
|
||||
struct repository *r = the_repository;
|
||||
struct fsck_options fsck_options;
|
||||
struct ref *ref = copy_ref_list(orig_ref);
|
||||
enum fetch_state state = FETCH_CHECK_LOCAL;
|
||||
struct oidset common = OIDSET_INIT;
|
||||
@@ -1667,6 +1671,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
|
||||
struct strvec index_pack_args = STRVEC_INIT;
|
||||
const char *promisor_remote_config;
|
||||
|
||||
fsck_options_init(&fsck_options, the_repository, FSCK_OPTIONS_MISSING_GITMODULES);
|
||||
|
||||
if (server_feature_v2("promisor-remote", &promisor_remote_config))
|
||||
promisor_remote_reply(promisor_remote_config, NULL);
|
||||
|
||||
@@ -1878,6 +1884,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
|
||||
if (negotiator)
|
||||
negotiator->release(negotiator);
|
||||
|
||||
fsck_options_clear(&fsck_options);
|
||||
oidset_clear(&common);
|
||||
return ref;
|
||||
}
|
||||
|
||||
76
fsck.c
76
fsck.c
@@ -1,5 +1,3 @@
|
||||
#define USE_THE_REPOSITORY_VARIABLE
|
||||
|
||||
#include "git-compat-util.h"
|
||||
#include "date.h"
|
||||
#include "dir.h"
|
||||
@@ -207,7 +205,7 @@ void fsck_set_msg_types(struct fsck_options *options, const char *values)
|
||||
if (equal == len)
|
||||
die("skiplist requires a path");
|
||||
oidset_parse_file(&options->skip_oids, buf + equal + 1,
|
||||
the_repository->hash_algo);
|
||||
options->repo->hash_algo);
|
||||
buf += len + 1;
|
||||
continue;
|
||||
}
|
||||
@@ -360,7 +358,7 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
|
||||
int res = 0;
|
||||
const char *name;
|
||||
|
||||
if (repo_parse_tree(the_repository, tree))
|
||||
if (repo_parse_tree(options->repo, tree))
|
||||
return -1;
|
||||
|
||||
name = fsck_get_object_name(options, &tree->object.oid);
|
||||
@@ -375,14 +373,14 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
|
||||
continue;
|
||||
|
||||
if (S_ISDIR(entry.mode)) {
|
||||
obj = (struct object *)lookup_tree(the_repository, &entry.oid);
|
||||
obj = (struct object *)lookup_tree(options->repo, &entry.oid);
|
||||
if (name && obj)
|
||||
fsck_put_object_name(options, &entry.oid, "%s%s/",
|
||||
name, entry.path);
|
||||
result = 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);
|
||||
obj = (struct object *)lookup_blob(options->repo, &entry.oid);
|
||||
if (name && obj)
|
||||
fsck_put_object_name(options, &entry.oid, "%s%s",
|
||||
name, entry.path);
|
||||
@@ -409,7 +407,7 @@ static int fsck_walk_commit(struct commit *commit, void *data, struct fsck_optio
|
||||
int result;
|
||||
const char *name;
|
||||
|
||||
if (repo_parse_commit(the_repository, commit))
|
||||
if (repo_parse_commit(options->repo, commit))
|
||||
return -1;
|
||||
|
||||
name = fsck_get_object_name(options, &commit->object.oid);
|
||||
@@ -417,7 +415,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->walk((struct object *) repo_get_commit_tree(options->repo, commit),
|
||||
OBJ_TREE, data, options);
|
||||
if (result < 0)
|
||||
return result;
|
||||
@@ -474,7 +472,7 @@ static int fsck_walk_tag(struct tag *tag, void *data, struct fsck_options *optio
|
||||
{
|
||||
const char *name = fsck_get_object_name(options, &tag->object.oid);
|
||||
|
||||
if (parse_tag(the_repository, tag))
|
||||
if (parse_tag(options->repo, tag))
|
||||
return -1;
|
||||
if (name)
|
||||
fsck_put_object_name(options, &tag->tagged->oid, "%s", name);
|
||||
@@ -487,7 +485,7 @@ int fsck_walk(struct object *obj, void *data, struct fsck_options *options)
|
||||
return -1;
|
||||
|
||||
if (obj->type == OBJ_NONE)
|
||||
parse_object(the_repository, &obj->oid);
|
||||
parse_object(options->repo, &obj->oid);
|
||||
|
||||
switch (obj->type) {
|
||||
case OBJ_BLOB:
|
||||
@@ -970,14 +968,14 @@ static int fsck_commit(const struct object_id *oid,
|
||||
|
||||
if (buffer >= buffer_end || !skip_prefix(buffer, "tree ", &buffer))
|
||||
return report(options, oid, OBJ_COMMIT, FSCK_MSG_MISSING_TREE, "invalid format - expected 'tree' line");
|
||||
if (parse_oid_hex(buffer, &tree_oid, &p) || *p != '\n') {
|
||||
if (parse_oid_hex_algop(buffer, &tree_oid, &p, options->repo->hash_algo) || *p != '\n') {
|
||||
err = report(options, oid, OBJ_COMMIT, FSCK_MSG_BAD_TREE_SHA1, "invalid 'tree' line format - bad sha1");
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
buffer = p + 1;
|
||||
while (buffer < buffer_end && skip_prefix(buffer, "parent ", &buffer)) {
|
||||
if (parse_oid_hex(buffer, &parent_oid, &p) || *p != '\n') {
|
||||
if (parse_oid_hex_algop(buffer, &parent_oid, &p, options->repo->hash_algo) || *p != '\n') {
|
||||
err = report(options, oid, OBJ_COMMIT, FSCK_MSG_BAD_PARENT_SHA1, "invalid 'parent' line format - bad sha1");
|
||||
if (err)
|
||||
return err;
|
||||
@@ -1044,7 +1042,7 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
|
||||
ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line");
|
||||
goto done;
|
||||
}
|
||||
if (parse_oid_hex(buffer, tagged_oid, &p) || *p != '\n') {
|
||||
if (parse_oid_hex_algop(buffer, tagged_oid, &p, options->repo->hash_algo) || *p != '\n') {
|
||||
ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1");
|
||||
if (ret)
|
||||
goto done;
|
||||
@@ -1336,9 +1334,9 @@ static int fsck_blobs(struct oidset *blobs_found, struct oidset *blobs_done,
|
||||
if (oidset_contains(blobs_done, oid))
|
||||
continue;
|
||||
|
||||
buf = odb_read_object(the_repository->objects, oid, &type, &size);
|
||||
buf = odb_read_object(options->repo->objects, oid, &type, &size);
|
||||
if (!buf) {
|
||||
if (is_promisor_object(the_repository, oid))
|
||||
if (is_promisor_object(options->repo, oid))
|
||||
continue;
|
||||
ret |= report(options,
|
||||
oid, OBJ_BLOB, msg_missing,
|
||||
@@ -1380,6 +1378,54 @@ bool fsck_has_queued_checks(struct fsck_options *options)
|
||||
!oidset_equal(&options->gitattributes_found, &options->gitattributes_done);
|
||||
}
|
||||
|
||||
void fsck_options_init(struct fsck_options *options,
|
||||
struct repository *repo,
|
||||
enum fsck_options_type type)
|
||||
{
|
||||
static const struct fsck_options defaults[] = {
|
||||
[FSCK_OPTIONS_DEFAULT] = {
|
||||
.skip_oids = OIDSET_INIT,
|
||||
.gitmodules_found = OIDSET_INIT,
|
||||
.gitmodules_done = OIDSET_INIT,
|
||||
.gitattributes_found = OIDSET_INIT,
|
||||
.gitattributes_done = OIDSET_INIT,
|
||||
.error_func = fsck_objects_error_function
|
||||
},
|
||||
[FSCK_OPTIONS_STRICT] = {
|
||||
.strict = 1,
|
||||
.gitmodules_found = OIDSET_INIT,
|
||||
.gitmodules_done = OIDSET_INIT,
|
||||
.gitattributes_found = OIDSET_INIT,
|
||||
.gitattributes_done = OIDSET_INIT,
|
||||
.error_func = fsck_objects_error_function,
|
||||
},
|
||||
[FSCK_OPTIONS_MISSING_GITMODULES] = {
|
||||
.strict = 1,
|
||||
.gitmodules_found = OIDSET_INIT,
|
||||
.gitmodules_done = OIDSET_INIT,
|
||||
.gitattributes_found = OIDSET_INIT,
|
||||
.gitattributes_done = OIDSET_INIT,
|
||||
.error_func = fsck_objects_error_cb_print_missing_gitmodules,
|
||||
},
|
||||
[FSCK_OPTIONS_REFS] = {
|
||||
.error_func = fsck_refs_error_function,
|
||||
},
|
||||
};
|
||||
|
||||
switch (type) {
|
||||
case FSCK_OPTIONS_DEFAULT:
|
||||
case FSCK_OPTIONS_STRICT:
|
||||
case FSCK_OPTIONS_MISSING_GITMODULES:
|
||||
case FSCK_OPTIONS_REFS:
|
||||
memcpy(options, &defaults[type], sizeof(*options));
|
||||
break;
|
||||
default:
|
||||
BUG("unknown fsck options type %d", type);
|
||||
}
|
||||
|
||||
options->repo = repo;
|
||||
}
|
||||
|
||||
void fsck_options_clear(struct fsck_options *options)
|
||||
{
|
||||
free(options->msg_type);
|
||||
|
||||
42
fsck.h
42
fsck.h
@@ -166,7 +166,10 @@ struct fsck_ref_report {
|
||||
const char *path;
|
||||
};
|
||||
|
||||
struct repository;
|
||||
|
||||
struct fsck_options {
|
||||
struct repository *repo;
|
||||
fsck_walk_func walk;
|
||||
fsck_error error_func;
|
||||
unsigned strict;
|
||||
@@ -180,34 +183,6 @@ struct fsck_options {
|
||||
kh_oid_map_t *object_names;
|
||||
};
|
||||
|
||||
#define FSCK_OPTIONS_DEFAULT { \
|
||||
.skip_oids = OIDSET_INIT, \
|
||||
.gitmodules_found = OIDSET_INIT, \
|
||||
.gitmodules_done = OIDSET_INIT, \
|
||||
.gitattributes_found = OIDSET_INIT, \
|
||||
.gitattributes_done = OIDSET_INIT, \
|
||||
.error_func = fsck_objects_error_function \
|
||||
}
|
||||
#define FSCK_OPTIONS_STRICT { \
|
||||
.strict = 1, \
|
||||
.gitmodules_found = OIDSET_INIT, \
|
||||
.gitmodules_done = OIDSET_INIT, \
|
||||
.gitattributes_found = OIDSET_INIT, \
|
||||
.gitattributes_done = OIDSET_INIT, \
|
||||
.error_func = fsck_objects_error_function, \
|
||||
}
|
||||
#define FSCK_OPTIONS_MISSING_GITMODULES { \
|
||||
.strict = 1, \
|
||||
.gitmodules_found = OIDSET_INIT, \
|
||||
.gitmodules_done = OIDSET_INIT, \
|
||||
.gitattributes_found = OIDSET_INIT, \
|
||||
.gitattributes_done = OIDSET_INIT, \
|
||||
.error_func = fsck_objects_error_cb_print_missing_gitmodules, \
|
||||
}
|
||||
#define FSCK_REFS_OPTIONS_DEFAULT { \
|
||||
.error_func = fsck_refs_error_function, \
|
||||
}
|
||||
|
||||
/* descend in all linked child objects
|
||||
* the return value is:
|
||||
* -1 error in processing the object
|
||||
@@ -255,6 +230,17 @@ int fsck_finish(struct fsck_options *options);
|
||||
*/
|
||||
bool fsck_has_queued_checks(struct fsck_options *options);
|
||||
|
||||
enum fsck_options_type {
|
||||
FSCK_OPTIONS_DEFAULT,
|
||||
FSCK_OPTIONS_STRICT,
|
||||
FSCK_OPTIONS_MISSING_GITMODULES,
|
||||
FSCK_OPTIONS_REFS,
|
||||
};
|
||||
|
||||
void fsck_options_init(struct fsck_options *options,
|
||||
struct repository *repo,
|
||||
enum fsck_options_type type);
|
||||
|
||||
/*
|
||||
* Clear the fsck_options struct, freeing any allocated memory.
|
||||
*/
|
||||
|
||||
@@ -1282,8 +1282,9 @@ static int index_mem(struct index_state *istate,
|
||||
}
|
||||
}
|
||||
if (flags & INDEX_FORMAT_CHECK) {
|
||||
struct fsck_options opts = FSCK_OPTIONS_DEFAULT;
|
||||
struct fsck_options opts;
|
||||
|
||||
fsck_options_init(&opts, the_repository, FSCK_OPTIONS_DEFAULT);
|
||||
opts.strict = 1;
|
||||
opts.error_func = hash_format_check_report;
|
||||
if (fsck_buffer(null_oid(istate->repo->hash_algo), type, buf, size, &opts))
|
||||
|
||||
@@ -53,6 +53,7 @@ static int verify_packfile(struct repository *r,
|
||||
struct packed_git *p,
|
||||
struct pack_window **w_curs,
|
||||
verify_fn fn,
|
||||
void *fn_data,
|
||||
struct progress *progress, uint32_t base_count)
|
||||
|
||||
{
|
||||
@@ -161,7 +162,7 @@ static int verify_packfile(struct repository *r,
|
||||
oid_to_hex(&oid), p->pack_name);
|
||||
else if (fn) {
|
||||
int eaten = 0;
|
||||
err |= fn(&oid, type, size, data, &eaten);
|
||||
err |= fn(&oid, type, size, data, &eaten, fn_data);
|
||||
if (eaten)
|
||||
data = NULL;
|
||||
}
|
||||
@@ -192,7 +193,7 @@ int verify_pack_index(struct packed_git *p)
|
||||
return err;
|
||||
}
|
||||
|
||||
int verify_pack(struct repository *r, struct packed_git *p, verify_fn fn,
|
||||
int verify_pack(struct repository *r, struct packed_git *p, verify_fn fn, void *fn_data,
|
||||
struct progress *progress, uint32_t base_count)
|
||||
{
|
||||
int err = 0;
|
||||
@@ -202,7 +203,7 @@ int verify_pack(struct repository *r, struct packed_git *p, verify_fn fn,
|
||||
if (!p->index_data)
|
||||
return -1;
|
||||
|
||||
err |= verify_packfile(r, p, &w_curs, fn, progress, base_count);
|
||||
err |= verify_packfile(r, p, &w_curs, fn, fn_data, progress, base_count);
|
||||
unuse_pack(&w_curs);
|
||||
|
||||
return err;
|
||||
|
||||
9
pack.h
9
pack.h
@@ -85,7 +85,11 @@ struct pack_idx_entry {
|
||||
|
||||
struct progress;
|
||||
/* Note, the data argument could be NULL if object type is blob */
|
||||
typedef int (*verify_fn)(const struct object_id *, enum object_type, unsigned long, void*, int*);
|
||||
typedef int (*verify_fn)(const struct object_id *oid,
|
||||
enum object_type type,
|
||||
unsigned long size,
|
||||
void *buffer, int *eaten,
|
||||
void *fn_data);
|
||||
|
||||
const char *write_idx_file(struct repository *repo,
|
||||
const char *index_name,
|
||||
@@ -95,7 +99,8 @@ const char *write_idx_file(struct repository *repo,
|
||||
const unsigned char *sha1);
|
||||
int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr);
|
||||
int verify_pack_index(struct packed_git *);
|
||||
int verify_pack(struct repository *, struct packed_git *, verify_fn fn, struct progress *, uint32_t);
|
||||
int verify_pack(struct repository *, struct packed_git *, verify_fn fn, void *fn_data,
|
||||
struct progress *, uint32_t);
|
||||
off_t write_pack_header(struct hashfile *f, uint32_t);
|
||||
void fixup_pack_header_footer(const struct git_hash_algo *, int,
|
||||
unsigned char *, const char *, uint32_t,
|
||||
|
||||
Reference in New Issue
Block a user