builtin / fsck.con commit submodule: port submodule subcommand 'status' from shell to C (a9f8a37)
   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"
  18#include "packfile.h"
  19
  20#define REACHABLE 0x0001
  21#define SEEN      0x0002
  22#define HAS_OBJ   0x0004
  23/* This flag is set if something points to this object. */
  24#define USED      0x0008
  25
  26static int show_root;
  27static int show_tags;
  28static int show_unreachable;
  29static int include_reflogs = 1;
  30static int check_full = 1;
  31static int connectivity_only;
  32static int check_strict;
  33static int keep_cache_objects;
  34static struct fsck_options fsck_walk_options = FSCK_OPTIONS_DEFAULT;
  35static struct fsck_options fsck_obj_options = FSCK_OPTIONS_DEFAULT;
  36static struct object_id head_oid;
  37static const char *head_points_at;
  38static int errors_found;
  39static int write_lost_and_found;
  40static int verbose;
  41static int show_progress = -1;
  42static int show_dangling = 1;
  43static int name_objects;
  44#define ERROR_OBJECT 01
  45#define ERROR_REACHABLE 02
  46#define ERROR_PACK 04
  47#define ERROR_REFS 010
  48
  49static const char *describe_object(struct object *obj)
  50{
  51        static struct strbuf buf = STRBUF_INIT;
  52        char *name = name_objects ?
  53                lookup_decoration(fsck_walk_options.object_names, obj) : NULL;
  54
  55        strbuf_reset(&buf);
  56        strbuf_addstr(&buf, oid_to_hex(&obj->oid));
  57        if (name)
  58                strbuf_addf(&buf, " (%s)", name);
  59
  60        return buf.buf;
  61}
  62
  63static const char *printable_type(struct object *obj)
  64{
  65        const char *ret;
  66
  67        if (obj->type == OBJ_NONE) {
  68                enum object_type type = sha1_object_info(obj->oid.hash, NULL);
  69                if (type > 0)
  70                        object_as_type(obj, type, 0);
  71        }
  72
  73        ret = typename(obj->type);
  74        if (!ret)
  75                ret = "unknown";
  76
  77        return ret;
  78}
  79
  80static int fsck_config(const char *var, const char *value, void *cb)
  81{
  82        if (strcmp(var, "fsck.skiplist") == 0) {
  83                const char *path;
  84                struct strbuf sb = STRBUF_INIT;
  85
  86                if (git_config_pathname(&path, var, value))
  87                        return 1;
  88                strbuf_addf(&sb, "skiplist=%s", path);
  89                free((char *)path);
  90                fsck_set_msg_types(&fsck_obj_options, sb.buf);
  91                strbuf_release(&sb);
  92                return 0;
  93        }
  94
  95        if (skip_prefix(var, "fsck.", &var)) {
  96                fsck_set_msg_type(&fsck_obj_options, var, value);
  97                return 0;
  98        }
  99
 100        return git_default_config(var, value, cb);
 101}
 102
 103static void objreport(struct object *obj, const char *msg_type,
 104                        const char *err)
 105{
 106        fprintf(stderr, "%s in %s %s: %s\n",
 107                msg_type, printable_type(obj), describe_object(obj), err);
 108}
 109
 110static int objerror(struct object *obj, const char *err)
 111{
 112        errors_found |= ERROR_OBJECT;
 113        objreport(obj, "error", err);
 114        return -1;
 115}
 116
 117static int fsck_error_func(struct fsck_options *o,
 118        struct object *obj, int type, const char *message)
 119{
 120        objreport(obj, (type == FSCK_WARN) ? "warning" : "error", message);
 121        return (type == FSCK_WARN) ? 0 : 1;
 122}
 123
 124static struct object_array pending;
 125
 126static int mark_object(struct object *obj, int type, void *data, struct fsck_options *options)
 127{
 128        struct object *parent = data;
 129
 130        /*
 131         * The only case data is NULL or type is OBJ_ANY is when
 132         * mark_object_reachable() calls us.  All the callers of
 133         * that function has non-NULL obj hence ...
 134         */
 135        if (!obj) {
 136                /* ... these references to parent->fld are safe here */
 137                printf("broken link from %7s %s\n",
 138                           printable_type(parent), describe_object(parent));
 139                printf("broken link from %7s %s\n",
 140                           (type == OBJ_ANY ? "unknown" : typename(type)), "unknown");
 141                errors_found |= ERROR_REACHABLE;
 142                return 1;
 143        }
 144
 145        if (type != OBJ_ANY && obj->type != type)
 146                /* ... and the reference to parent is safe here */
 147                objerror(parent, "wrong object type in link");
 148
 149        if (obj->flags & REACHABLE)
 150                return 0;
 151        obj->flags |= REACHABLE;
 152        if (!(obj->flags & HAS_OBJ)) {
 153                if (parent && !has_object_file(&obj->oid)) {
 154                        printf("broken link from %7s %s\n",
 155                                 printable_type(parent), describe_object(parent));
 156                        printf("              to %7s %s\n",
 157                                 printable_type(obj), describe_object(obj));
 158                        errors_found |= ERROR_REACHABLE;
 159                }
 160                return 1;
 161        }
 162
 163        add_object_array(obj, NULL, &pending);
 164        return 0;
 165}
 166
 167static void mark_object_reachable(struct object *obj)
 168{
 169        mark_object(obj, OBJ_ANY, NULL, NULL);
 170}
 171
 172static int traverse_one_object(struct object *obj)
 173{
 174        return fsck_walk(obj, obj, &fsck_walk_options);
 175}
 176
 177static int traverse_reachable(void)
 178{
 179        struct progress *progress = NULL;
 180        unsigned int nr = 0;
 181        int result = 0;
 182        if (show_progress)
 183                progress = start_delayed_progress(_("Checking connectivity"), 0);
 184        while (pending.nr) {
 185                struct object_array_entry *entry;
 186                struct object *obj;
 187
 188                entry = pending.objects + --pending.nr;
 189                obj = entry->item;
 190                result |= traverse_one_object(obj);
 191                display_progress(progress, ++nr);
 192        }
 193        stop_progress(&progress);
 194        return !!result;
 195}
 196
 197static int mark_used(struct object *obj, int type, void *data, struct fsck_options *options)
 198{
 199        if (!obj)
 200                return 1;
 201        obj->flags |= USED;
 202        return 0;
 203}
 204
 205/*
 206 * Check a single reachable object
 207 */
 208static void check_reachable_object(struct object *obj)
 209{
 210        /*
 211         * We obviously want the object to be parsed,
 212         * except if it was in a pack-file and we didn't
 213         * do a full fsck
 214         */
 215        if (!(obj->flags & HAS_OBJ)) {
 216                if (has_sha1_pack(obj->oid.hash))
 217                        return; /* it is in pack - forget about it */
 218                printf("missing %s %s\n", printable_type(obj),
 219                        describe_object(obj));
 220                errors_found |= ERROR_REACHABLE;
 221                return;
 222        }
 223}
 224
 225/*
 226 * Check a single unreachable object
 227 */
 228static void check_unreachable_object(struct object *obj)
 229{
 230        /*
 231         * Missing unreachable object? Ignore it. It's not like
 232         * we miss it (since it can't be reached), nor do we want
 233         * to complain about it being unreachable (since it does
 234         * not exist).
 235         */
 236        if (!(obj->flags & HAS_OBJ))
 237                return;
 238
 239        /*
 240         * Unreachable object that exists? Show it if asked to,
 241         * since this is something that is prunable.
 242         */
 243        if (show_unreachable) {
 244                printf("unreachable %s %s\n", printable_type(obj),
 245                        describe_object(obj));
 246                return;
 247        }
 248
 249        /*
 250         * "!USED" means that nothing at all points to it, including
 251         * other unreachable objects. In other words, it's the "tip"
 252         * of some set of unreachable objects, usually a commit that
 253         * got dropped.
 254         *
 255         * Such starting points are more interesting than some random
 256         * set of unreachable objects, so we show them even if the user
 257         * hasn't asked for _all_ unreachable objects. If you have
 258         * deleted a branch by mistake, this is a prime candidate to
 259         * start looking at, for example.
 260         */
 261        if (!(obj->flags & USED)) {
 262                if (show_dangling)
 263                        printf("dangling %s %s\n", printable_type(obj),
 264                               describe_object(obj));
 265                if (write_lost_and_found) {
 266                        char *filename = git_pathdup("lost-found/%s/%s",
 267                                obj->type == OBJ_COMMIT ? "commit" : "other",
 268                                describe_object(obj));
 269                        FILE *f;
 270
 271                        if (safe_create_leading_directories_const(filename)) {
 272                                error("Could not create lost-found");
 273                                free(filename);
 274                                return;
 275                        }
 276                        f = xfopen(filename, "w");
 277                        if (obj->type == OBJ_BLOB) {
 278                                if (stream_blob_to_fd(fileno(f), &obj->oid, NULL, 1))
 279                                        die_errno("Could not write '%s'", filename);
 280                        } else
 281                                fprintf(f, "%s\n", describe_object(obj));
 282                        if (fclose(f))
 283                                die_errno("Could not finish '%s'",
 284                                          filename);
 285                        free(filename);
 286                }
 287                return;
 288        }
 289
 290        /*
 291         * Otherwise? It's there, it's unreachable, and some other unreachable
 292         * object points to it. Ignore it - it's not interesting, and we showed
 293         * all the interesting cases above.
 294         */
 295}
 296
 297static void check_object(struct object *obj)
 298{
 299        if (verbose)
 300                fprintf(stderr, "Checking %s\n", describe_object(obj));
 301
 302        if (obj->flags & REACHABLE)
 303                check_reachable_object(obj);
 304        else
 305                check_unreachable_object(obj);
 306}
 307
 308static void check_connectivity(void)
 309{
 310        int i, max;
 311
 312        /* Traverse the pending reachable objects */
 313        traverse_reachable();
 314
 315        /* Look up all the requirements, warn about missing objects.. */
 316        max = get_max_object_index();
 317        if (verbose)
 318                fprintf(stderr, "Checking connectivity (%d objects)\n", max);
 319
 320        for (i = 0; i < max; i++) {
 321                struct object *obj = get_indexed_object(i);
 322
 323                if (obj)
 324                        check_object(obj);
 325        }
 326}
 327
 328static int fsck_obj(struct object *obj)
 329{
 330        int err;
 331
 332        if (obj->flags & SEEN)
 333                return 0;
 334        obj->flags |= SEEN;
 335
 336        if (verbose)
 337                fprintf(stderr, "Checking %s %s\n",
 338                        printable_type(obj), describe_object(obj));
 339
 340        if (fsck_walk(obj, NULL, &fsck_obj_options))
 341                objerror(obj, "broken links");
 342        err = fsck_object(obj, NULL, 0, &fsck_obj_options);
 343        if (err)
 344                goto out;
 345
 346        if (obj->type == OBJ_COMMIT) {
 347                struct commit *commit = (struct commit *) obj;
 348
 349                if (!commit->parents && show_root)
 350                        printf("root %s\n", describe_object(&commit->object));
 351        }
 352
 353        if (obj->type == OBJ_TAG) {
 354                struct tag *tag = (struct tag *) obj;
 355
 356                if (show_tags && tag->tagged) {
 357                        printf("tagged %s %s", printable_type(tag->tagged),
 358                                describe_object(tag->tagged));
 359                        printf(" (%s) in %s\n", tag->tag,
 360                                describe_object(&tag->object));
 361                }
 362        }
 363
 364out:
 365        if (obj->type == OBJ_TREE)
 366                free_tree_buffer((struct tree *)obj);
 367        if (obj->type == OBJ_COMMIT)
 368                free_commit_buffer((struct commit *)obj);
 369        return err;
 370}
 371
 372static int fsck_obj_buffer(const struct object_id *oid, enum object_type type,
 373                           unsigned long size, void *buffer, int *eaten)
 374{
 375        /*
 376         * Note, buffer may be NULL if type is OBJ_BLOB. See
 377         * verify_packfile(), data_valid variable for details.
 378         */
 379        struct object *obj;
 380        obj = parse_object_buffer(oid, type, size, buffer, eaten);
 381        if (!obj) {
 382                errors_found |= ERROR_OBJECT;
 383                return error("%s: object corrupt or missing", oid_to_hex(oid));
 384        }
 385        obj->flags &= ~(REACHABLE | SEEN);
 386        obj->flags |= HAS_OBJ;
 387        return fsck_obj(obj);
 388}
 389
 390static int default_refs;
 391
 392static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
 393        timestamp_t timestamp)
 394{
 395        struct object *obj;
 396
 397        if (!is_null_oid(oid)) {
 398                obj = lookup_object(oid->hash);
 399                if (obj && (obj->flags & HAS_OBJ)) {
 400                        if (timestamp && name_objects)
 401                                add_decoration(fsck_walk_options.object_names,
 402                                        obj,
 403                                        xstrfmt("%s@{%"PRItime"}", refname, timestamp));
 404                        obj->flags |= USED;
 405                        mark_object_reachable(obj);
 406                } else {
 407                        error("%s: invalid reflog entry %s", refname, oid_to_hex(oid));
 408                        errors_found |= ERROR_REACHABLE;
 409                }
 410        }
 411}
 412
 413static int fsck_handle_reflog_ent(struct object_id *ooid, struct object_id *noid,
 414                const char *email, timestamp_t timestamp, int tz,
 415                const char *message, void *cb_data)
 416{
 417        const char *refname = cb_data;
 418
 419        if (verbose)
 420                fprintf(stderr, "Checking reflog %s->%s\n",
 421                        oid_to_hex(ooid), oid_to_hex(noid));
 422
 423        fsck_handle_reflog_oid(refname, ooid, 0);
 424        fsck_handle_reflog_oid(refname, noid, timestamp);
 425        return 0;
 426}
 427
 428static int fsck_handle_reflog(const char *logname, const struct object_id *oid,
 429                              int flag, void *cb_data)
 430{
 431        for_each_reflog_ent(logname, fsck_handle_reflog_ent, (void *)logname);
 432        return 0;
 433}
 434
 435static int fsck_handle_ref(const char *refname, const struct object_id *oid,
 436                           int flag, void *cb_data)
 437{
 438        struct object *obj;
 439
 440        obj = parse_object(oid);
 441        if (!obj) {
 442                error("%s: invalid sha1 pointer %s", refname, oid_to_hex(oid));
 443                errors_found |= ERROR_REACHABLE;
 444                /* We'll continue with the rest despite the error.. */
 445                return 0;
 446        }
 447        if (obj->type != OBJ_COMMIT && is_branch(refname)) {
 448                error("%s: not a commit", refname);
 449                errors_found |= ERROR_REFS;
 450        }
 451        default_refs++;
 452        obj->flags |= USED;
 453        if (name_objects)
 454                add_decoration(fsck_walk_options.object_names,
 455                        obj, xstrdup(refname));
 456        mark_object_reachable(obj);
 457
 458        return 0;
 459}
 460
 461static void get_default_heads(void)
 462{
 463        if (head_points_at && !is_null_oid(&head_oid))
 464                fsck_handle_ref("HEAD", &head_oid, 0, NULL);
 465        for_each_rawref(fsck_handle_ref, NULL);
 466        if (include_reflogs)
 467                for_each_reflog(fsck_handle_reflog, NULL);
 468
 469        /*
 470         * Not having any default heads isn't really fatal, but
 471         * it does mean that "--unreachable" no longer makes any
 472         * sense (since in this case everything will obviously
 473         * be unreachable by definition.
 474         *
 475         * Showing dangling objects is valid, though (as those
 476         * dangling objects are likely lost heads).
 477         *
 478         * So we just print a warning about it, and clear the
 479         * "show_unreachable" flag.
 480         */
 481        if (!default_refs) {
 482                fprintf(stderr, "notice: No default references\n");
 483                show_unreachable = 0;
 484        }
 485}
 486
 487static struct object *parse_loose_object(const struct object_id *oid,
 488                                         const char *path)
 489{
 490        struct object *obj;
 491        void *contents;
 492        enum object_type type;
 493        unsigned long size;
 494        int eaten;
 495
 496        if (read_loose_object(path, oid->hash, &type, &size, &contents) < 0)
 497                return NULL;
 498
 499        if (!contents && type != OBJ_BLOB)
 500                die("BUG: read_loose_object streamed a non-blob");
 501
 502        obj = parse_object_buffer(oid, type, size, contents, &eaten);
 503
 504        if (!eaten)
 505                free(contents);
 506        return obj;
 507}
 508
 509static int fsck_loose(const struct object_id *oid, const char *path, void *data)
 510{
 511        struct object *obj = parse_loose_object(oid, path);
 512
 513        if (!obj) {
 514                errors_found |= ERROR_OBJECT;
 515                error("%s: object corrupt or missing: %s",
 516                      oid_to_hex(oid), path);
 517                return 0; /* keep checking other objects */
 518        }
 519
 520        obj->flags &= ~(REACHABLE | SEEN);
 521        obj->flags |= HAS_OBJ;
 522        if (fsck_obj(obj))
 523                errors_found |= ERROR_OBJECT;
 524        return 0;
 525}
 526
 527static int fsck_cruft(const char *basename, const char *path, void *data)
 528{
 529        if (!starts_with(basename, "tmp_obj_"))
 530                fprintf(stderr, "bad sha1 file: %s\n", path);
 531        return 0;
 532}
 533
 534static int fsck_subdir(unsigned int nr, const char *path, void *progress)
 535{
 536        display_progress(progress, nr + 1);
 537        return 0;
 538}
 539
 540static void fsck_object_dir(const char *path)
 541{
 542        struct progress *progress = NULL;
 543
 544        if (verbose)
 545                fprintf(stderr, "Checking object directory\n");
 546
 547        if (show_progress)
 548                progress = start_progress(_("Checking object directories"), 256);
 549
 550        for_each_loose_file_in_objdir(path, fsck_loose, fsck_cruft, fsck_subdir,
 551                                      progress);
 552        display_progress(progress, 256);
 553        stop_progress(&progress);
 554}
 555
 556static int fsck_head_link(void)
 557{
 558        int null_is_error = 0;
 559
 560        if (verbose)
 561                fprintf(stderr, "Checking HEAD link\n");
 562
 563        head_points_at = resolve_ref_unsafe("HEAD", 0, head_oid.hash, NULL);
 564        if (!head_points_at) {
 565                errors_found |= ERROR_REFS;
 566                return error("Invalid HEAD");
 567        }
 568        if (!strcmp(head_points_at, "HEAD"))
 569                /* detached HEAD */
 570                null_is_error = 1;
 571        else if (!starts_with(head_points_at, "refs/heads/")) {
 572                errors_found |= ERROR_REFS;
 573                return error("HEAD points to something strange (%s)",
 574                             head_points_at);
 575        }
 576        if (is_null_oid(&head_oid)) {
 577                if (null_is_error) {
 578                        errors_found |= ERROR_REFS;
 579                        return error("HEAD: detached HEAD points at nothing");
 580                }
 581                fprintf(stderr, "notice: HEAD points to an unborn branch (%s)\n",
 582                        head_points_at + 11);
 583        }
 584        return 0;
 585}
 586
 587static int fsck_cache_tree(struct cache_tree *it)
 588{
 589        int i;
 590        int err = 0;
 591
 592        if (verbose)
 593                fprintf(stderr, "Checking cache tree\n");
 594
 595        if (0 <= it->entry_count) {
 596                struct object *obj = parse_object(&it->oid);
 597                if (!obj) {
 598                        error("%s: invalid sha1 pointer in cache-tree",
 599                              oid_to_hex(&it->oid));
 600                        errors_found |= ERROR_REFS;
 601                        return 1;
 602                }
 603                obj->flags |= USED;
 604                if (name_objects)
 605                        add_decoration(fsck_walk_options.object_names,
 606                                obj, xstrdup(":"));
 607                mark_object_reachable(obj);
 608                if (obj->type != OBJ_TREE)
 609                        err |= objerror(obj, "non-tree in cache-tree");
 610        }
 611        for (i = 0; i < it->subtree_nr; i++)
 612                err |= fsck_cache_tree(it->down[i]->cache_tree);
 613        return err;
 614}
 615
 616static void mark_object_for_connectivity(const struct object_id *oid)
 617{
 618        struct object *obj = lookup_unknown_object(oid->hash);
 619        obj->flags |= HAS_OBJ;
 620}
 621
 622static int mark_loose_for_connectivity(const struct object_id *oid,
 623                                       const char *path,
 624                                       void *data)
 625{
 626        mark_object_for_connectivity(oid);
 627        return 0;
 628}
 629
 630static int mark_packed_for_connectivity(const struct object_id *oid,
 631                                        struct packed_git *pack,
 632                                        uint32_t pos,
 633                                        void *data)
 634{
 635        mark_object_for_connectivity(oid);
 636        return 0;
 637}
 638
 639static char const * const fsck_usage[] = {
 640        N_("git fsck [<options>] [<object>...]"),
 641        NULL
 642};
 643
 644static struct option fsck_opts[] = {
 645        OPT__VERBOSE(&verbose, N_("be verbose")),
 646        OPT_BOOL(0, "unreachable", &show_unreachable, N_("show unreachable objects")),
 647        OPT_BOOL(0, "dangling", &show_dangling, N_("show dangling objects")),
 648        OPT_BOOL(0, "tags", &show_tags, N_("report tags")),
 649        OPT_BOOL(0, "root", &show_root, N_("report root nodes")),
 650        OPT_BOOL(0, "cache", &keep_cache_objects, N_("make index objects head nodes")),
 651        OPT_BOOL(0, "reflogs", &include_reflogs, N_("make reflogs head nodes (default)")),
 652        OPT_BOOL(0, "full", &check_full, N_("also consider packs and alternate objects")),
 653        OPT_BOOL(0, "connectivity-only", &connectivity_only, N_("check only connectivity")),
 654        OPT_BOOL(0, "strict", &check_strict, N_("enable more strict checking")),
 655        OPT_BOOL(0, "lost-found", &write_lost_and_found,
 656                                N_("write dangling objects in .git/lost-found")),
 657        OPT_BOOL(0, "progress", &show_progress, N_("show progress")),
 658        OPT_BOOL(0, "name-objects", &name_objects, N_("show verbose names for reachable objects")),
 659        OPT_END(),
 660};
 661
 662int cmd_fsck(int argc, const char **argv, const char *prefix)
 663{
 664        int i;
 665        struct alternate_object_database *alt;
 666
 667        errors_found = 0;
 668        check_replace_refs = 0;
 669
 670        argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0);
 671
 672        fsck_walk_options.walk = mark_object;
 673        fsck_obj_options.walk = mark_used;
 674        fsck_obj_options.error_func = fsck_error_func;
 675        if (check_strict)
 676                fsck_obj_options.strict = 1;
 677
 678        if (show_progress == -1)
 679                show_progress = isatty(2);
 680        if (verbose)
 681                show_progress = 0;
 682
 683        if (write_lost_and_found) {
 684                check_full = 1;
 685                include_reflogs = 0;
 686        }
 687
 688        if (name_objects)
 689                fsck_walk_options.object_names =
 690                        xcalloc(1, sizeof(struct decoration));
 691
 692        git_config(fsck_config, NULL);
 693
 694        fsck_head_link();
 695        if (connectivity_only) {
 696                for_each_loose_object(mark_loose_for_connectivity, NULL, 0);
 697                for_each_packed_object(mark_packed_for_connectivity, NULL, 0);
 698        } else {
 699                fsck_object_dir(get_object_directory());
 700
 701                prepare_alt_odb();
 702                for (alt = alt_odb_list; alt; alt = alt->next)
 703                        fsck_object_dir(alt->path);
 704
 705                if (check_full) {
 706                        struct packed_git *p;
 707                        uint32_t total = 0, count = 0;
 708                        struct progress *progress = NULL;
 709
 710                        prepare_packed_git();
 711
 712                        if (show_progress) {
 713                                for (p = packed_git; p; p = p->next) {
 714                                        if (open_pack_index(p))
 715                                                continue;
 716                                        total += p->num_objects;
 717                                }
 718
 719                                progress = start_progress(_("Checking objects"), total);
 720                        }
 721                        for (p = packed_git; p; p = p->next) {
 722                                /* verify gives error messages itself */
 723                                if (verify_pack(p, fsck_obj_buffer,
 724                                                progress, count))
 725                                        errors_found |= ERROR_PACK;
 726                                count += p->num_objects;
 727                        }
 728                        stop_progress(&progress);
 729                }
 730        }
 731
 732        for (i = 0; i < argc; i++) {
 733                const char *arg = argv[i];
 734                struct object_id oid;
 735                if (!get_oid(arg, &oid)) {
 736                        struct object *obj = lookup_object(oid.hash);
 737
 738                        if (!obj || !(obj->flags & HAS_OBJ)) {
 739                                error("%s: object missing", oid_to_hex(&oid));
 740                                errors_found |= ERROR_OBJECT;
 741                                continue;
 742                        }
 743
 744                        obj->flags |= USED;
 745                        if (name_objects)
 746                                add_decoration(fsck_walk_options.object_names,
 747                                        obj, xstrdup(arg));
 748                        mark_object_reachable(obj);
 749                        continue;
 750                }
 751                error("invalid parameter: expected sha1, got '%s'", arg);
 752                errors_found |= ERROR_OBJECT;
 753        }
 754
 755        /*
 756         * If we've not been given any explicit head information, do the
 757         * default ones from .git/refs. We also consider the index file
 758         * in this case (ie this implies --cache).
 759         */
 760        if (!argc) {
 761                get_default_heads();
 762                keep_cache_objects = 1;
 763        }
 764
 765        if (keep_cache_objects) {
 766                verify_index_checksum = 1;
 767                read_cache();
 768                for (i = 0; i < active_nr; i++) {
 769                        unsigned int mode;
 770                        struct blob *blob;
 771                        struct object *obj;
 772
 773                        mode = active_cache[i]->ce_mode;
 774                        if (S_ISGITLINK(mode))
 775                                continue;
 776                        blob = lookup_blob(&active_cache[i]->oid);
 777                        if (!blob)
 778                                continue;
 779                        obj = &blob->object;
 780                        obj->flags |= USED;
 781                        if (name_objects)
 782                                add_decoration(fsck_walk_options.object_names,
 783                                        obj,
 784                                        xstrfmt(":%s", active_cache[i]->name));
 785                        mark_object_reachable(obj);
 786                }
 787                if (active_cache_tree)
 788                        fsck_cache_tree(active_cache_tree);
 789        }
 790
 791        check_connectivity();
 792        return errors_found;
 793}