5 struct rev_cache
**rev_cache
;
6 int nr_revs
, alloc_revs
;
8 struct rev_list_elem
*rle_free
;
10 #define BATCH_SIZE 512
12 int find_rev_cache(const unsigned char *sha1
)
14 int lo
= 0, hi
= nr_revs
;
16 int mi
= (lo
+ hi
) / 2;
17 struct rev_cache
*ri
= rev_cache
[mi
];
18 int cmp
= memcmp(sha1
, ri
->sha1
, 20);
29 static struct rev_list_elem
*alloc_list_elem(void)
31 struct rev_list_elem
*rle
;
35 rle
= xmalloc(sizeof(*rle
) * BATCH_SIZE
);
36 for (i
= 0; i
< BATCH_SIZE
- 1; i
++) {
38 rle
[i
].next
= &rle
[i
+ 1];
40 rle
[BATCH_SIZE
- 1].ri
= NULL
;
41 rle
[BATCH_SIZE
- 1].next
= NULL
;
49 static struct rev_cache
*create_rev_cache(const unsigned char *sha1
)
52 int pos
= find_rev_cache(sha1
);
55 return rev_cache
[pos
];
57 if (alloc_revs
<= ++nr_revs
) {
58 alloc_revs
= alloc_nr(alloc_revs
);
59 rev_cache
= xrealloc(rev_cache
, sizeof(ri
) * alloc_revs
);
62 memmove(rev_cache
+ pos
+ 1, rev_cache
+ pos
,
63 (nr_revs
- pos
- 1) * sizeof(ri
));
64 ri
= xcalloc(1, sizeof(*ri
));
65 memcpy(ri
->sha1
, sha1
, 20);
70 static unsigned char last_sha1
[20];
72 static void write_one_rev_cache(FILE *rev_cache_file
, struct rev_cache
*ri
)
75 struct rev_list_elem
*rle
;
81 /* We use last_sha1 compression only for the first parent;
82 * otherwise the resulting rev-cache would lose the parent
86 !memcmp(ri
->parents
->ri
->sha1
, last_sha1
, 20))
87 flag
= (ri
->num_parents
- 1) | 0x80;
89 flag
= ri
->num_parents
;
91 fwrite(ri
->sha1
, 20, 1, rev_cache_file
);
92 fwrite(&flag
, 1, 1, rev_cache_file
);
93 for (rle
= ri
->parents
; rle
; rle
= rle
->next
) {
94 if (flag
& 0x80 && rle
== ri
->parents
)
96 fwrite(rle
->ri
->sha1
, 20, 1, rev_cache_file
);
98 memcpy(last_sha1
, ri
->sha1
, 20);
101 /* recursively write children depth first */
102 for (rle
= ri
->children
; rle
; rle
= rle
->next
)
103 write_one_rev_cache(rev_cache_file
, rle
->ri
);
106 void write_rev_cache(const char *newpath
, const char *oldpath
)
108 /* write the following commit ancestry information in
109 * $GIT_DIR/info/rev-cache.
112 * 20-byte SHA1 (commit ID)
114 * - bit 0-6 records "number of parent commit SHA1s to
115 * follow" (i.e. up to 127 children can be listed).
116 * - when the bit 7 is on, then "the entry immediately
117 * before this entry is one of the parents of this
119 * N x 20-byte SHA1 (parent commit IDs)
121 FILE *rev_cache_file
;
123 struct rev_cache
*ri
;
125 if (!strcmp(newpath
, oldpath
)) {
126 /* If we are doing it in place */
127 rev_cache_file
= fopen(newpath
, "a");
132 FILE *oldfp
= fopen(oldpath
, "r");
133 rev_cache_file
= fopen(newpath
, "w");
136 sz
= fread(buf
, 1, sizeof(buf
), oldfp
);
139 fwrite(buf
, 1, sz
, rev_cache_file
);
145 memset(last_sha1
, 0, 20);
147 /* Go through available rev_cache structures, starting from
148 * parentless ones first, so that we would get most out of
149 * last_sha1 optimization by the depth first behaviour of
150 * write_one_rev_cache().
152 for (i
= 0; i
< nr_revs
; i
++) {
156 write_one_rev_cache(rev_cache_file
, ri
);
159 for (i
= 0; i
< nr_revs
; i
++) {
161 write_one_rev_cache(rev_cache_file
, ri
);
163 fclose(rev_cache_file
);
166 static void add_parent(struct rev_cache
*child
,
167 const unsigned char *parent_sha1
)
169 struct rev_cache
*parent
= create_rev_cache(parent_sha1
);
170 struct rev_list_elem
*e
= alloc_list_elem();
172 /* Keep the parent list ordered in the same way the commit
173 * object records them.
177 if (!child
->parents_tail
)
180 child
->parents_tail
->next
= e
;
181 child
->parents_tail
= e
;
182 child
->num_parents
++;
184 /* There is no inherent order of the children so we just
185 * LIFO them together.
187 e
= alloc_list_elem();
188 e
->next
= parent
->children
;
189 parent
->children
= e
;
191 parent
->num_children
++;
194 int read_rev_cache(const char *path
, FILE *dumpfile
, int dry_run
)
199 unsigned long ofs
, len
;
200 struct rev_cache
*ri
= NULL
;
202 fd
= open(path
, O_RDONLY
);
205 return error("cannot open %s", path
);
210 if (fstat(fd
, &st
)) {
214 map
= mmap(NULL
, st
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
216 if (map
== MAP_FAILED
)
219 memset(last_sha1
, 0, 20);
223 unsigned char sha1
[20];
226 die("rev-cache too short");
227 memcpy(sha1
, map
+ ofs
, 20);
228 flag
= map
[ofs
+ 20];
230 cnt
= (flag
& 0x7f) + ((flag
& 0x80) != 0);
231 if (len
< ofs
+ (flag
& 0x7f) * 20)
232 die("rev-cache too short to have %d more parents",
235 fprintf(dumpfile
, "%s", sha1_to_hex(sha1
));
237 ri
= create_rev_cache(sha1
);
239 die("cannot create rev-cache for %s",
241 ri
->written
= ri
->parsed
= 1;
246 add_parent(ri
, last_sha1
);
248 fprintf(dumpfile
, " %s",
249 sha1_to_hex(last_sha1
));
254 add_parent(ri
, map
+ ofs
);
256 fprintf(dumpfile
, " %s",
257 sha1_to_hex(last_sha1
));
261 fprintf(dumpfile
, "\n");
262 memcpy(last_sha1
, sha1
, 20);
265 die("rev-cache truncated?");
270 int record_rev_cache(const unsigned char *sha1
, FILE *dumpfile
)
272 unsigned char parent
[20];
274 unsigned long size
, ofs
;
277 struct rev_cache
*ri
;
279 buf
= read_sha1_file(sha1
, type
, &size
);
281 return error("%s: not found", sha1_to_hex(sha1
));
282 if (strcmp(type
, "commit")) {
284 return error("%s: not a commit but a %s",
285 sha1_to_hex(sha1
), type
);
287 ri
= create_rev_cache(sha1
);
291 fprintf(dumpfile
, "commit %s\n", sha1_to_hex(sha1
));
294 ofs
= 46; /* "tree " + hex-sha1 + "\n" */
295 while (!memcmp(buf
+ ofs
, "parent ", 7) &&
296 !get_sha1_hex(buf
+ ofs
+ 7, parent
)) {
300 if (cnt
* 48 + 46 != ofs
) {
302 die("internal error in record_rev_cache");
305 ri
= create_rev_cache(sha1
);
308 for (i
= 0; i
< cnt
; i
++) {
309 unsigned char parent_sha1
[20];
311 ofs
= 46 + i
* 48 + 7;
312 get_sha1_hex(buf
+ ofs
, parent_sha1
);
313 add_parent(ri
, parent_sha1
);
314 record_rev_cache(parent_sha1
, dumpfile
);