mirror of
https://github.com/git/git
synced 2024-08-27 19:49:21 +00:00
builtin-fsck: move away from object-refs to fsck_walk
Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
355885d531
commit
271b8d25b2
|
@ -8,6 +8,7 @@
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
#include "cache-tree.h"
|
#include "cache-tree.h"
|
||||||
#include "tree-walk.h"
|
#include "tree-walk.h"
|
||||||
|
#include "fsck.h"
|
||||||
#include "parse-options.h"
|
#include "parse-options.h"
|
||||||
|
|
||||||
#define REACHABLE 0x0001
|
#define REACHABLE 0x0001
|
||||||
|
@ -63,13 +64,73 @@ static int objwarning(struct object *obj, const char *err, ...)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mark_object(struct object *obj, int type, void *data)
|
||||||
|
{
|
||||||
|
struct tree *tree = NULL;
|
||||||
|
struct object *parent = data;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (!obj) {
|
||||||
|
printf("broken link from %7s %s\n",
|
||||||
|
typename(parent->type), sha1_to_hex(parent->sha1));
|
||||||
|
printf("broken link from %7s %s\n",
|
||||||
|
(type == OBJ_ANY ? "unknown" : typename(type)), "unknown");
|
||||||
|
errors_found |= ERROR_REACHABLE;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != OBJ_ANY && obj->type != type)
|
||||||
|
objerror(parent, "wrong object type in link");
|
||||||
|
|
||||||
|
if (obj->flags & REACHABLE)
|
||||||
|
return 0;
|
||||||
|
obj->flags |= REACHABLE;
|
||||||
|
if (!obj->parsed) {
|
||||||
|
if (parent && !has_sha1_file(obj->sha1)) {
|
||||||
|
printf("broken link from %7s %s\n",
|
||||||
|
typename(parent->type), sha1_to_hex(parent->sha1));
|
||||||
|
printf(" to %7s %s\n",
|
||||||
|
typename(obj->type), sha1_to_hex(obj->sha1));
|
||||||
|
errors_found |= ERROR_REACHABLE;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->type == OBJ_TREE) {
|
||||||
|
obj->parsed = 0;
|
||||||
|
tree = (struct tree *)obj;
|
||||||
|
if (parse_tree(tree) < 0)
|
||||||
|
return 1; /* error already displayed */
|
||||||
|
}
|
||||||
|
result = fsck_walk(obj, mark_object, obj);
|
||||||
|
if (tree) {
|
||||||
|
free(tree->buffer);
|
||||||
|
tree->buffer = NULL;
|
||||||
|
}
|
||||||
|
if (result < 0)
|
||||||
|
result = 1;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mark_object_reachable(struct object *obj)
|
||||||
|
{
|
||||||
|
mark_object(obj, OBJ_ANY, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mark_used(struct object *obj, int type, void *data)
|
||||||
|
{
|
||||||
|
if (!obj)
|
||||||
|
return 1;
|
||||||
|
obj->used = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check a single reachable object
|
* Check a single reachable object
|
||||||
*/
|
*/
|
||||||
static void check_reachable_object(struct object *obj)
|
static void check_reachable_object(struct object *obj)
|
||||||
{
|
{
|
||||||
const struct object_refs *refs;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We obviously want the object to be parsed,
|
* We obviously want the object to be parsed,
|
||||||
* except if it was in a pack-file and we didn't
|
* except if it was in a pack-file and we didn't
|
||||||
|
@ -82,25 +143,6 @@ static void check_reachable_object(struct object *obj)
|
||||||
errors_found |= ERROR_REACHABLE;
|
errors_found |= ERROR_REACHABLE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Check that everything that we try to reference is also good.
|
|
||||||
*/
|
|
||||||
refs = lookup_object_refs(obj);
|
|
||||||
if (refs) {
|
|
||||||
unsigned j;
|
|
||||||
for (j = 0; j < refs->count; j++) {
|
|
||||||
struct object *ref = refs->ref[j];
|
|
||||||
if (ref->parsed ||
|
|
||||||
(has_sha1_file(ref->sha1)))
|
|
||||||
continue;
|
|
||||||
printf("broken link from %7s %s\n",
|
|
||||||
typename(obj->type), sha1_to_hex(obj->sha1));
|
|
||||||
printf(" to %7s %s\n",
|
|
||||||
typename(ref->type), sha1_to_hex(ref->sha1));
|
|
||||||
errors_found |= ERROR_REACHABLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -414,6 +456,8 @@ static int fsck_sha1(const unsigned char *sha1)
|
||||||
if (obj->flags & SEEN)
|
if (obj->flags & SEEN)
|
||||||
return 0;
|
return 0;
|
||||||
obj->flags |= SEEN;
|
obj->flags |= SEEN;
|
||||||
|
if (fsck_walk(obj, mark_used, 0))
|
||||||
|
objerror(obj, "broken links");
|
||||||
if (obj->type == OBJ_BLOB)
|
if (obj->type == OBJ_BLOB)
|
||||||
return 0;
|
return 0;
|
||||||
if (obj->type == OBJ_TREE)
|
if (obj->type == OBJ_TREE)
|
||||||
|
@ -538,13 +582,13 @@ static int fsck_handle_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
|
||||||
obj = lookup_object(osha1);
|
obj = lookup_object(osha1);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
obj->used = 1;
|
obj->used = 1;
|
||||||
mark_reachable(obj, REACHABLE);
|
mark_object_reachable(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
obj = lookup_object(nsha1);
|
obj = lookup_object(nsha1);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
obj->used = 1;
|
obj->used = 1;
|
||||||
mark_reachable(obj, REACHABLE);
|
mark_object_reachable(obj);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -574,7 +618,7 @@ static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int f
|
||||||
error("%s: not a commit", refname);
|
error("%s: not a commit", refname);
|
||||||
default_refs++;
|
default_refs++;
|
||||||
obj->used = 1;
|
obj->used = 1;
|
||||||
mark_reachable(obj, REACHABLE);
|
mark_object_reachable(obj);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -660,7 +704,7 @@ static int fsck_cache_tree(struct cache_tree *it)
|
||||||
sha1_to_hex(it->sha1));
|
sha1_to_hex(it->sha1));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
mark_reachable(obj, REACHABLE);
|
mark_object_reachable(obj);
|
||||||
obj->used = 1;
|
obj->used = 1;
|
||||||
if (obj->type != OBJ_TREE)
|
if (obj->type != OBJ_TREE)
|
||||||
err |= objerror(obj, "non-tree in cache-tree");
|
err |= objerror(obj, "non-tree in cache-tree");
|
||||||
|
@ -693,7 +737,6 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i, heads;
|
int i, heads;
|
||||||
|
|
||||||
track_object_refs = 1;
|
|
||||||
errors_found = 0;
|
errors_found = 0;
|
||||||
|
|
||||||
argc = parse_options(argc, argv, fsck_opts, fsck_usage, 0);
|
argc = parse_options(argc, argv, fsck_opts, fsck_usage, 0);
|
||||||
|
@ -741,7 +784,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
obj->used = 1;
|
obj->used = 1;
|
||||||
mark_reachable(obj, REACHABLE);
|
mark_object_reachable(obj);
|
||||||
heads++;
|
heads++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -773,7 +816,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
|
||||||
continue;
|
continue;
|
||||||
obj = &blob->object;
|
obj = &blob->object;
|
||||||
obj->used = 1;
|
obj->used = 1;
|
||||||
mark_reachable(obj, REACHABLE);
|
mark_object_reachable(obj);
|
||||||
}
|
}
|
||||||
if (active_cache_tree)
|
if (active_cache_tree)
|
||||||
fsck_cache_tree(active_cache_tree);
|
fsck_cache_tree(active_cache_tree);
|
||||||
|
|
Loading…
Reference in a new issue