1 #include "cache.h"
3 struct entry {
4 unsigned char old_sha1[20];
5 unsigned char new_sha1[20];
6 int converted;
7 };
9 #define MAXOBJECTS (1000000)
11 static struct entry *convert[MAXOBJECTS];
12 static int nr_convert;
14 static struct entry * convert_entry(unsigned char *sha1);
16 static struct entry *insert_new(unsigned char *sha1, int pos)
17 {
18 struct entry *new = malloc(sizeof(struct entry));
20 memset(new, 0, sizeof(*new));
21 memcpy(new->old_sha1, sha1, 20);
22 memmove(convert + pos + 1, convert + pos, (nr_convert - pos) * sizeof(struct entry *));
23 convert[pos] = new;
24 nr_convert++;
25 if (nr_convert == MAXOBJECTS)
26 die("you're kidding me - hit maximum object limit");
27 return new;
28 }
30 static struct entry *lookup_entry(unsigned char *sha1)
31 {
32 int low = 0, high = nr_convert;
34 while (low < high) {
35 int next = (low + high) / 2;
36 struct entry *n = convert[next];
37 int cmp = memcmp(sha1, n->old_sha1, 20);
38 if (!cmp)
39 return n;
40 if (cmp < 0) {
41 high = next;
42 continue;
43 }
44 low = next+1;
45 }
46 return insert_new(sha1, low);
47 }
49 static void convert_blob(void *buffer, unsigned long size)
50 {
51 /* Nothing to do */
52 }
54 static void convert_binary_sha1(void *buffer)
55 {
56 struct entry *entry = convert_entry(buffer);
57 memcpy(buffer, entry->new_sha1, 20);
58 }
60 static void convert_ascii_sha1(void *buffer)
61 {
62 unsigned char sha1[20];
63 struct entry *entry;
65 if (get_sha1_hex(buffer, sha1))
66 die("bad sha1");
67 entry = convert_entry(sha1);
68 memcpy(buffer, sha1_to_hex(entry->new_sha1), 40);
69 }
71 static void convert_tree(void *buffer, unsigned long size)
72 {
73 while (size) {
74 int len = 1+strlen(buffer);
76 convert_binary_sha1(buffer + len);
78 len += 20;
79 if (len > size)
80 die("corrupt tree object");
81 size -= len;
82 buffer += len;
83 }
84 }
86 static void convert_commit(void *buffer, unsigned long size)
87 {
88 convert_ascii_sha1(buffer+5);
89 buffer += 46; /* "tree " + "hex sha1" + "\n" */
90 while (!memcmp(buffer, "parent ", 7)) {
91 convert_ascii_sha1(buffer+7);
92 buffer += 48;
93 }
94 }
96 static struct entry * convert_entry(unsigned char *sha1)
97 {
98 struct entry *entry = lookup_entry(sha1);
99 char type[20];
100 void *buffer, *data;
101 unsigned long size, offset;
103 if (entry->converted)
104 return entry;
105 data = read_sha1_file(sha1, type, &size);
106 if (!data)
107 die("unable to read object %s", sha1_to_hex(sha1));
109 buffer = malloc(size + 100);
110 offset = sprintf(buffer, "%s %lu", type, size)+1;
111 memcpy(buffer + offset, data, size);
113 if (!strcmp(type, "blob"))
114 convert_blob(buffer + offset, size);
115 else if (!strcmp(type, "tree"))
116 convert_tree(buffer + offset, size);
117 else if (!strcmp(type, "commit"))
118 convert_commit(buffer + offset, size);
119 else
120 die("unknown object type '%s' in %s", type, sha1_to_hex(sha1));
121 write_sha1_file(buffer, size + offset, entry->new_sha1);
122 entry->converted = 1;
123 free(buffer);
124 return entry;
125 }
127 int main(int argc, char **argv)
128 {
129 unsigned char sha1[20];
130 struct entry *entry;
132 if (argc != 2 || get_sha1_hex(argv[1], sha1))
133 usage("convert-cache <sha1>");
135 entry = convert_entry(sha1);
136 printf("new sha1: %s\n", sha1_to_hex(entry->new_sha1));
137 return 0;
138 }