builtin-fsck.con commit Merge branch 'master' of git://repo.or.cz/git-gui (e92ea62)
   1#include "builtin.h"
   2#include "cache.h"
   3#include "commit.h"
   4#include "tree.h"
   5#include "blob.h"
   6#include "tag.h"
   7#include "refs.h"
   8#include "pack.h"
   9#include "cache-tree.h"
  10#include "tree-walk.h"
  11
  12#define REACHABLE 0x0001
  13#define SEEN      0x0002
  14
  15static int show_root;
  16static int show_tags;
  17static int show_unreachable;
  18static int include_reflogs = 1;
  19static int check_full;
  20static int check_strict;
  21static int keep_cache_objects;
  22static unsigned char head_sha1[20];
  23static int errors_found;
  24static int write_lost_and_found;
  25static int verbose;
  26#define ERROR_OBJECT 01
  27#define ERROR_REACHABLE 02
  28
  29#ifdef NO_D_INO_IN_DIRENT
  30#define SORT_DIRENT 0
  31#define DIRENT_SORT_HINT(de) 0
  32#else
  33#define SORT_DIRENT 1
  34#define DIRENT_SORT_HINT(de) ((de)->d_ino)
  35#endif
  36
  37static void objreport(struct object *obj, const char *severity,
  38                      const char *err, va_list params)
  39{
  40        fprintf(stderr, "%s in %s %s: ",
  41                severity, typename(obj->type), sha1_to_hex(obj->sha1));
  42        vfprintf(stderr, err, params);
  43        fputs("\n", stderr);
  44}
  45
  46static int objerror(struct object *obj, const char *err, ...)
  47{
  48        va_list params;
  49        va_start(params, err);
  50        errors_found |= ERROR_OBJECT;
  51        objreport(obj, "error", err, params);
  52        va_end(params);
  53        return -1;
  54}
  55
  56static int objwarning(struct object *obj, const char *err, ...)
  57{
  58        va_list params;
  59        va_start(params, err);
  60        objreport(obj, "warning", err, params);
  61        va_end(params);
  62        return -1;
  63}
  64
  65/*
  66 * Check a single reachable object
  67 */
  68static void check_reachable_object(struct object *obj)
  69{
  70        const struct object_refs *refs;
  71
  72        /*
  73         * We obviously want the object to be parsed,
  74         * except if it was in a pack-file and we didn't
  75         * do a full fsck
  76         */
  77        if (!obj->parsed) {
  78                if (has_sha1_pack(obj->sha1, NULL))
  79                        return; /* it is in pack - forget about it */
  80                printf("missing %s %s\n", typename(obj->type), sha1_to_hex(obj->sha1));
  81                errors_found |= ERROR_REACHABLE;
  82                return;
  83        }
  84
  85        /*
  86         * Check that everything that we try to reference is also good.
  87         */
  88        refs = lookup_object_refs(obj);
  89        if (refs) {
  90                unsigned j;
  91                for (j = 0; j < refs->count; j++) {
  92                        struct object *ref = refs->ref[j];
  93                        if (ref->parsed ||
  94                            (has_sha1_file(ref->sha1)))
  95                                continue;
  96                        printf("broken link from %7s %s\n",
  97                               typename(obj->type), sha1_to_hex(obj->sha1));
  98                        printf("              to %7s %s\n",
  99                               typename(ref->type), sha1_to_hex(ref->sha1));
 100                        errors_found |= ERROR_REACHABLE;
 101                }
 102        }
 103}
 104
 105/*
 106 * Check a single unreachable object
 107 */
 108static void check_unreachable_object(struct object *obj)
 109{
 110        /*
 111         * Missing unreachable object? Ignore it. It's not like
 112         * we miss it (since it can't be reached), nor do we want
 113         * to complain about it being unreachable (since it does
 114         * not exist).
 115         */
 116        if (!obj->parsed)
 117                return;
 118
 119        /*
 120         * Unreachable object that exists? Show it if asked to,
 121         * since this is something that is prunable.
 122         */
 123        if (show_unreachable) {
 124                printf("unreachable %s %s\n", typename(obj->type), sha1_to_hex(obj->sha1));
 125                return;
 126        }
 127
 128        /*
 129         * "!used" means that nothing at all points to it, including
 130         * other unreachable objects. In other words, it's the "tip"
 131         * of some set of unreachable objects, usually a commit that
 132         * got dropped.
 133         *
 134         * Such starting points are more interesting than some random
 135         * set of unreachable objects, so we show them even if the user
 136         * hasn't asked for _all_ unreachable objects. If you have
 137         * deleted a branch by mistake, this is a prime candidate to
 138         * start looking at, for example.
 139         */
 140        if (!obj->used) {
 141                printf("dangling %s %s\n", typename(obj->type),
 142                       sha1_to_hex(obj->sha1));
 143                if (write_lost_and_found) {
 144                        char *filename = git_path("lost-found/%s/%s",
 145                                obj->type == OBJ_COMMIT ? "commit" : "other",
 146                                sha1_to_hex(obj->sha1));
 147                        FILE *f;
 148
 149                        if (safe_create_leading_directories(filename)) {
 150                                error("Could not create lost-found");
 151                                return;
 152                        }
 153                        if (!(f = fopen(filename, "w")))
 154                                die("Could not open %s", filename);
 155                        if (obj->type == OBJ_BLOB) {
 156                                enum object_type type;
 157                                unsigned long size;
 158                                char *buf = read_sha1_file(obj->sha1,
 159                                                &type, &size);
 160                                if (buf) {
 161                                        fwrite(buf, size, 1, f);
 162                                        free(buf);
 163                                }
 164                        } else
 165                                fprintf(f, "%s\n", sha1_to_hex(obj->sha1));
 166                        fclose(f);
 167                }
 168                return;
 169        }
 170
 171        /*
 172         * Otherwise? It's there, it's unreachable, and some other unreachable
 173         * object points to it. Ignore it - it's not interesting, and we showed
 174         * all the interesting cases above.
 175         */
 176}
 177
 178static void check_object(struct object *obj)
 179{
 180        if (verbose)
 181                fprintf(stderr, "Checking %s\n", sha1_to_hex(obj->sha1));
 182
 183        if (obj->flags & REACHABLE)
 184                check_reachable_object(obj);
 185        else
 186                check_unreachable_object(obj);
 187}
 188
 189static void check_connectivity(void)
 190{
 191        int i, max;
 192
 193        /* Look up all the requirements, warn about missing objects.. */
 194        max = get_max_object_index();
 195        if (verbose)
 196                fprintf(stderr, "Checking connectivity (%d objects)\n", max);
 197
 198        for (i = 0; i < max; i++) {
 199                struct object *obj = get_indexed_object(i);
 200
 201                if (obj)
 202                        check_object(obj);
 203        }
 204}
 205
 206/*
 207 * The entries in a tree are ordered in the _path_ order,
 208 * which means that a directory entry is ordered by adding
 209 * a slash to the end of it.
 210 *
 211 * So a directory called "a" is ordered _after_ a file
 212 * called "a.c", because "a/" sorts after "a.c".
 213 */
 214#define TREE_UNORDERED (-1)
 215#define TREE_HAS_DUPS  (-2)
 216
 217static int verify_ordered(unsigned mode1, const char *name1, unsigned mode2, const char *name2)
 218{
 219        int len1 = strlen(name1);
 220        int len2 = strlen(name2);
 221        int len = len1 < len2 ? len1 : len2;
 222        unsigned char c1, c2;
 223        int cmp;
 224
 225        cmp = memcmp(name1, name2, len);
 226        if (cmp < 0)
 227                return 0;
 228        if (cmp > 0)
 229                return TREE_UNORDERED;
 230
 231        /*
 232         * Ok, the first <len> characters are the same.
 233         * Now we need to order the next one, but turn
 234         * a '\0' into a '/' for a directory entry.
 235         */
 236        c1 = name1[len];
 237        c2 = name2[len];
 238        if (!c1 && !c2)
 239                /*
 240                 * git-write-tree used to write out a nonsense tree that has
 241                 * entries with the same name, one blob and one tree.  Make
 242                 * sure we do not have duplicate entries.
 243                 */
 244                return TREE_HAS_DUPS;
 245        if (!c1 && S_ISDIR(mode1))
 246                c1 = '/';
 247        if (!c2 && S_ISDIR(mode2))
 248                c2 = '/';
 249        return c1 < c2 ? 0 : TREE_UNORDERED;
 250}
 251
 252static int fsck_tree(struct tree *item)
 253{
 254        int retval;
 255        int has_full_path = 0;
 256        int has_empty_name = 0;
 257        int has_zero_pad = 0;
 258        int has_bad_modes = 0;
 259        int has_dup_entries = 0;
 260        int not_properly_sorted = 0;
 261        struct tree_desc desc;
 262        unsigned o_mode;
 263        const char *o_name;
 264        const unsigned char *o_sha1;
 265
 266        if (verbose)
 267                fprintf(stderr, "Checking tree %s\n",
 268                                sha1_to_hex(item->object.sha1));
 269
 270        init_tree_desc(&desc, item->buffer, item->size);
 271
 272        o_mode = 0;
 273        o_name = NULL;
 274        o_sha1 = NULL;
 275        while (desc.size) {
 276                unsigned mode;
 277                const char *name;
 278                const unsigned char *sha1;
 279
 280                sha1 = tree_entry_extract(&desc, &name, &mode);
 281
 282                if (strchr(name, '/'))
 283                        has_full_path = 1;
 284                if (!*name)
 285                        has_empty_name = 1;
 286                has_zero_pad |= *(char *)desc.buffer == '0';
 287                update_tree_entry(&desc);
 288
 289                switch (mode) {
 290                /*
 291                 * Standard modes..
 292                 */
 293                case S_IFREG | 0755:
 294                case S_IFREG | 0644:
 295                case S_IFLNK:
 296                case S_IFDIR:
 297                case S_IFGITLINK:
 298                        break;
 299                /*
 300                 * This is nonstandard, but we had a few of these
 301                 * early on when we honored the full set of mode
 302                 * bits..
 303                 */
 304                case S_IFREG | 0664:
 305                        if (!check_strict)
 306                                break;
 307                default:
 308                        has_bad_modes = 1;
 309                }
 310
 311                if (o_name) {
 312                        switch (verify_ordered(o_mode, o_name, mode, name)) {
 313                        case TREE_UNORDERED:
 314                                not_properly_sorted = 1;
 315                                break;
 316                        case TREE_HAS_DUPS:
 317                                has_dup_entries = 1;
 318                                break;
 319                        default:
 320                                break;
 321                        }
 322                }
 323
 324                o_mode = mode;
 325                o_name = name;
 326                o_sha1 = sha1;
 327        }
 328        free(item->buffer);
 329        item->buffer = NULL;
 330
 331        retval = 0;
 332        if (has_full_path) {
 333                objwarning(&item->object, "contains full pathnames");
 334        }
 335        if (has_empty_name) {
 336                objwarning(&item->object, "contains empty pathname");
 337        }
 338        if (has_zero_pad) {
 339                objwarning(&item->object, "contains zero-padded file modes");
 340        }
 341        if (has_bad_modes) {
 342                objwarning(&item->object, "contains bad file modes");
 343        }
 344        if (has_dup_entries) {
 345                retval = objerror(&item->object, "contains duplicate file entries");
 346        }
 347        if (not_properly_sorted) {
 348                retval = objerror(&item->object, "not properly sorted");
 349        }
 350        return retval;
 351}
 352
 353static int fsck_commit(struct commit *commit)
 354{
 355        char *buffer = commit->buffer;
 356        unsigned char tree_sha1[20], sha1[20];
 357
 358        if (verbose)
 359                fprintf(stderr, "Checking commit %s\n",
 360                        sha1_to_hex(commit->object.sha1));
 361
 362        if (memcmp(buffer, "tree ", 5))
 363                return objerror(&commit->object, "invalid format - expected 'tree' line");
 364        if (get_sha1_hex(buffer+5, tree_sha1) || buffer[45] != '\n')
 365                return objerror(&commit->object, "invalid 'tree' line format - bad sha1");
 366        buffer += 46;
 367        while (!memcmp(buffer, "parent ", 7)) {
 368                if (get_sha1_hex(buffer+7, sha1) || buffer[47] != '\n')
 369                        return objerror(&commit->object, "invalid 'parent' line format - bad sha1");
 370                buffer += 48;
 371        }
 372        if (memcmp(buffer, "author ", 7))
 373                return objerror(&commit->object, "invalid format - expected 'author' line");
 374        free(commit->buffer);
 375        commit->buffer = NULL;
 376        if (!commit->tree)
 377                return objerror(&commit->object, "could not load commit's tree %s", tree_sha1);
 378        if (!commit->parents && show_root)
 379                printf("root %s\n", sha1_to_hex(commit->object.sha1));
 380        if (!commit->date)
 381                printf("bad commit date in %s\n",
 382                       sha1_to_hex(commit->object.sha1));
 383        return 0;
 384}
 385
 386static int fsck_tag(struct tag *tag)
 387{
 388        struct object *tagged = tag->tagged;
 389
 390        if (verbose)
 391                fprintf(stderr, "Checking tag %s\n",
 392                        sha1_to_hex(tag->object.sha1));
 393
 394        if (!tagged) {
 395                return objerror(&tag->object, "could not load tagged object");
 396        }
 397        if (!show_tags)
 398                return 0;
 399
 400        printf("tagged %s %s", typename(tagged->type), sha1_to_hex(tagged->sha1));
 401        printf(" (%s) in %s\n", tag->tag, sha1_to_hex(tag->object.sha1));
 402        return 0;
 403}
 404
 405static int fsck_sha1(const unsigned char *sha1)
 406{
 407        struct object *obj = parse_object(sha1);
 408        if (!obj) {
 409                errors_found |= ERROR_OBJECT;
 410                return error("%s: object corrupt or missing",
 411                             sha1_to_hex(sha1));
 412        }
 413        if (obj->flags & SEEN)
 414                return 0;
 415        obj->flags |= SEEN;
 416        if (obj->type == OBJ_BLOB)
 417                return 0;
 418        if (obj->type == OBJ_TREE)
 419                return fsck_tree((struct tree *) obj);
 420        if (obj->type == OBJ_COMMIT)
 421                return fsck_commit((struct commit *) obj);
 422        if (obj->type == OBJ_TAG)
 423                return fsck_tag((struct tag *) obj);
 424
 425        /* By now, parse_object() would've returned NULL instead. */
 426        return objerror(obj, "unknown type '%d' (internal fsck error)",
 427                        obj->type);
 428}
 429
 430/*
 431 * This is the sorting chunk size: make it reasonably
 432 * big so that we can sort well..
 433 */
 434#define MAX_SHA1_ENTRIES (1024)
 435
 436struct sha1_entry {
 437        unsigned long ino;
 438        unsigned char sha1[20];
 439};
 440
 441static struct {
 442        unsigned long nr;
 443        struct sha1_entry *entry[MAX_SHA1_ENTRIES];
 444} sha1_list;
 445
 446static int ino_compare(const void *_a, const void *_b)
 447{
 448        const struct sha1_entry *a = _a, *b = _b;
 449        unsigned long ino1 = a->ino, ino2 = b->ino;
 450        return ino1 < ino2 ? -1 : ino1 > ino2 ? 1 : 0;
 451}
 452
 453static void fsck_sha1_list(void)
 454{
 455        int i, nr = sha1_list.nr;
 456
 457        if (SORT_DIRENT)
 458                qsort(sha1_list.entry, nr,
 459                      sizeof(struct sha1_entry *), ino_compare);
 460        for (i = 0; i < nr; i++) {
 461                struct sha1_entry *entry = sha1_list.entry[i];
 462                unsigned char *sha1 = entry->sha1;
 463
 464                sha1_list.entry[i] = NULL;
 465                fsck_sha1(sha1);
 466                free(entry);
 467        }
 468        sha1_list.nr = 0;
 469}
 470
 471static void add_sha1_list(unsigned char *sha1, unsigned long ino)
 472{
 473        struct sha1_entry *entry = xmalloc(sizeof(*entry));
 474        int nr;
 475
 476        entry->ino = ino;
 477        hashcpy(entry->sha1, sha1);
 478        nr = sha1_list.nr;
 479        if (nr == MAX_SHA1_ENTRIES) {
 480                fsck_sha1_list();
 481                nr = 0;
 482        }
 483        sha1_list.entry[nr] = entry;
 484        sha1_list.nr = ++nr;
 485}
 486
 487static void fsck_dir(int i, char *path)
 488{
 489        DIR *dir = opendir(path);
 490        struct dirent *de;
 491
 492        if (!dir)
 493                return;
 494
 495        if (verbose)
 496                fprintf(stderr, "Checking directory %s\n", path);
 497
 498        while ((de = readdir(dir)) != NULL) {
 499                char name[100];
 500                unsigned char sha1[20];
 501                int len = strlen(de->d_name);
 502
 503                switch (len) {
 504                case 2:
 505                        if (de->d_name[1] != '.')
 506                                break;
 507                case 1:
 508                        if (de->d_name[0] != '.')
 509                                break;
 510                        continue;
 511                case 38:
 512                        sprintf(name, "%02x", i);
 513                        memcpy(name+2, de->d_name, len+1);
 514                        if (get_sha1_hex(name, sha1) < 0)
 515                                break;
 516                        add_sha1_list(sha1, DIRENT_SORT_HINT(de));
 517                        continue;
 518                }
 519                fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name);
 520        }
 521        closedir(dir);
 522}
 523
 524static int default_refs;
 525
 526static int fsck_handle_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
 527                const char *email, unsigned long timestamp, int tz,
 528                const char *message, void *cb_data)
 529{
 530        struct object *obj;
 531
 532        if (verbose)
 533                fprintf(stderr, "Checking reflog %s->%s\n",
 534                        sha1_to_hex(osha1), sha1_to_hex(nsha1));
 535
 536        if (!is_null_sha1(osha1)) {
 537                obj = lookup_object(osha1);
 538                if (obj) {
 539                        obj->used = 1;
 540                        mark_reachable(obj, REACHABLE);
 541                }
 542        }
 543        obj = lookup_object(nsha1);
 544        if (obj) {
 545                obj->used = 1;
 546                mark_reachable(obj, REACHABLE);
 547        }
 548        return 0;
 549}
 550
 551static int fsck_handle_reflog(const char *logname, const unsigned char *sha1, int flag, void *cb_data)
 552{
 553        for_each_reflog_ent(logname, fsck_handle_reflog_ent, NULL);
 554        return 0;
 555}
 556
 557static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
 558{
 559        struct object *obj;
 560
 561        obj = lookup_object(sha1);
 562        if (!obj) {
 563                if (has_sha1_file(sha1)) {
 564                        default_refs++;
 565                        return 0; /* it is in a pack */
 566                }
 567                error("%s: invalid sha1 pointer %s", refname, sha1_to_hex(sha1));
 568                /* We'll continue with the rest despite the error.. */
 569                return 0;
 570        }
 571        default_refs++;
 572        obj->used = 1;
 573        mark_reachable(obj, REACHABLE);
 574
 575        return 0;
 576}
 577
 578static void get_default_heads(void)
 579{
 580        for_each_ref(fsck_handle_ref, NULL);
 581        if (include_reflogs)
 582                for_each_reflog(fsck_handle_reflog, NULL);
 583
 584        /*
 585         * Not having any default heads isn't really fatal, but
 586         * it does mean that "--unreachable" no longer makes any
 587         * sense (since in this case everything will obviously
 588         * be unreachable by definition.
 589         *
 590         * Showing dangling objects is valid, though (as those
 591         * dangling objects are likely lost heads).
 592         *
 593         * So we just print a warning about it, and clear the
 594         * "show_unreachable" flag.
 595         */
 596        if (!default_refs) {
 597                fprintf(stderr, "notice: No default references\n");
 598                show_unreachable = 0;
 599        }
 600}
 601
 602static void fsck_object_dir(const char *path)
 603{
 604        int i;
 605
 606        if (verbose)
 607                fprintf(stderr, "Checking object directory\n");
 608
 609        for (i = 0; i < 256; i++) {
 610                static char dir[4096];
 611                sprintf(dir, "%s/%02x", path, i);
 612                fsck_dir(i, dir);
 613        }
 614        fsck_sha1_list();
 615}
 616
 617static int fsck_head_link(void)
 618{
 619        unsigned char sha1[20];
 620        int flag;
 621        int null_is_error = 0;
 622        const char *head_points_at = resolve_ref("HEAD", sha1, 0, &flag);
 623
 624        if (verbose)
 625                fprintf(stderr, "Checking HEAD link\n");
 626
 627        if (!head_points_at)
 628                return error("Invalid HEAD");
 629        if (!strcmp(head_points_at, "HEAD"))
 630                /* detached HEAD */
 631                null_is_error = 1;
 632        else if (prefixcmp(head_points_at, "refs/heads/"))
 633                return error("HEAD points to something strange (%s)",
 634                             head_points_at);
 635        if (is_null_sha1(sha1)) {
 636                if (null_is_error)
 637                        return error("HEAD: detached HEAD points at nothing");
 638                fprintf(stderr, "notice: HEAD points to an unborn branch (%s)\n",
 639                        head_points_at + 11);
 640        }
 641        return 0;
 642}
 643
 644static int fsck_cache_tree(struct cache_tree *it)
 645{
 646        int i;
 647        int err = 0;
 648
 649        if (verbose)
 650                fprintf(stderr, "Checking cache tree\n");
 651
 652        if (0 <= it->entry_count) {
 653                struct object *obj = parse_object(it->sha1);
 654                if (!obj) {
 655                        error("%s: invalid sha1 pointer in cache-tree",
 656                              sha1_to_hex(it->sha1));
 657                        return 1;
 658                }
 659                mark_reachable(obj, REACHABLE);
 660                obj->used = 1;
 661                if (obj->type != OBJ_TREE)
 662                        err |= objerror(obj, "non-tree in cache-tree");
 663        }
 664        for (i = 0; i < it->subtree_nr; i++)
 665                err |= fsck_cache_tree(it->down[i]->cache_tree);
 666        return err;
 667}
 668
 669static const char fsck_usage[] =
 670"git-fsck [--tags] [--root] [[--unreachable] [--cache] [--full] "
 671"[--strict] [--verbose] <head-sha1>*]";
 672
 673int cmd_fsck(int argc, const char **argv, const char *prefix)
 674{
 675        int i, heads;
 676
 677        track_object_refs = 1;
 678        errors_found = 0;
 679
 680        for (i = 1; i < argc; i++) {
 681                const char *arg = argv[i];
 682
 683                if (!strcmp(arg, "--unreachable")) {
 684                        show_unreachable = 1;
 685                        continue;
 686                }
 687                if (!strcmp(arg, "--tags")) {
 688                        show_tags = 1;
 689                        continue;
 690                }
 691                if (!strcmp(arg, "--root")) {
 692                        show_root = 1;
 693                        continue;
 694                }
 695                if (!strcmp(arg, "--cache")) {
 696                        keep_cache_objects = 1;
 697                        continue;
 698                }
 699                if (!strcmp(arg, "--no-reflogs")) {
 700                        include_reflogs = 0;
 701                        continue;
 702                }
 703                if (!strcmp(arg, "--full")) {
 704                        check_full = 1;
 705                        continue;
 706                }
 707                if (!strcmp(arg, "--strict")) {
 708                        check_strict = 1;
 709                        continue;
 710                }
 711                if (!strcmp(arg, "--verbose")) {
 712                        verbose = 1;
 713                        continue;
 714                }
 715                if (!strcmp(arg, "--lost-found")) {
 716                        check_full = 1;
 717                        include_reflogs = 0;
 718                        write_lost_and_found = 1;
 719                        continue;
 720                }
 721                if (*arg == '-')
 722                        usage(fsck_usage);
 723        }
 724
 725        fsck_head_link();
 726        fsck_object_dir(get_object_directory());
 727        if (check_full) {
 728                struct alternate_object_database *alt;
 729                struct packed_git *p;
 730                prepare_alt_odb();
 731                for (alt = alt_odb_list; alt; alt = alt->next) {
 732                        char namebuf[PATH_MAX];
 733                        int namelen = alt->name - alt->base;
 734                        memcpy(namebuf, alt->base, namelen);
 735                        namebuf[namelen - 1] = 0;
 736                        fsck_object_dir(namebuf);
 737                }
 738                prepare_packed_git();
 739                for (p = packed_git; p; p = p->next)
 740                        /* verify gives error messages itself */
 741                        verify_pack(p, 0);
 742
 743                for (p = packed_git; p; p = p->next) {
 744                        uint32_t i, num;
 745                        if (open_pack_index(p))
 746                                continue;
 747                        num = p->num_objects;
 748                        for (i = 0; i < num; i++)
 749                                fsck_sha1(nth_packed_object_sha1(p, i));
 750                }
 751        }
 752
 753        heads = 0;
 754        for (i = 1; i < argc; i++) {
 755                const char *arg = argv[i];
 756
 757                if (*arg == '-')
 758                        continue;
 759
 760                if (!get_sha1(arg, head_sha1)) {
 761                        struct object *obj = lookup_object(head_sha1);
 762
 763                        /* Error is printed by lookup_object(). */
 764                        if (!obj)
 765                                continue;
 766
 767                        obj->used = 1;
 768                        mark_reachable(obj, REACHABLE);
 769                        heads++;
 770                        continue;
 771                }
 772                error("invalid parameter: expected sha1, got '%s'", arg);
 773        }
 774
 775        /*
 776         * If we've not been given any explicit head information, do the
 777         * default ones from .git/refs. We also consider the index file
 778         * in this case (ie this implies --cache).
 779         */
 780        if (!heads) {
 781                get_default_heads();
 782                keep_cache_objects = 1;
 783        }
 784
 785        if (keep_cache_objects) {
 786                int i;
 787                read_cache();
 788                for (i = 0; i < active_nr; i++) {
 789                        unsigned int mode;
 790                        struct blob *blob;
 791                        struct object *obj;
 792
 793                        mode = ntohl(active_cache[i]->ce_mode);
 794                        if (S_ISGITLINK(mode))
 795                                continue;
 796                        blob = lookup_blob(active_cache[i]->sha1);
 797                        if (!blob)
 798                                continue;
 799                        obj = &blob->object;
 800                        obj->used = 1;
 801                        mark_reachable(obj, REACHABLE);
 802                }
 803                if (active_cache_tree)
 804                        fsck_cache_tree(active_cache_tree);
 805        }
 806
 807        check_connectivity();
 808        return errors_found;
 809}