]> git.ipfire.org Git - thirdparty/git.git/blame - convert-cache.c
Use O_NOATIME when opening the sha1 files.
[thirdparty/git.git] / convert-cache.c
CommitLineData
d98b46f8
LT
1#include "cache.h"
2
3struct entry {
4 unsigned char old_sha1[20];
5 unsigned char new_sha1[20];
6 int converted;
7};
8
9#define MAXOBJECTS (1000000)
10
11static struct entry *convert[MAXOBJECTS];
12static int nr_convert;
13
14static struct entry * convert_entry(unsigned char *sha1);
15
16static struct entry *insert_new(unsigned char *sha1, int pos)
17{
18 struct entry *new = malloc(sizeof(struct entry));
19
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}
29
30static struct entry *lookup_entry(unsigned char *sha1)
31{
32 int low = 0, high = nr_convert;
33
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}
48
49static void convert_blob(void *buffer, unsigned long size)
50{
51 /* Nothing to do */
52}
53
54static void convert_binary_sha1(void *buffer)
55{
56 struct entry *entry = convert_entry(buffer);
57 memcpy(buffer, entry->new_sha1, 20);
58}
59
60static void convert_ascii_sha1(void *buffer)
61{
62 unsigned char sha1[20];
63 struct entry *entry;
64
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}
70
71static void convert_tree(void *buffer, unsigned long size)
72{
73 while (size) {
74 int len = 1+strlen(buffer);
75
76 convert_binary_sha1(buffer + len);
77
78 len += 20;
79 if (len > size)
80 die("corrupt tree object");
81 size -= len;
82 buffer += len;
83 }
84}
85
86static 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}
95
96static 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;
102
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));
108
109 buffer = malloc(size + 100);
110 offset = sprintf(buffer, "%s %lu", type, size)+1;
111 memcpy(buffer + offset, data, size);
112
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}
126
127int main(int argc, char **argv)
128{
129 unsigned char sha1[20];
130 struct entry *entry;
131
132 if (argc != 2 || get_sha1_hex(argv[1], sha1))
133 usage("convert-cache <sha1>");
134
135 entry = convert_entry(sha1);
136 printf("new sha1: %s\n", sha1_to_hex(entry->new_sha1));
137 return 0;
138}