builtin / show-index.con commit rev-list: handle missing tree objects properly (7c0fe33)
   1#include "builtin.h"
   2#include "cache.h"
   3#include "pack.h"
   4
   5static const char show_index_usage[] =
   6"git show-index";
   7
   8int cmd_show_index(int argc, const char **argv, const char *prefix)
   9{
  10        int i;
  11        unsigned nr;
  12        unsigned int version;
  13        static unsigned int top_index[256];
  14
  15        if (argc != 1)
  16                usage(show_index_usage);
  17        if (fread(top_index, 2 * 4, 1, stdin) != 1)
  18                die("unable to read header");
  19        if (top_index[0] == htonl(PACK_IDX_SIGNATURE)) {
  20                version = ntohl(top_index[1]);
  21                if (version < 2 || version > 2)
  22                        die("unknown index version");
  23                if (fread(top_index, 256 * 4, 1, stdin) != 1)
  24                        die("unable to read index");
  25        } else {
  26                version = 1;
  27                if (fread(&top_index[2], 254 * 4, 1, stdin) != 1)
  28                        die("unable to read index");
  29        }
  30        nr = 0;
  31        for (i = 0; i < 256; i++) {
  32                unsigned n = ntohl(top_index[i]);
  33                if (n < nr)
  34                        die("corrupt index file");
  35                nr = n;
  36        }
  37        if (version == 1) {
  38                for (i = 0; i < nr; i++) {
  39                        unsigned int offset, entry[6];
  40
  41                        if (fread(entry, 4 + 20, 1, stdin) != 1)
  42                                die("unable to read entry %u/%u", i, nr);
  43                        offset = ntohl(entry[0]);
  44                        printf("%u %s\n", offset, sha1_to_hex((void *)(entry+1)));
  45                }
  46        } else {
  47                unsigned off64_nr = 0;
  48                struct {
  49                        unsigned char sha1[20];
  50                        uint32_t crc;
  51                        uint32_t off;
  52                } *entries;
  53                ALLOC_ARRAY(entries, nr);
  54                for (i = 0; i < nr; i++)
  55                        if (fread(entries[i].sha1, 20, 1, stdin) != 1)
  56                                die("unable to read sha1 %u/%u", i, nr);
  57                for (i = 0; i < nr; i++)
  58                        if (fread(&entries[i].crc, 4, 1, stdin) != 1)
  59                                die("unable to read crc %u/%u", i, nr);
  60                for (i = 0; i < nr; i++)
  61                        if (fread(&entries[i].off, 4, 1, stdin) != 1)
  62                                die("unable to read 32b offset %u/%u", i, nr);
  63                for (i = 0; i < nr; i++) {
  64                        uint64_t offset;
  65                        uint32_t off = ntohl(entries[i].off);
  66                        if (!(off & 0x80000000)) {
  67                                offset = off;
  68                        } else {
  69                                uint32_t off64[2];
  70                                if ((off & 0x7fffffff) != off64_nr)
  71                                        die("inconsistent 64b offset index");
  72                                if (fread(off64, 8, 1, stdin) != 1)
  73                                        die("unable to read 64b offset %u", off64_nr);
  74                                offset = (((uint64_t)ntohl(off64[0])) << 32) |
  75                                                     ntohl(off64[1]);
  76                                off64_nr++;
  77                        }
  78                        printf("%" PRIuMAX " %s (%08"PRIx32")\n",
  79                               (uintmax_t) offset,
  80                               sha1_to_hex(entries[i].sha1),
  81                               ntohl(entries[i].crc));
  82                }
  83                free(entries);
  84        }
  85        return 0;
  86}