Git fork
at reftables-rust 125 lines 3.5 kB view raw
1#define USE_THE_REPOSITORY_VARIABLE 2#define DISABLE_SIGN_COMPARE_WARNINGS 3 4#include "builtin.h" 5#include "gettext.h" 6#include "hash.h" 7#include "hex.h" 8#include "pack.h" 9#include "parse-options.h" 10 11static const char *const show_index_usage[] = { 12 "git show-index [--object-format=<hash-algorithm>] < <pack-idx-file>", 13 NULL 14}; 15 16int cmd_show_index(int argc, 17 const char **argv, 18 const char *prefix, 19 struct repository *repo UNUSED) 20{ 21 int i; 22 unsigned nr; 23 unsigned int version; 24 static unsigned int top_index[256]; 25 unsigned hashsz; 26 const char *hash_name = NULL; 27 int hash_algo; 28 const struct option show_index_options[] = { 29 OPT_STRING(0, "object-format", &hash_name, N_("hash-algorithm"), 30 N_("specify the hash algorithm to use")), 31 OPT_END() 32 }; 33 34 argc = parse_options(argc, argv, prefix, show_index_options, show_index_usage, 0); 35 36 if (hash_name) { 37 hash_algo = hash_algo_by_name(hash_name); 38 if (hash_algo == GIT_HASH_UNKNOWN) 39 die(_("Unknown hash algorithm")); 40 repo_set_hash_algo(the_repository, hash_algo); 41 } 42 43 /* 44 * Fallback to SHA1 if we are running outside of a repository. 45 * 46 * TODO: Figure out and implement a way to detect the hash algorithm in use by the 47 * the index file passed in and use that instead. 48 */ 49 if (!the_hash_algo) 50 repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT); 51 52 hashsz = the_hash_algo->rawsz; 53 54 if (fread(top_index, 2 * 4, 1, stdin) != 1) 55 die("unable to read header"); 56 if (top_index[0] == htonl(PACK_IDX_SIGNATURE)) { 57 version = ntohl(top_index[1]); 58 if (version < 2 || version > 2) 59 die("unknown index version"); 60 if (fread(top_index, 256 * 4, 1, stdin) != 1) 61 die("unable to read index"); 62 } else { 63 version = 1; 64 if (fread(&top_index[2], 254 * 4, 1, stdin) != 1) 65 die("unable to read index"); 66 } 67 nr = 0; 68 for (i = 0; i < 256; i++) { 69 unsigned n = ntohl(top_index[i]); 70 if (n < nr) 71 die("corrupt index file"); 72 nr = n; 73 } 74 if (version == 1) { 75 for (i = 0; i < nr; i++) { 76 unsigned int offset, entry[(GIT_MAX_RAWSZ + 4) / sizeof(unsigned int)]; 77 78 if (fread(entry, 4 + hashsz, 1, stdin) != 1) 79 die("unable to read entry %u/%u", i, nr); 80 offset = ntohl(entry[0]); 81 printf("%u %s\n", offset, hash_to_hex((void *)(entry+1))); 82 } 83 } else { 84 unsigned off64_nr = 0; 85 struct { 86 struct object_id oid; 87 uint32_t crc; 88 uint32_t off; 89 } *entries; 90 ALLOC_ARRAY(entries, nr); 91 for (i = 0; i < nr; i++) { 92 if (fread(entries[i].oid.hash, hashsz, 1, stdin) != 1) 93 die("unable to read sha1 %u/%u", i, nr); 94 entries[i].oid.algo = hash_algo_by_ptr(the_hash_algo); 95 } 96 for (i = 0; i < nr; i++) 97 if (fread(&entries[i].crc, 4, 1, stdin) != 1) 98 die("unable to read crc %u/%u", i, nr); 99 for (i = 0; i < nr; i++) 100 if (fread(&entries[i].off, 4, 1, stdin) != 1) 101 die("unable to read 32b offset %u/%u", i, nr); 102 for (i = 0; i < nr; i++) { 103 uint64_t offset; 104 uint32_t off = ntohl(entries[i].off); 105 if (!(off & 0x80000000)) { 106 offset = off; 107 } else { 108 uint32_t off64[2]; 109 if ((off & 0x7fffffff) != off64_nr) 110 die("inconsistent 64b offset index"); 111 if (fread(off64, 8, 1, stdin) != 1) 112 die("unable to read 64b offset %u", off64_nr); 113 offset = (((uint64_t)ntohl(off64[0])) << 32) | 114 ntohl(off64[1]); 115 off64_nr++; 116 } 117 printf("%" PRIuMAX " %s (%08"PRIx32")\n", 118 (uintmax_t) offset, 119 oid_to_hex(&entries[i].oid), 120 ntohl(entries[i].crc)); 121 } 122 free(entries); 123 } 124 return 0; 125}