10 static const char index_pack_usage
[] =
11 "git-index-pack [-o index-file] pack-file";
16 enum object_type type
;
17 enum object_type real_type
;
18 unsigned char sha1
[20];
23 struct object_entry
*obj
;
24 unsigned char base_sha1
[20];
27 static const char *pack_name
;
28 static unsigned char *pack_base
;
29 static unsigned long pack_size
;
30 static struct object_entry
*objects
;
31 static struct delta_entry
*deltas
;
32 static int nr_objects
;
35 static void open_pack_file(void)
40 fd
= open(pack_name
, O_RDONLY
);
42 die("cannot open packfile '%s': %s", pack_name
,
47 die("cannot fstat packfile '%s': %s", pack_name
,
50 pack_size
= st
.st_size
;
51 pack_base
= mmap(NULL
, pack_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
52 if (pack_base
== MAP_FAILED
) {
55 die("cannot mmap packfile '%s': %s", pack_name
,
61 static void parse_pack_header(void)
63 const struct pack_header
*hdr
;
64 unsigned char sha1
[20];
67 /* Ensure there are enough bytes for the header and final SHA1 */
68 if (pack_size
< sizeof(struct pack_header
) + 20)
69 die("packfile '%s' is too small", pack_name
);
71 /* Header consistency check */
72 hdr
= (void *)pack_base
;
73 if (hdr
->hdr_signature
!= htonl(PACK_SIGNATURE
))
74 die("packfile '%s' signature mismatch", pack_name
);
75 if (!pack_version_ok(hdr
->hdr_version
))
76 die("packfile '%s' version %d unsupported",
77 pack_name
, ntohl(hdr
->hdr_version
));
79 nr_objects
= ntohl(hdr
->hdr_entries
);
81 /* Check packfile integrity */
83 SHA1_Update(&ctx
, pack_base
, pack_size
- 20);
84 SHA1_Final(sha1
, &ctx
);
85 if (hashcmp(sha1
, pack_base
+ pack_size
- 20))
86 die("packfile '%s' SHA1 mismatch", pack_name
);
89 static void bad_object(unsigned long offset
, const char *format
,
90 ...) NORETURN
__attribute__((format (printf
, 2, 3)));
92 static void bad_object(unsigned long offset
, const char *format
, ...)
97 va_start(params
, format
);
98 vsnprintf(buf
, sizeof(buf
), format
, params
);
100 die("packfile '%s': bad object at offset %lu: %s",
101 pack_name
, offset
, buf
);
104 static void *unpack_entry_data(unsigned long offset
,
105 unsigned long *current_pos
, unsigned long size
)
107 unsigned long pack_limit
= pack_size
- 20;
108 unsigned long pos
= *current_pos
;
110 void *buf
= xmalloc(size
);
112 memset(&stream
, 0, sizeof(stream
));
113 stream
.next_out
= buf
;
114 stream
.avail_out
= size
;
115 stream
.next_in
= pack_base
+ pos
;
116 stream
.avail_in
= pack_limit
- pos
;
117 inflateInit(&stream
);
120 int ret
= inflate(&stream
, 0);
121 if (ret
== Z_STREAM_END
)
124 bad_object(offset
, "inflate returned %d", ret
);
127 if (stream
.total_out
!= size
)
128 bad_object(offset
, "size mismatch (expected %lu, got %lu)",
129 size
, stream
.total_out
);
130 *current_pos
= pack_limit
- stream
.avail_in
;
134 static void *unpack_raw_entry(unsigned long offset
,
135 enum object_type
*obj_type
,
136 unsigned long *obj_size
,
137 unsigned char *delta_base
,
138 unsigned long *next_obj_offset
)
140 unsigned long pack_limit
= pack_size
- 20;
141 unsigned long pos
= offset
;
145 enum object_type type
;
148 c
= pack_base
[pos
++];
153 if (pos
>= pack_limit
)
154 bad_object(offset
, "object extends past end of pack");
155 c
= pack_base
[pos
++];
156 size
+= (c
& 0x7fUL
) << shift
;
162 if (pos
+ 20 >= pack_limit
)
163 bad_object(offset
, "object extends past end of pack");
164 hashcpy(delta_base
, pack_base
+ pos
);
171 data
= unpack_entry_data(offset
, &pos
, size
);
174 bad_object(offset
, "bad object type %d", type
);
179 *next_obj_offset
= pos
;
183 static int find_delta(const unsigned char *base_sha1
)
185 int first
= 0, last
= nr_deltas
;
187 while (first
< last
) {
188 int next
= (first
+ last
) / 2;
189 struct delta_entry
*delta
= &deltas
[next
];
192 cmp
= hashcmp(base_sha1
, delta
->base_sha1
);
204 static int find_deltas_based_on_sha1(const unsigned char *base_sha1
,
205 int *first_index
, int *last_index
)
207 int first
= find_delta(base_sha1
);
209 int end
= nr_deltas
- 1;
213 while (first
> 0 && !hashcmp(deltas
[first
- 1].base_sha1
, base_sha1
))
215 while (last
< end
&& !hashcmp(deltas
[last
+ 1].base_sha1
, base_sha1
))
217 *first_index
= first
;
222 static void sha1_object(const void *data
, unsigned long size
,
223 enum object_type type
, unsigned char *sha1
)
228 const char *type_str
;
231 case OBJ_COMMIT
: type_str
= commit_type
; break;
232 case OBJ_TREE
: type_str
= tree_type
; break;
233 case OBJ_BLOB
: type_str
= blob_type
; break;
234 case OBJ_TAG
: type_str
= tag_type
; break;
236 die("bad type %d", type
);
239 header_size
= sprintf(header
, "%s %lu", type_str
, size
) + 1;
242 SHA1_Update(&ctx
, header
, header_size
);
243 SHA1_Update(&ctx
, data
, size
);
244 SHA1_Final(sha1
, &ctx
);
247 static void resolve_delta(struct delta_entry
*delta
, void *base_data
,
248 unsigned long base_size
, enum object_type type
)
250 struct object_entry
*obj
= delta
->obj
;
252 unsigned long delta_size
;
254 unsigned long result_size
;
255 enum object_type delta_type
;
256 unsigned char base_sha1
[20];
257 unsigned long next_obj_offset
;
260 obj
->real_type
= type
;
261 delta_data
= unpack_raw_entry(obj
->offset
, &delta_type
,
262 &delta_size
, base_sha1
,
264 result
= patch_delta(base_data
, base_size
, delta_data
, delta_size
,
268 bad_object(obj
->offset
, "failed to apply delta");
269 sha1_object(result
, result_size
, type
, obj
->sha1
);
270 if (!find_deltas_based_on_sha1(obj
->sha1
, &first
, &last
)) {
271 for (j
= first
; j
<= last
; j
++)
272 resolve_delta(&deltas
[j
], result
, result_size
, type
);
277 static int compare_delta_entry(const void *a
, const void *b
)
279 const struct delta_entry
*delta_a
= a
;
280 const struct delta_entry
*delta_b
= b
;
281 return hashcmp(delta_a
->base_sha1
, delta_b
->base_sha1
);
284 static void parse_pack_objects(void)
287 unsigned long offset
= sizeof(struct pack_header
);
288 unsigned char base_sha1
[20];
290 unsigned long data_size
;
294 * - find locations of all objects;
295 * - calculate SHA1 of all non-delta objects;
296 * - remember base SHA1 for all deltas.
298 for (i
= 0; i
< nr_objects
; i
++) {
299 struct object_entry
*obj
= &objects
[i
];
300 obj
->offset
= offset
;
301 data
= unpack_raw_entry(offset
, &obj
->type
, &data_size
,
303 obj
->real_type
= obj
->type
;
304 if (obj
->type
== OBJ_DELTA
) {
305 struct delta_entry
*delta
= &deltas
[nr_deltas
++];
307 hashcpy(delta
->base_sha1
, base_sha1
);
309 sha1_object(data
, data_size
, obj
->type
, obj
->sha1
);
312 if (offset
!= pack_size
- 20)
313 die("packfile '%s' has junk at the end", pack_name
);
315 /* Sort deltas by base SHA1 for fast searching */
316 qsort(deltas
, nr_deltas
, sizeof(struct delta_entry
),
317 compare_delta_entry
);
321 * - for all non-delta objects, look if it is used as a base for
323 * - if used as a base, uncompress the object and apply all deltas,
324 * recursively checking if the resulting object is used as a base
325 * for some more deltas.
327 for (i
= 0; i
< nr_objects
; i
++) {
328 struct object_entry
*obj
= &objects
[i
];
331 if (obj
->type
== OBJ_DELTA
)
333 if (find_deltas_based_on_sha1(obj
->sha1
, &first
, &last
))
335 data
= unpack_raw_entry(obj
->offset
, &obj
->type
, &data_size
,
337 for (j
= first
; j
<= last
; j
++)
338 resolve_delta(&deltas
[j
], data
, data_size
, obj
->type
);
342 /* Check for unresolved deltas */
343 for (i
= 0; i
< nr_deltas
; i
++) {
344 if (deltas
[i
].obj
->real_type
== OBJ_DELTA
)
345 die("packfile '%s' has unresolved deltas", pack_name
);
349 static int sha1_compare(const void *_a
, const void *_b
)
351 struct object_entry
*a
= *(struct object_entry
**)_a
;
352 struct object_entry
*b
= *(struct object_entry
**)_b
;
353 return hashcmp(a
->sha1
, b
->sha1
);
356 static void write_index_file(const char *index_name
, unsigned char *sha1
)
359 struct object_entry
**sorted_by_sha
, **list
, **last
;
360 unsigned int array
[256];
366 xcalloc(nr_objects
, sizeof(struct object_entry
*));
367 list
= sorted_by_sha
;
368 last
= sorted_by_sha
+ nr_objects
;
369 for (i
= 0; i
< nr_objects
; ++i
)
370 sorted_by_sha
[i
] = &objects
[i
];
371 qsort(sorted_by_sha
, nr_objects
, sizeof(sorted_by_sha
[0]),
376 sorted_by_sha
= list
= last
= NULL
;
379 f
= sha1create("%s", index_name
);
382 * Write the first-level table (the list is sorted,
383 * but we use a 256-entry lookup to be able to avoid
384 * having to do eight extra binary search iterations).
386 for (i
= 0; i
< 256; i
++) {
387 struct object_entry
**next
= list
;
388 while (next
< last
) {
389 struct object_entry
*obj
= *next
;
390 if (obj
->sha1
[0] != i
)
394 array
[i
] = htonl(next
- sorted_by_sha
);
397 sha1write(f
, array
, 256 * sizeof(int));
399 /* recompute the SHA1 hash of sorted object names.
400 * currently pack-objects does not do this, but that
405 * Write the actual SHA1 entries..
407 list
= sorted_by_sha
;
408 for (i
= 0; i
< nr_objects
; i
++) {
409 struct object_entry
*obj
= *list
++;
410 unsigned int offset
= htonl(obj
->offset
);
411 sha1write(f
, &offset
, 4);
412 sha1write(f
, obj
->sha1
, 20);
413 SHA1_Update(&ctx
, obj
->sha1
, 20);
415 sha1write(f
, pack_base
+ pack_size
- 20, 20);
416 sha1close(f
, NULL
, 1);
418 SHA1_Final(sha1
, &ctx
);
421 int main(int argc
, char **argv
)
424 char *index_name
= NULL
;
425 char *index_name_buf
= NULL
;
426 unsigned char sha1
[20];
428 for (i
= 1; i
< argc
; i
++) {
429 const char *arg
= argv
[i
];
432 if (!strcmp(arg
, "-o")) {
433 if (index_name
|| (i
+1) >= argc
)
434 usage(index_pack_usage
);
435 index_name
= argv
[++i
];
437 usage(index_pack_usage
);
442 usage(index_pack_usage
);
447 usage(index_pack_usage
);
449 int len
= strlen(pack_name
);
450 if (!has_extension(pack_name
, ".pack"))
451 die("packfile name '%s' does not end with '.pack'",
453 index_name_buf
= xmalloc(len
);
454 memcpy(index_name_buf
, pack_name
, len
- 5);
455 strcpy(index_name_buf
+ len
- 5, ".idx");
456 index_name
= index_name_buf
;
461 objects
= xcalloc(nr_objects
, sizeof(struct object_entry
));
462 deltas
= xcalloc(nr_objects
, sizeof(struct delta_entry
));
463 parse_pack_objects();
465 write_index_file(index_name
, sha1
);
467 free(index_name_buf
);
469 printf("%s\n", sha1_to_hex(sha1
));