files-backend: add and use files_ref_path()
[gitweb.git] / fsck.c
diff --git a/fsck.c b/fsck.c
index 828c5c6484f6c9f9e0b074674295a62da45308c9..939792752bf39c72cc536f00c21e2af8ed854c3e 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -323,6 +323,19 @@ static void put_object_name(struct fsck_options *options, struct object *obj,
        va_end(ap);
 }
 
+static const char *describe_object(struct fsck_options *o, struct object *obj)
+{
+       static struct strbuf buf = STRBUF_INIT;
+       char *name;
+
+       strbuf_reset(&buf);
+       strbuf_addstr(&buf, oid_to_hex(&obj->oid));
+       if (o->object_names && (name = lookup_decoration(o->object_names, obj)))
+               strbuf_addf(&buf, " (%s)", name);
+
+       return buf.buf;
+}
+
 static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *options)
 {
        struct tree_desc desc;
@@ -334,8 +347,9 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
                return -1;
 
        name = get_object_name(options, &tree->object);
-       init_tree_desc(&desc, tree->buffer, tree->size);
-       while (tree_entry(&desc, &entry)) {
+       if (init_tree_desc_gently(&desc, tree->buffer, tree->size))
+               return -1;
+       while (tree_entry_gently(&desc, &entry)) {
                struct object *obj;
                int result;
 
@@ -358,7 +372,7 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
                }
                else {
                        result = error("in tree %s: entry %s has bad mode %.6o",
-                                       oid_to_hex(&tree->object.oid), entry.path, entry.mode);
+                                       describe_object(options, &tree->object), entry.path, entry.mode);
                }
                if (result < 0)
                        return result;
@@ -444,6 +458,10 @@ int fsck_walk(struct object *obj, void *data, struct fsck_options *options)
 {
        if (!obj)
                return -1;
+
+       if (obj->type == OBJ_NONE)
+               parse_object(obj->oid.hash);
+
        switch (obj->type) {
        case OBJ_BLOB:
                return 0;
@@ -454,7 +472,7 @@ int fsck_walk(struct object *obj, void *data, struct fsck_options *options)
        case OBJ_TAG:
                return fsck_walk_tag((struct tag *)obj, data, options);
        default:
-               error("Unknown object type for %s", oid_to_hex(&obj->oid));
+               error("Unknown object type for %s", describe_object(options, obj));
                return -1;
        }
 }
@@ -507,7 +525,7 @@ static int verify_ordered(unsigned mode1, const char *name1, unsigned mode2, con
 
 static int fsck_tree(struct tree *item, struct fsck_options *options)
 {
-       int retval;
+       int retval = 0;
        int has_null_sha1 = 0;
        int has_full_path = 0;
        int has_empty_name = 0;
@@ -522,7 +540,10 @@ static int fsck_tree(struct tree *item, struct fsck_options *options)
        unsigned o_mode;
        const char *o_name;
 
-       init_tree_desc(&desc, item->buffer, item->size);
+       if (init_tree_desc_gently(&desc, item->buffer, item->size)) {
+               retval += report(options, &item->object, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
+               return retval;
+       }
 
        o_mode = 0;
        o_name = NULL;
@@ -543,7 +564,10 @@ static int fsck_tree(struct tree *item, struct fsck_options *options)
                               is_hfs_dotgit(name) ||
                               is_ntfs_dotgit(name));
                has_zero_pad |= *(char *)desc.buffer == '0';
-               update_tree_entry(&desc);
+               if (update_tree_entry_gently(&desc)) {
+                       retval += report(options, &item->object, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
+                       break;
+               }
 
                switch (mode) {
                /*
@@ -584,7 +608,6 @@ static int fsck_tree(struct tree *item, struct fsck_options *options)
                o_name = name;
        }
 
-       retval = 0;
        if (has_null_sha1)
                retval += report(options, &item->object, FSCK_MSG_NULL_SHA1, "contains entries pointing to null sha1");
        if (has_full_path)
@@ -901,9 +924,9 @@ int fsck_error_function(struct fsck_options *o,
        struct object *obj, int msg_type, const char *message)
 {
        if (msg_type == FSCK_WARN) {
-               warning("object %s: %s", oid_to_hex(&obj->oid), message);
+               warning("object %s: %s", describe_object(o, obj), message);
                return 0;
        }
-       error("object %s: %s", oid_to_hex(&obj->oid), message);
+       error("object %s: %s", describe_object(o, obj), message);
        return 1;
 }