~ubuntu-branches/ubuntu/intrepid/git-core/intrepid-updates

« back to all changes in this revision

Viewing changes to builtin-fsck.c

  • Committer: Package Import Robot
  • Author(s): Gerrit Pape
  • Date: 2007-04-22 13:31:05 UTC
  • mfrom: (1.1.14)
  • Revision ID: package-import@ubuntu.com-20070422133105-tkmhz328g2p0epz1
Tags: 1:1.5.1.2-1
* new upstream point release.
* debian/changelog.upstream: upstream changes taken from mailing list
  announcement.

Show diffs side-by-side

added added

removed removed

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