show-index.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "builtin.h"
  2. #include "cache.h"
  3. #include "pack.h"
  4. #include "parse-options.h"
  5. static const char *const show_index_usage[] = {
  6. "git show-index [--object-format=<hash-algorithm>]",
  7. NULL
  8. };
  9. int cmd_show_index(int argc, const char **argv, const char *prefix)
  10. {
  11. int i;
  12. unsigned nr;
  13. unsigned int version;
  14. static unsigned int top_index[256];
  15. unsigned hashsz;
  16. const char *hash_name = NULL;
  17. int hash_algo;
  18. const struct option show_index_options[] = {
  19. OPT_STRING(0, "object-format", &hash_name, N_("hash-algorithm"),
  20. N_("specify the hash algorithm to use")),
  21. OPT_END()
  22. };
  23. argc = parse_options(argc, argv, prefix, show_index_options, show_index_usage, 0);
  24. if (hash_name) {
  25. hash_algo = hash_algo_by_name(hash_name);
  26. if (hash_algo == GIT_HASH_UNKNOWN)
  27. die(_("Unknown hash algorithm"));
  28. repo_set_hash_algo(the_repository, hash_algo);
  29. }
  30. hashsz = the_hash_algo->rawsz;
  31. if (fread(top_index, 2 * 4, 1, stdin) != 1)
  32. die("unable to read header");
  33. if (top_index[0] == htonl(PACK_IDX_SIGNATURE)) {
  34. version = ntohl(top_index[1]);
  35. if (version < 2 || version > 2)
  36. die("unknown index version");
  37. if (fread(top_index, 256 * 4, 1, stdin) != 1)
  38. die("unable to read index");
  39. } else {
  40. version = 1;
  41. if (fread(&top_index[2], 254 * 4, 1, stdin) != 1)
  42. die("unable to read index");
  43. }
  44. nr = 0;
  45. for (i = 0; i < 256; i++) {
  46. unsigned n = ntohl(top_index[i]);
  47. if (n < nr)
  48. die("corrupt index file");
  49. nr = n;
  50. }
  51. if (version == 1) {
  52. for (i = 0; i < nr; i++) {
  53. unsigned int offset, entry[(GIT_MAX_RAWSZ + 4) / sizeof(unsigned int)];
  54. if (fread(entry, 4 + hashsz, 1, stdin) != 1)
  55. die("unable to read entry %u/%u", i, nr);
  56. offset = ntohl(entry[0]);
  57. printf("%u %s\n", offset, hash_to_hex((void *)(entry+1)));
  58. }
  59. } else {
  60. unsigned off64_nr = 0;
  61. struct {
  62. struct object_id oid;
  63. uint32_t crc;
  64. uint32_t off;
  65. } *entries;
  66. ALLOC_ARRAY(entries, nr);
  67. for (i = 0; i < nr; i++)
  68. if (fread(entries[i].oid.hash, hashsz, 1, stdin) != 1)
  69. die("unable to read sha1 %u/%u", i, nr);
  70. for (i = 0; i < nr; i++)
  71. if (fread(&entries[i].crc, 4, 1, stdin) != 1)
  72. die("unable to read crc %u/%u", i, nr);
  73. for (i = 0; i < nr; i++)
  74. if (fread(&entries[i].off, 4, 1, stdin) != 1)
  75. die("unable to read 32b offset %u/%u", i, nr);
  76. for (i = 0; i < nr; i++) {
  77. uint64_t offset;
  78. uint32_t off = ntohl(entries[i].off);
  79. if (!(off & 0x80000000)) {
  80. offset = off;
  81. } else {
  82. uint32_t off64[2];
  83. if ((off & 0x7fffffff) != off64_nr)
  84. die("inconsistent 64b offset index");
  85. if (fread(off64, 8, 1, stdin) != 1)
  86. die("unable to read 64b offset %u", off64_nr);
  87. offset = (((uint64_t)ntohl(off64[0])) << 32) |
  88. ntohl(off64[1]);
  89. off64_nr++;
  90. }
  91. printf("%" PRIuMAX " %s (%08"PRIx32")\n",
  92. (uintmax_t) offset,
  93. oid_to_hex(&entries[i].oid),
  94. ntohl(entries[i].crc));
  95. }
  96. free(entries);
  97. }
  98. return 0;
  99. }