X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=fsck-objects.c;h=5e65df436ba8e4191530ec6f9351d5e069928412;hb=136f2e548a34f1f504b0f062f87ddf33e8d6e83b;hp=17d05363e08b48275cb38631e82f0f48321fa728;hpb=f51248eb482a7a0feacb04d02119c94d35845975;p=git.git diff --git a/fsck-objects.c b/fsck-objects.c index 17d05363..5e65df43 100644 --- a/fsck-objects.c +++ b/fsck-objects.c @@ -8,18 +8,25 @@ #include "tag.h" #include "refs.h" #include "pack.h" +#include "cache-tree.h" #define REACHABLE 0x0001 static int show_root = 0; static int show_tags = 0; static int show_unreachable = 0; -static int standalone = 0; static int check_full = 0; static int check_strict = 0; -static int keep_cache_objects = 0; +static int keep_cache_objects = 0; static unsigned char head_sha1[20]; +#ifdef NO_D_INO_IN_DIRENT +#define SORT_DIRENT 0 +#define DIRENT_SORT_HINT(de) 0 +#else +#define SORT_DIRENT 1 +#define DIRENT_SORT_HINT(de) ((de)->d_ino) +#endif static void objreport(struct object *obj, const char *severity, const char *err, va_list params) @@ -54,12 +61,14 @@ static void check_connectivity(void) int i; /* Look up all the requirements, warn about missing objects.. */ - for (i = 0; i < nr_objs; i++) { + for (i = 0; i < obj_allocs; i++) { struct object *obj = objs[i]; - struct object_list *refs; + + if (!obj) + continue; if (!obj->parsed) { - if (!standalone && has_sha1_file(obj->sha1)) + if (has_sha1_file(obj->sha1)) ; /* it is in pack */ else printf("missing %s %s\n", @@ -67,14 +76,19 @@ static void check_connectivity(void) continue; } - for (refs = obj->refs; refs; refs = refs->next) { - if (refs->item->parsed || - (!standalone && has_sha1_file(refs->item->sha1))) - continue; - printf("broken link from %7s %s\n", - obj->type, sha1_to_hex(obj->sha1)); - printf(" to %7s %s\n", - refs->item->type, sha1_to_hex(refs->item->sha1)); + if (obj->refs) { + const struct object_refs *refs = obj->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", + obj->type, sha1_to_hex(obj->sha1)); + printf(" to %7s %s\n", + ref->type, sha1_to_hex(ref->sha1)); + } } if (show_unreachable && !(obj->flags & REACHABLE)) { @@ -184,10 +198,16 @@ static int fsck_tree(struct tree *item) default: break; } + free(last); } last = entry; } + if (last) + free(last); + item->entries = NULL; + free(item->buffer); + item->buffer = NULL; retval = 0; if (has_full_path) { @@ -296,7 +316,9 @@ static void fsck_sha1_list(void) { int i, nr = sha1_list.nr; - qsort(sha1_list.entry, nr, sizeof(struct sha1_entry *), ino_compare); + if (SORT_DIRENT) + qsort(sha1_list.entry, nr, + sizeof(struct sha1_entry *), ino_compare); for (i = 0; i < nr; i++) { struct sha1_entry *entry = sha1_list.entry[i]; unsigned char *sha1 = entry->sha1; @@ -350,7 +372,7 @@ static int fsck_dir(int i, char *path) memcpy(name+2, de->d_name, len+1); if (get_sha1_hex(name, sha1) < 0) break; - add_sha1_list(sha1, de->d_ino); + add_sha1_list(sha1, DIRENT_SORT_HINT(de)); continue; } fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name); @@ -367,7 +389,7 @@ static int fsck_handle_ref(const char *refname, const unsigned char *sha1) obj = lookup_object(sha1); if (!obj) { - if (!standalone && has_sha1_file(sha1)) { + if (has_sha1_file(sha1)) { default_refs++; return 0; /* it is in a pack */ } @@ -416,10 +438,34 @@ static int fsck_head_link(void) return 0; } +static int fsck_cache_tree(struct cache_tree *it) +{ + int i; + int err = 0; + + if (0 <= it->entry_count) { + struct object *obj = parse_object(it->sha1); + if (!obj) { + error("%s: invalid sha1 pointer in cache-tree", + sha1_to_hex(it->sha1)); + return 1; + } + mark_reachable(obj, REACHABLE); + obj->used = 1; + if (obj->type != tree_type) + err |= objerror(obj, "non-tree in cache-tree"); + } + for (i = 0; i < it->subtree_nr; i++) + err |= fsck_cache_tree(it->down[i]->cache_tree); + return err; +} + int main(int argc, char **argv) { int i, heads; + setup_git_directory(); + for (i = 1; i < argc; i++) { const char *arg = argv[i]; @@ -439,10 +485,6 @@ int main(int argc, char **argv) keep_cache_objects = 1; continue; } - if (!strcmp(arg, "--standalone")) { - standalone = 1; - continue; - } if (!strcmp(arg, "--full")) { check_full = 1; continue; @@ -452,14 +494,9 @@ int main(int argc, char **argv) continue; } if (*arg == '-') - usage("git-fsck-objects [--tags] [--root] [[--unreachable] [--cache] [--standalone | --full] [--strict] *]"); + usage("git-fsck-objects [--tags] [--root] [[--unreachable] [--cache] [--full] [--strict] *]"); } - if (standalone && check_full) - die("Only one of --standalone or --full can be used."); - if (standalone) - putenv("GIT_ALTERNATE_OBJECT_DIRECTORIES="); - fsck_head_link(); fsck_object_dir(get_object_directory()); if (check_full) { @@ -532,6 +569,8 @@ int main(int argc, char **argv) obj->used = 1; mark_reachable(obj, REACHABLE); } + if (active_cache_tree) + fsck_cache_tree(active_cache_tree); } check_connectivity();