read-tree.con commit Make "fsck-cache" print out all the root commits it finds. (16d4d1b)
   1/*
   2 * GIT - The information manager from hell
   3 *
   4 * Copyright (C) Linus Torvalds, 2005
   5 */
   6#include "cache.h"
   7
   8static int read_one_entry(unsigned char *sha1, const char *pathname, unsigned mode)
   9{
  10        int len = strlen(pathname);
  11        unsigned int size = cache_entry_size(len);
  12        struct cache_entry *ce = malloc(size);
  13
  14        memset(ce, 0, size);
  15
  16        ce->st_mode = mode;
  17        ce->namelen = len;
  18        memcpy(ce->name, pathname, len+1);
  19        memcpy(ce->sha1, sha1, 20);
  20        return add_cache_entry(ce);
  21}
  22
  23static int read_tree(unsigned char *sha1)
  24{
  25        void *buffer;
  26        unsigned long size;
  27        char type[20];
  28
  29        buffer = read_sha1_file(sha1, type, &size);
  30        if (!buffer)
  31                return -1;
  32        if (strcmp(type, "tree"))
  33                return -1;
  34        while (size) {
  35                int len = strlen(buffer)+1;
  36                unsigned char *sha1 = buffer + len;
  37                char *path = strchr(buffer, ' ')+1;
  38                unsigned int mode;
  39
  40                if (size < len + 20 || sscanf(buffer, "%o", &mode) != 1)
  41                        return -1;
  42
  43                buffer = sha1 + 20;
  44                size -= len + 20;
  45
  46                if (read_one_entry(sha1, path, mode) < 0)
  47                        return -1;
  48        }
  49        return 0;
  50}
  51
  52int main(int argc, char **argv)
  53{
  54        int i, newfd;
  55        unsigned char sha1[20];
  56
  57        newfd = open(".dircache/index.lock", O_RDWR | O_CREAT | O_EXCL, 0600);
  58        if (newfd < 0)
  59                usage("unable to create new cachefile");
  60
  61        for (i = 1; i < argc; i++) {
  62                const char *arg = argv[i];
  63
  64                /* "-m" stands for "merge" current directory cache */
  65                if (!strcmp(arg, "-m")) {
  66                        if (active_cache) {
  67                                fprintf(stderr, "read-tree: cannot merge old cache on top of new\n");
  68                                goto out;
  69                        }
  70                        if (read_cache() < 0) {
  71                                fprintf(stderr, "read-tree: corrupt directory cache\n");
  72                                goto out;
  73                        }
  74                        continue;
  75                }
  76                if (get_sha1_hex(arg, sha1) < 0) {
  77                        fprintf(stderr, "read-tree [-m] <sha1>\n");
  78                        goto out;
  79                }
  80                if (read_tree(sha1) < 0) {
  81                        fprintf(stderr, "failed to unpack tree object %s\n", arg);
  82                        goto out;
  83                }
  84        }
  85        if (!write_cache(newfd, active_cache, active_nr) && !rename(".dircache/index.lock", ".dircache/index"))
  86                return 0;
  87
  88out:
  89        unlink(".dircache/index.lock");
  90        exit(1);
  91}