fsck: fix leak when traversing trees
[alt-git.git] / builtin / fsck.c
blob5aa4a1b336563313f1e17e57c9049699442a8a63
1 #include "builtin.h"
2 #include "cache.h"
3 #include "config.h"
4 #include "commit.h"
5 #include "tree.h"
6 #include "blob.h"
7 #include "tag.h"
8 #include "refs.h"
9 #include "pack.h"
10 #include "cache-tree.h"
11 #include "tree-walk.h"
12 #include "fsck.h"
13 #include "parse-options.h"
14 #include "dir.h"
15 #include "progress.h"
16 #include "streaming.h"
17 #include "decorate.h"
19 #define REACHABLE 0x0001
20 #define SEEN 0x0002
21 #define HAS_OBJ 0x0004
22 /* This flag is set if something points to this object. */
23 #define USED 0x0008
25 static int show_root;
26 static int show_tags;
27 static int show_unreachable;
28 static int include_reflogs = 1;
29 static int check_full = 1;
30 static int connectivity_only;
31 static int check_strict;
32 static int keep_cache_objects;
33 static struct fsck_options fsck_walk_options = FSCK_OPTIONS_DEFAULT;
34 static struct fsck_options fsck_obj_options = FSCK_OPTIONS_DEFAULT;
35 static struct object_id head_oid;
36 static const char *head_points_at;
37 static int errors_found;
38 static int write_lost_and_found;
39 static int verbose;
40 static int show_progress = -1;
41 static int show_dangling = 1;
42 static int name_objects;
43 #define ERROR_OBJECT 01
44 #define ERROR_REACHABLE 02
45 #define ERROR_PACK 04
46 #define ERROR_REFS 010
48 static const char *describe_object(struct object *obj)
50 static struct strbuf buf = STRBUF_INIT;
51 char *name = name_objects ?
52 lookup_decoration(fsck_walk_options.object_names, obj) : NULL;
54 strbuf_reset(&buf);
55 strbuf_addstr(&buf, oid_to_hex(&obj->oid));
56 if (name)
57 strbuf_addf(&buf, " (%s)", name);
59 return buf.buf;
62 static const char *printable_type(struct object *obj)
64 const char *ret;
66 if (obj->type == OBJ_NONE) {
67 enum object_type type = sha1_object_info(obj->oid.hash, NULL);
68 if (type > 0)
69 object_as_type(obj, type, 0);
72 ret = typename(obj->type);
73 if (!ret)
74 ret = "unknown";
76 return ret;
79 static int fsck_config(const char *var, const char *value, void *cb)
81 if (strcmp(var, "fsck.skiplist") == 0) {
82 const char *path;
83 struct strbuf sb = STRBUF_INIT;
85 if (git_config_pathname(&path, var, value))
86 return 1;
87 strbuf_addf(&sb, "skiplist=%s", path);
88 free((char *)path);
89 fsck_set_msg_types(&fsck_obj_options, sb.buf);
90 strbuf_release(&sb);
91 return 0;
94 if (skip_prefix(var, "fsck.", &var)) {
95 fsck_set_msg_type(&fsck_obj_options, var, value);
96 return 0;
99 return git_default_config(var, value, cb);
102 static void objreport(struct object *obj, const char *msg_type,
103 const char *err)
105 fprintf(stderr, "%s in %s %s: %s\n",
106 msg_type, printable_type(obj), describe_object(obj), err);
109 static int objerror(struct object *obj, const char *err)
111 errors_found |= ERROR_OBJECT;
112 objreport(obj, "error", err);
113 return -1;
116 static int fsck_error_func(struct fsck_options *o,
117 struct object *obj, int type, const char *message)
119 objreport(obj, (type == FSCK_WARN) ? "warning" : "error", message);
120 return (type == FSCK_WARN) ? 0 : 1;
123 static struct object_array pending;
125 static int mark_object(struct object *obj, int type, void *data, struct fsck_options *options)
127 struct object *parent = data;
130 * The only case data is NULL or type is OBJ_ANY is when
131 * mark_object_reachable() calls us. All the callers of
132 * that function has non-NULL obj hence ...
134 if (!obj) {
135 /* ... these references to parent->fld are safe here */
136 printf("broken link from %7s %s\n",
137 printable_type(parent), describe_object(parent));
138 printf("broken link from %7s %s\n",
139 (type == OBJ_ANY ? "unknown" : typename(type)), "unknown");
140 errors_found |= ERROR_REACHABLE;
141 return 1;
144 if (type != OBJ_ANY && obj->type != type)
145 /* ... and the reference to parent is safe here */
146 objerror(parent, "wrong object type in link");
148 if (obj->flags & REACHABLE)
149 return 0;
150 obj->flags |= REACHABLE;
151 if (!(obj->flags & HAS_OBJ)) {
152 if (parent && !has_object_file(&obj->oid)) {
153 printf("broken link from %7s %s\n",
154 printable_type(parent), describe_object(parent));
155 printf(" to %7s %s\n",
156 printable_type(obj), describe_object(obj));
157 errors_found |= ERROR_REACHABLE;
159 return 1;
162 add_object_array(obj, NULL, &pending);
163 return 0;
166 static void mark_object_reachable(struct object *obj)
168 mark_object(obj, OBJ_ANY, NULL, NULL);
171 static int traverse_one_object(struct object *obj)
173 int result = fsck_walk(obj, obj, &fsck_walk_options);
175 if (obj->type == OBJ_TREE) {
176 struct tree *tree = (struct tree *)obj;
177 free_tree_buffer(tree);
179 return result;
182 static int traverse_reachable(void)
184 struct progress *progress = NULL;
185 unsigned int nr = 0;
186 int result = 0;
187 if (show_progress)
188 progress = start_progress_delay(_("Checking connectivity"), 0, 0, 2);
189 while (pending.nr) {
190 struct object_array_entry *entry;
191 struct object *obj;
193 entry = pending.objects + --pending.nr;
194 obj = entry->item;
195 result |= traverse_one_object(obj);
196 display_progress(progress, ++nr);
198 stop_progress(&progress);
199 return !!result;
202 static int mark_used(struct object *obj, int type, void *data, struct fsck_options *options)
204 if (!obj)
205 return 1;
206 obj->flags |= USED;
207 return 0;
211 * Check a single reachable object
213 static void check_reachable_object(struct object *obj)
216 * We obviously want the object to be parsed,
217 * except if it was in a pack-file and we didn't
218 * do a full fsck
220 if (!(obj->flags & HAS_OBJ)) {
221 if (has_sha1_pack(obj->oid.hash))
222 return; /* it is in pack - forget about it */
223 printf("missing %s %s\n", printable_type(obj),
224 describe_object(obj));
225 errors_found |= ERROR_REACHABLE;
226 return;
231 * Check a single unreachable object
233 static void check_unreachable_object(struct object *obj)
236 * Missing unreachable object? Ignore it. It's not like
237 * we miss it (since it can't be reached), nor do we want
238 * to complain about it being unreachable (since it does
239 * not exist).
241 if (!(obj->flags & HAS_OBJ))
242 return;
245 * Unreachable object that exists? Show it if asked to,
246 * since this is something that is prunable.
248 if (show_unreachable) {
249 printf("unreachable %s %s\n", printable_type(obj),
250 describe_object(obj));
251 return;
255 * "!USED" means that nothing at all points to it, including
256 * other unreachable objects. In other words, it's the "tip"
257 * of some set of unreachable objects, usually a commit that
258 * got dropped.
260 * Such starting points are more interesting than some random
261 * set of unreachable objects, so we show them even if the user
262 * hasn't asked for _all_ unreachable objects. If you have
263 * deleted a branch by mistake, this is a prime candidate to
264 * start looking at, for example.
266 if (!(obj->flags & USED)) {
267 if (show_dangling)
268 printf("dangling %s %s\n", printable_type(obj),
269 describe_object(obj));
270 if (write_lost_and_found) {
271 char *filename = git_pathdup("lost-found/%s/%s",
272 obj->type == OBJ_COMMIT ? "commit" : "other",
273 describe_object(obj));
274 FILE *f;
276 if (safe_create_leading_directories_const(filename)) {
277 error("Could not create lost-found");
278 free(filename);
279 return;
281 f = xfopen(filename, "w");
282 if (obj->type == OBJ_BLOB) {
283 if (stream_blob_to_fd(fileno(f), &obj->oid, NULL, 1))
284 die_errno("Could not write '%s'", filename);
285 } else
286 fprintf(f, "%s\n", describe_object(obj));
287 if (fclose(f))
288 die_errno("Could not finish '%s'",
289 filename);
290 free(filename);
292 return;
296 * Otherwise? It's there, it's unreachable, and some other unreachable
297 * object points to it. Ignore it - it's not interesting, and we showed
298 * all the interesting cases above.
302 static void check_object(struct object *obj)
304 if (verbose)
305 fprintf(stderr, "Checking %s\n", describe_object(obj));
307 if (obj->flags & REACHABLE)
308 check_reachable_object(obj);
309 else
310 check_unreachable_object(obj);
313 static void check_connectivity(void)
315 int i, max;
317 /* Traverse the pending reachable objects */
318 traverse_reachable();
320 /* Look up all the requirements, warn about missing objects.. */
321 max = get_max_object_index();
322 if (verbose)
323 fprintf(stderr, "Checking connectivity (%d objects)\n", max);
325 for (i = 0; i < max; i++) {
326 struct object *obj = get_indexed_object(i);
328 if (obj)
329 check_object(obj);
333 static int fsck_obj(struct object *obj)
335 if (obj->flags & SEEN)
336 return 0;
337 obj->flags |= SEEN;
339 if (verbose)
340 fprintf(stderr, "Checking %s %s\n",
341 printable_type(obj), describe_object(obj));
343 if (fsck_walk(obj, NULL, &fsck_obj_options))
344 objerror(obj, "broken links");
345 if (fsck_object(obj, NULL, 0, &fsck_obj_options))
346 return -1;
348 if (obj->type == OBJ_TREE) {
349 struct tree *item = (struct tree *) obj;
351 free_tree_buffer(item);
354 if (obj->type == OBJ_COMMIT) {
355 struct commit *commit = (struct commit *) obj;
357 free_commit_buffer(commit);
359 if (!commit->parents && show_root)
360 printf("root %s\n", describe_object(&commit->object));
363 if (obj->type == OBJ_TAG) {
364 struct tag *tag = (struct tag *) obj;
366 if (show_tags && tag->tagged) {
367 printf("tagged %s %s", printable_type(tag->tagged),
368 describe_object(tag->tagged));
369 printf(" (%s) in %s\n", tag->tag,
370 describe_object(&tag->object));
374 return 0;
377 static int fsck_obj_buffer(const struct object_id *oid, enum object_type type,
378 unsigned long size, void *buffer, int *eaten)
381 * Note, buffer may be NULL if type is OBJ_BLOB. See
382 * verify_packfile(), data_valid variable for details.
384 struct object *obj;
385 obj = parse_object_buffer(oid, type, size, buffer, eaten);
386 if (!obj) {
387 errors_found |= ERROR_OBJECT;
388 return error("%s: object corrupt or missing", oid_to_hex(oid));
390 obj->flags &= ~(REACHABLE | SEEN);
391 obj->flags |= HAS_OBJ;
392 return fsck_obj(obj);
395 static int default_refs;
397 static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
398 timestamp_t timestamp)
400 struct object *obj;
402 if (!is_null_oid(oid)) {
403 obj = lookup_object(oid->hash);
404 if (obj && (obj->flags & HAS_OBJ)) {
405 if (timestamp && name_objects)
406 add_decoration(fsck_walk_options.object_names,
407 obj,
408 xstrfmt("%s@{%"PRItime"}", refname, timestamp));
409 obj->flags |= USED;
410 mark_object_reachable(obj);
411 } else {
412 error("%s: invalid reflog entry %s", refname, oid_to_hex(oid));
413 errors_found |= ERROR_REACHABLE;
418 static int fsck_handle_reflog_ent(struct object_id *ooid, struct object_id *noid,
419 const char *email, timestamp_t timestamp, int tz,
420 const char *message, void *cb_data)
422 const char *refname = cb_data;
424 if (verbose)
425 fprintf(stderr, "Checking reflog %s->%s\n",
426 oid_to_hex(ooid), oid_to_hex(noid));
428 fsck_handle_reflog_oid(refname, ooid, 0);
429 fsck_handle_reflog_oid(refname, noid, timestamp);
430 return 0;
433 static int fsck_handle_reflog(const char *logname, const struct object_id *oid,
434 int flag, void *cb_data)
436 for_each_reflog_ent(logname, fsck_handle_reflog_ent, (void *)logname);
437 return 0;
440 static int fsck_handle_ref(const char *refname, const struct object_id *oid,
441 int flag, void *cb_data)
443 struct object *obj;
445 obj = parse_object(oid);
446 if (!obj) {
447 error("%s: invalid sha1 pointer %s", refname, oid_to_hex(oid));
448 errors_found |= ERROR_REACHABLE;
449 /* We'll continue with the rest despite the error.. */
450 return 0;
452 if (obj->type != OBJ_COMMIT && is_branch(refname)) {
453 error("%s: not a commit", refname);
454 errors_found |= ERROR_REFS;
456 default_refs++;
457 obj->flags |= USED;
458 if (name_objects)
459 add_decoration(fsck_walk_options.object_names,
460 obj, xstrdup(refname));
461 mark_object_reachable(obj);
463 return 0;
466 static void get_default_heads(void)
468 if (head_points_at && !is_null_oid(&head_oid))
469 fsck_handle_ref("HEAD", &head_oid, 0, NULL);
470 for_each_rawref(fsck_handle_ref, NULL);
471 if (include_reflogs)
472 for_each_reflog(fsck_handle_reflog, NULL);
475 * Not having any default heads isn't really fatal, but
476 * it does mean that "--unreachable" no longer makes any
477 * sense (since in this case everything will obviously
478 * be unreachable by definition.
480 * Showing dangling objects is valid, though (as those
481 * dangling objects are likely lost heads).
483 * So we just print a warning about it, and clear the
484 * "show_unreachable" flag.
486 if (!default_refs) {
487 fprintf(stderr, "notice: No default references\n");
488 show_unreachable = 0;
492 static struct object *parse_loose_object(const struct object_id *oid,
493 const char *path)
495 struct object *obj;
496 void *contents;
497 enum object_type type;
498 unsigned long size;
499 int eaten;
501 if (read_loose_object(path, oid->hash, &type, &size, &contents) < 0)
502 return NULL;
504 if (!contents && type != OBJ_BLOB)
505 die("BUG: read_loose_object streamed a non-blob");
507 obj = parse_object_buffer(oid, type, size, contents, &eaten);
509 if (!eaten)
510 free(contents);
511 return obj;
514 static int fsck_loose(const struct object_id *oid, const char *path, void *data)
516 struct object *obj = parse_loose_object(oid, path);
518 if (!obj) {
519 errors_found |= ERROR_OBJECT;
520 error("%s: object corrupt or missing: %s",
521 oid_to_hex(oid), path);
522 return 0; /* keep checking other objects */
525 obj->flags &= ~(REACHABLE | SEEN);
526 obj->flags |= HAS_OBJ;
527 if (fsck_obj(obj))
528 errors_found |= ERROR_OBJECT;
529 return 0;
532 static int fsck_cruft(const char *basename, const char *path, void *data)
534 if (!starts_with(basename, "tmp_obj_"))
535 fprintf(stderr, "bad sha1 file: %s\n", path);
536 return 0;
539 static int fsck_subdir(unsigned int nr, const char *path, void *progress)
541 display_progress(progress, nr + 1);
542 return 0;
545 static void fsck_object_dir(const char *path)
547 struct progress *progress = NULL;
549 if (verbose)
550 fprintf(stderr, "Checking object directory\n");
552 if (show_progress)
553 progress = start_progress(_("Checking object directories"), 256);
555 for_each_loose_file_in_objdir(path, fsck_loose, fsck_cruft, fsck_subdir,
556 progress);
557 display_progress(progress, 256);
558 stop_progress(&progress);
561 static int fsck_head_link(void)
563 int null_is_error = 0;
565 if (verbose)
566 fprintf(stderr, "Checking HEAD link\n");
568 head_points_at = resolve_ref_unsafe("HEAD", 0, head_oid.hash, NULL);
569 if (!head_points_at) {
570 errors_found |= ERROR_REFS;
571 return error("Invalid HEAD");
573 if (!strcmp(head_points_at, "HEAD"))
574 /* detached HEAD */
575 null_is_error = 1;
576 else if (!starts_with(head_points_at, "refs/heads/")) {
577 errors_found |= ERROR_REFS;
578 return error("HEAD points to something strange (%s)",
579 head_points_at);
581 if (is_null_oid(&head_oid)) {
582 if (null_is_error) {
583 errors_found |= ERROR_REFS;
584 return error("HEAD: detached HEAD points at nothing");
586 fprintf(stderr, "notice: HEAD points to an unborn branch (%s)\n",
587 head_points_at + 11);
589 return 0;
592 static int fsck_cache_tree(struct cache_tree *it)
594 int i;
595 int err = 0;
597 if (verbose)
598 fprintf(stderr, "Checking cache tree\n");
600 if (0 <= it->entry_count) {
601 struct object *obj = parse_object(&it->oid);
602 if (!obj) {
603 error("%s: invalid sha1 pointer in cache-tree",
604 oid_to_hex(&it->oid));
605 errors_found |= ERROR_REFS;
606 return 1;
608 obj->flags |= USED;
609 if (name_objects)
610 add_decoration(fsck_walk_options.object_names,
611 obj, xstrdup(":"));
612 mark_object_reachable(obj);
613 if (obj->type != OBJ_TREE)
614 err |= objerror(obj, "non-tree in cache-tree");
616 for (i = 0; i < it->subtree_nr; i++)
617 err |= fsck_cache_tree(it->down[i]->cache_tree);
618 return err;
621 static void mark_object_for_connectivity(const struct object_id *oid)
623 struct object *obj = lookup_unknown_object(oid->hash);
624 obj->flags |= HAS_OBJ;
627 static int mark_loose_for_connectivity(const struct object_id *oid,
628 const char *path,
629 void *data)
631 mark_object_for_connectivity(oid);
632 return 0;
635 static int mark_packed_for_connectivity(const struct object_id *oid,
636 struct packed_git *pack,
637 uint32_t pos,
638 void *data)
640 mark_object_for_connectivity(oid);
641 return 0;
644 static char const * const fsck_usage[] = {
645 N_("git fsck [<options>] [<object>...]"),
646 NULL
649 static struct option fsck_opts[] = {
650 OPT__VERBOSE(&verbose, N_("be verbose")),
651 OPT_BOOL(0, "unreachable", &show_unreachable, N_("show unreachable objects")),
652 OPT_BOOL(0, "dangling", &show_dangling, N_("show dangling objects")),
653 OPT_BOOL(0, "tags", &show_tags, N_("report tags")),
654 OPT_BOOL(0, "root", &show_root, N_("report root nodes")),
655 OPT_BOOL(0, "cache", &keep_cache_objects, N_("make index objects head nodes")),
656 OPT_BOOL(0, "reflogs", &include_reflogs, N_("make reflogs head nodes (default)")),
657 OPT_BOOL(0, "full", &check_full, N_("also consider packs and alternate objects")),
658 OPT_BOOL(0, "connectivity-only", &connectivity_only, N_("check only connectivity")),
659 OPT_BOOL(0, "strict", &check_strict, N_("enable more strict checking")),
660 OPT_BOOL(0, "lost-found", &write_lost_and_found,
661 N_("write dangling objects in .git/lost-found")),
662 OPT_BOOL(0, "progress", &show_progress, N_("show progress")),
663 OPT_BOOL(0, "name-objects", &name_objects, N_("show verbose names for reachable objects")),
664 OPT_END(),
667 int cmd_fsck(int argc, const char **argv, const char *prefix)
669 int i;
670 struct alternate_object_database *alt;
672 errors_found = 0;
673 check_replace_refs = 0;
675 argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0);
677 fsck_walk_options.walk = mark_object;
678 fsck_obj_options.walk = mark_used;
679 fsck_obj_options.error_func = fsck_error_func;
680 if (check_strict)
681 fsck_obj_options.strict = 1;
683 if (show_progress == -1)
684 show_progress = isatty(2);
685 if (verbose)
686 show_progress = 0;
688 if (write_lost_and_found) {
689 check_full = 1;
690 include_reflogs = 0;
693 if (name_objects)
694 fsck_walk_options.object_names =
695 xcalloc(1, sizeof(struct decoration));
697 git_config(fsck_config, NULL);
699 fsck_head_link();
700 if (connectivity_only) {
701 for_each_loose_object(mark_loose_for_connectivity, NULL, 0);
702 for_each_packed_object(mark_packed_for_connectivity, NULL, 0);
703 } else {
704 fsck_object_dir(get_object_directory());
706 prepare_alt_odb();
707 for (alt = alt_odb_list; alt; alt = alt->next)
708 fsck_object_dir(alt->path);
710 if (check_full) {
711 struct packed_git *p;
712 uint32_t total = 0, count = 0;
713 struct progress *progress = NULL;
715 prepare_packed_git();
717 if (show_progress) {
718 for (p = packed_git; p; p = p->next) {
719 if (open_pack_index(p))
720 continue;
721 total += p->num_objects;
724 progress = start_progress(_("Checking objects"), total);
726 for (p = packed_git; p; p = p->next) {
727 /* verify gives error messages itself */
728 if (verify_pack(p, fsck_obj_buffer,
729 progress, count))
730 errors_found |= ERROR_PACK;
731 count += p->num_objects;
733 stop_progress(&progress);
737 for (i = 0; i < argc; i++) {
738 const char *arg = argv[i];
739 unsigned char sha1[20];
740 if (!get_sha1(arg, sha1)) {
741 struct object *obj = lookup_object(sha1);
743 if (!obj || !(obj->flags & HAS_OBJ)) {
744 error("%s: object missing", sha1_to_hex(sha1));
745 errors_found |= ERROR_OBJECT;
746 continue;
749 obj->flags |= USED;
750 if (name_objects)
751 add_decoration(fsck_walk_options.object_names,
752 obj, xstrdup(arg));
753 mark_object_reachable(obj);
754 continue;
756 error("invalid parameter: expected sha1, got '%s'", arg);
757 errors_found |= ERROR_OBJECT;
761 * If we've not been given any explicit head information, do the
762 * default ones from .git/refs. We also consider the index file
763 * in this case (ie this implies --cache).
765 if (!argc) {
766 get_default_heads();
767 keep_cache_objects = 1;
770 if (keep_cache_objects) {
771 verify_index_checksum = 1;
772 read_cache();
773 for (i = 0; i < active_nr; i++) {
774 unsigned int mode;
775 struct blob *blob;
776 struct object *obj;
778 mode = active_cache[i]->ce_mode;
779 if (S_ISGITLINK(mode))
780 continue;
781 blob = lookup_blob(&active_cache[i]->oid);
782 if (!blob)
783 continue;
784 obj = &blob->object;
785 obj->flags |= USED;
786 if (name_objects)
787 add_decoration(fsck_walk_options.object_names,
788 obj,
789 xstrfmt(":%s", active_cache[i]->name));
790 mark_object_reachable(obj);
792 if (active_cache_tree)
793 fsck_cache_tree(active_cache_tree);
796 check_connectivity();
797 return errors_found;