diff options
Diffstat (limited to 'builtin/fsck.c')
-rw-r--r-- | builtin/fsck.c | 71 |
1 files changed, 31 insertions, 40 deletions
diff --git a/builtin/fsck.c b/builtin/fsck.c index 99dea7adf6..b0964a8d34 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -19,6 +19,8 @@ #define REACHABLE 0x0001 #define SEEN 0x0002 #define HAS_OBJ 0x0004 +/* This flag is set if something points to this object. */ +#define USED 0x0008 static int show_root; static int show_tags; @@ -168,18 +170,7 @@ static void mark_object_reachable(struct object *obj) static int traverse_one_object(struct object *obj) { - int result; - struct tree *tree = NULL; - - if (obj->type == OBJ_TREE) { - tree = (struct tree *)obj; - if (parse_tree(tree) < 0) - return 1; /* error already displayed */ - } - result = fsck_walk(obj, obj, &fsck_walk_options); - if (tree) - free_tree_buffer(tree); - return result; + return fsck_walk(obj, obj, &fsck_walk_options); } static int traverse_reachable(void) @@ -206,7 +197,7 @@ static int mark_used(struct object *obj, int type, void *data, struct fsck_optio { if (!obj) return 1; - obj->used = 1; + obj->flags |= USED; return 0; } @@ -255,7 +246,7 @@ static void check_unreachable_object(struct object *obj) } /* - * "!used" means that nothing at all points to it, including + * "!USED" means that nothing at all points to it, including * other unreachable objects. In other words, it's the "tip" * of some set of unreachable objects, usually a commit that * got dropped. @@ -266,7 +257,7 @@ static void check_unreachable_object(struct object *obj) * deleted a branch by mistake, this is a prime candidate to * start looking at, for example. */ - if (!obj->used) { + if (!(obj->flags & USED)) { if (show_dangling) printf("dangling %s %s\n", printable_type(obj), describe_object(obj)); @@ -335,6 +326,8 @@ static void check_connectivity(void) static int fsck_obj(struct object *obj) { + int err; + if (obj->flags & SEEN) return 0; obj->flags |= SEEN; @@ -345,20 +338,13 @@ static int fsck_obj(struct object *obj) if (fsck_walk(obj, NULL, &fsck_obj_options)) objerror(obj, "broken links"); - if (fsck_object(obj, NULL, 0, &fsck_obj_options)) - return -1; - - if (obj->type == OBJ_TREE) { - struct tree *item = (struct tree *) obj; - - free_tree_buffer(item); - } + err = fsck_object(obj, NULL, 0, &fsck_obj_options); + if (err) + goto out; if (obj->type == OBJ_COMMIT) { struct commit *commit = (struct commit *) obj; - free_commit_buffer(commit); - if (!commit->parents && show_root) printf("root %s\n", describe_object(&commit->object)); } @@ -374,7 +360,12 @@ static int fsck_obj(struct object *obj) } } - return 0; +out: + if (obj->type == OBJ_TREE) + free_tree_buffer((struct tree *)obj); + if (obj->type == OBJ_COMMIT) + free_commit_buffer((struct commit *)obj); + return err; } static int fsck_obj_buffer(const struct object_id *oid, enum object_type type, @@ -390,7 +381,8 @@ static int fsck_obj_buffer(const struct object_id *oid, enum object_type type, errors_found |= ERROR_OBJECT; return error("%s: object corrupt or missing", oid_to_hex(oid)); } - obj->flags = HAS_OBJ; + obj->flags &= ~(REACHABLE | SEEN); + obj->flags |= HAS_OBJ; return fsck_obj(obj); } @@ -408,7 +400,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid, add_decoration(fsck_walk_options.object_names, obj, xstrfmt("%s@{%"PRItime"}", refname, timestamp)); - obj->used = 1; + obj->flags |= USED; mark_object_reachable(obj); } else { error("%s: invalid reflog entry %s", refname, oid_to_hex(oid)); @@ -456,7 +448,7 @@ static int fsck_handle_ref(const char *refname, const struct object_id *oid, errors_found |= ERROR_REFS; } default_refs++; - obj->used = 1; + obj->flags |= USED; if (name_objects) add_decoration(fsck_walk_options.object_names, obj, xstrdup(refname)); @@ -524,7 +516,8 @@ static int fsck_loose(const struct object_id *oid, const char *path, void *data) return 0; /* keep checking other objects */ } - obj->flags = HAS_OBJ; + obj->flags &= ~(REACHABLE | SEEN); + obj->flags |= HAS_OBJ; if (fsck_obj(obj)) errors_found |= ERROR_OBJECT; return 0; @@ -606,7 +599,7 @@ static int fsck_cache_tree(struct cache_tree *it) errors_found |= ERROR_REFS; return 1; } - obj->used = 1; + obj->flags |= USED; if (name_objects) add_decoration(fsck_walk_options.object_names, obj, xstrdup(":")); @@ -667,7 +660,7 @@ static struct option fsck_opts[] = { int cmd_fsck(int argc, const char **argv, const char *prefix) { - int i, heads; + int i; struct alternate_object_database *alt; errors_found = 0; @@ -735,25 +728,23 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) } } - heads = 0; for (i = 0; i < argc; i++) { const char *arg = argv[i]; - unsigned char sha1[20]; - if (!get_sha1(arg, sha1)) { - struct object *obj = lookup_object(sha1); + struct object_id oid; + if (!get_oid(arg, &oid)) { + struct object *obj = lookup_object(oid.hash); if (!obj || !(obj->flags & HAS_OBJ)) { - error("%s: object missing", sha1_to_hex(sha1)); + error("%s: object missing", oid_to_hex(&oid)); errors_found |= ERROR_OBJECT; continue; } - obj->used = 1; + obj->flags |= USED; if (name_objects) add_decoration(fsck_walk_options.object_names, obj, xstrdup(arg)); mark_object_reachable(obj); - heads++; continue; } error("invalid parameter: expected sha1, got '%s'", arg); @@ -785,7 +776,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) if (!blob) continue; obj = &blob->object; - obj->used = 1; + obj->flags |= USED; if (name_objects) add_decoration(fsck_walk_options.object_names, obj, |