Line | Count | Source |
1 | | #ifndef PACKFILE_H |
2 | | #define PACKFILE_H |
3 | | |
4 | | #include "list.h" |
5 | | #include "object.h" |
6 | | #include "odb.h" |
7 | | #include "odb/source-files.h" |
8 | | #include "oidset.h" |
9 | | #include "repository.h" |
10 | | #include "strmap.h" |
11 | | |
12 | | /* in odb.h */ |
13 | | struct object_info; |
14 | | struct odb_read_stream; |
15 | | |
16 | | struct packed_git { |
17 | | struct pack_window *windows; |
18 | | off_t pack_size; |
19 | | const void *index_data; |
20 | | size_t index_size; |
21 | | uint32_t num_objects; |
22 | | size_t crc_offset; |
23 | | struct oidset bad_objects; |
24 | | int index_version; |
25 | | time_t mtime; |
26 | | int pack_fd; |
27 | | int index; /* for builtin/pack-objects.c */ |
28 | | unsigned pack_local:1, |
29 | | pack_keep:1, |
30 | | pack_keep_in_core:1, |
31 | | freshened:1, |
32 | | do_not_close:1, |
33 | | pack_promisor:1, |
34 | | multi_pack_index:1, |
35 | | is_cruft:1; |
36 | | unsigned char hash[GIT_MAX_RAWSZ]; |
37 | | struct revindex_entry *revindex; |
38 | | const uint32_t *revindex_data; |
39 | | const uint32_t *revindex_map; |
40 | | size_t revindex_size; |
41 | | /* |
42 | | * mtimes_map points at the beginning of the memory mapped region of |
43 | | * this pack's corresponding .mtimes file, and mtimes_size is the size |
44 | | * of that .mtimes file |
45 | | */ |
46 | | const uint32_t *mtimes_map; |
47 | | size_t mtimes_size; |
48 | | |
49 | | /* repo denotes the repository this packfile belongs to */ |
50 | | struct repository *repo; |
51 | | |
52 | | /* something like ".git/objects/pack/xxxxx.pack" */ |
53 | | char pack_name[FLEX_ARRAY]; /* more */ |
54 | | }; |
55 | | |
56 | | struct packfile_list { |
57 | | struct packfile_list_entry *head, *tail; |
58 | | }; |
59 | | |
60 | | struct packfile_list_entry { |
61 | | struct packfile_list_entry *next; |
62 | | struct packed_git *pack; |
63 | | }; |
64 | | |
65 | | void packfile_list_clear(struct packfile_list *list); |
66 | | void packfile_list_remove(struct packfile_list *list, struct packed_git *pack); |
67 | | void packfile_list_prepend(struct packfile_list *list, struct packed_git *pack); |
68 | | void packfile_list_append(struct packfile_list *list, struct packed_git *pack); |
69 | | |
70 | | /* |
71 | | * Find the pack within the "packs" list whose index contains the object |
72 | | * "oid". For general object lookups, you probably don't want this; use |
73 | | * find_pack_entry() instead. |
74 | | */ |
75 | | struct packed_git *packfile_list_find_oid(struct packfile_list_entry *packs, |
76 | | const struct object_id *oid); |
77 | | |
78 | | /* |
79 | | * A store that manages packfiles for a given object database. |
80 | | */ |
81 | | struct packfile_store { |
82 | | struct odb_source *source; |
83 | | |
84 | | /* |
85 | | * The list of packfiles in the order in which they have been most |
86 | | * recently used. |
87 | | */ |
88 | | struct packfile_list packs; |
89 | | |
90 | | /* |
91 | | * Cache of packfiles which are marked as "kept", either because there |
92 | | * is an on-disk ".keep" file or because they are marked as "kept" in |
93 | | * memory. |
94 | | * |
95 | | * Should not be accessed directly, but via |
96 | | * `packfile_store_get_kept_pack_cache()`. The list of packs gets |
97 | | * invalidated when the stored flags and the flags passed to |
98 | | * `packfile_store_get_kept_pack_cache()` mismatch. |
99 | | */ |
100 | | struct { |
101 | | struct packed_git **packs; |
102 | | unsigned flags; |
103 | | } kept_cache; |
104 | | |
105 | | /* The multi-pack index that belongs to this specific packfile store. */ |
106 | | struct multi_pack_index *midx; |
107 | | |
108 | | /* |
109 | | * A map of packfile names to packed_git structs for tracking which |
110 | | * packs have been loaded already. |
111 | | */ |
112 | | struct strmap packs_by_path; |
113 | | |
114 | | /* |
115 | | * Whether packfiles have already been populated with this store's |
116 | | * packs. |
117 | | */ |
118 | | bool initialized; |
119 | | |
120 | | /* |
121 | | * Usually, packfiles will be reordered to the front of the `packs` |
122 | | * list whenever an object is looked up via them. This has the effect |
123 | | * that packs that contain a lot of accessed objects will be located |
124 | | * towards the front. |
125 | | * |
126 | | * This is usually desireable, but there are exceptions. One exception |
127 | | * is when the looking up multiple objects in a loop for each packfile. |
128 | | * In that case, we may easily end up with an infinite loop as the |
129 | | * packfiles get reordered to the front repeatedly. |
130 | | * |
131 | | * Setting this field to `true` thus disables these reorderings. |
132 | | */ |
133 | | bool skip_mru_updates; |
134 | | }; |
135 | | |
136 | | /* |
137 | | * Allocate and initialize a new empty packfile store for the given object |
138 | | * database source. |
139 | | */ |
140 | | struct packfile_store *packfile_store_new(struct odb_source *source); |
141 | | |
142 | | /* |
143 | | * Free the packfile store and all its associated state. All packfiles |
144 | | * tracked by the store will be closed. |
145 | | */ |
146 | | void packfile_store_free(struct packfile_store *store); |
147 | | |
148 | | /* |
149 | | * Close all packfiles associated with this store. The packfiles won't be |
150 | | * free'd, so they can be re-opened at a later point in time. |
151 | | */ |
152 | | void packfile_store_close(struct packfile_store *store); |
153 | | |
154 | | /* |
155 | | * Prepare the packfile store by loading packfiles and multi-pack indices for |
156 | | * all alternates. This becomes a no-op if the store is already prepared. |
157 | | * |
158 | | * It shouldn't typically be necessary to call this function directly, as |
159 | | * functions that access the store know to prepare it. |
160 | | */ |
161 | | void packfile_store_prepare(struct packfile_store *store); |
162 | | |
163 | | /* |
164 | | * Clear the packfile caches and try to look up any new packfiles that have |
165 | | * appeared since last preparing the packfiles store. |
166 | | * |
167 | | * This function must be called under the `odb_read_lock()`. |
168 | | */ |
169 | | void packfile_store_reprepare(struct packfile_store *store); |
170 | | |
171 | | /* |
172 | | * Add the pack to the store so that contained objects become accessible via |
173 | | * the store. This moves ownership into the store. |
174 | | */ |
175 | | void packfile_store_add_pack(struct packfile_store *store, |
176 | | struct packed_git *pack); |
177 | | |
178 | | /* |
179 | | * Get all packs managed by the given store, including packfiles that are |
180 | | * referenced by multi-pack indices. |
181 | | */ |
182 | | struct packfile_list_entry *packfile_store_get_packs(struct packfile_store *store); |
183 | | |
184 | | struct repo_for_each_pack_data { |
185 | | struct odb_source *source; |
186 | | struct packfile_list_entry *entry; |
187 | | }; |
188 | | |
189 | | static inline struct repo_for_each_pack_data repo_for_eack_pack_data_init(struct repository *repo) |
190 | 0 | { |
191 | 0 | struct repo_for_each_pack_data data = { 0 }; |
192 | |
|
193 | 0 | odb_prepare_alternates(repo->objects); |
194 | |
|
195 | 0 | for (struct odb_source *source = repo->objects->sources; source; source = source->next) { |
196 | 0 | struct odb_source_files *files = odb_source_files_downcast(source); |
197 | 0 | struct packfile_list_entry *entry = packfile_store_get_packs(files->packed); |
198 | 0 | if (!entry) |
199 | 0 | continue; |
200 | 0 | data.source = source; |
201 | 0 | data.entry = entry; |
202 | 0 | break; |
203 | 0 | } |
204 | |
|
205 | 0 | return data; |
206 | 0 | } Unexecuted instantiation: fuzz-pack-idx.c:repo_for_eack_pack_data_init Unexecuted instantiation: packfile.c:repo_for_eack_pack_data_init Unexecuted instantiation: promisor-remote.c:repo_for_eack_pack_data_init Unexecuted instantiation: repo-settings.c:repo_for_eack_pack_data_init Unexecuted instantiation: run-command.c:repo_for_eack_pack_data_init Unexecuted instantiation: tag.c:repo_for_eack_pack_data_init Unexecuted instantiation: diff.c:repo_for_eack_pack_data_init Unexecuted instantiation: list-objects.c:repo_for_eack_pack_data_init Unexecuted instantiation: midx.c:repo_for_eack_pack_data_init Unexecuted instantiation: object-file.c:repo_for_eack_pack_data_init Unexecuted instantiation: object-name.c:repo_for_eack_pack_data_init Unexecuted instantiation: odb.c:repo_for_eack_pack_data_init Unexecuted instantiation: source.c:repo_for_eack_pack_data_init Unexecuted instantiation: source-files.c:repo_for_eack_pack_data_init Unexecuted instantiation: pack-check.c:repo_for_eack_pack_data_init Unexecuted instantiation: pack-mtimes.c:repo_for_eack_pack_data_init Unexecuted instantiation: pack-revindex.c:repo_for_eack_pack_data_init Unexecuted instantiation: pack-write.c:repo_for_eack_pack_data_init Unexecuted instantiation: path.c:repo_for_eack_pack_data_init Unexecuted instantiation: revision.c:repo_for_eack_pack_data_init Unexecuted instantiation: commit-graph.c:repo_for_eack_pack_data_init Unexecuted instantiation: connected.c:repo_for_eack_pack_data_init Unexecuted instantiation: fetch-pack.c:repo_for_eack_pack_data_init Unexecuted instantiation: fsck.c:repo_for_eack_pack_data_init Unexecuted instantiation: transport-helper.c:repo_for_eack_pack_data_init |
207 | | |
208 | | static inline void repo_for_each_pack_data_next(struct repo_for_each_pack_data *data) |
209 | 0 | { |
210 | 0 | struct odb_source *source; |
211 | |
|
212 | 0 | data->entry = data->entry->next; |
213 | 0 | if (data->entry) |
214 | 0 | return; |
215 | | |
216 | 0 | for (source = data->source->next; source; source = source->next) { |
217 | 0 | struct odb_source_files *files = odb_source_files_downcast(source); |
218 | 0 | struct packfile_list_entry *entry = packfile_store_get_packs(files->packed); |
219 | 0 | if (!entry) |
220 | 0 | continue; |
221 | 0 | data->source = source; |
222 | 0 | data->entry = entry; |
223 | 0 | return; |
224 | 0 | } |
225 | | |
226 | 0 | data->source = NULL; |
227 | 0 | data->entry = NULL; |
228 | 0 | } Unexecuted instantiation: fuzz-pack-idx.c:repo_for_each_pack_data_next Unexecuted instantiation: packfile.c:repo_for_each_pack_data_next Unexecuted instantiation: promisor-remote.c:repo_for_each_pack_data_next Unexecuted instantiation: repo-settings.c:repo_for_each_pack_data_next Unexecuted instantiation: run-command.c:repo_for_each_pack_data_next Unexecuted instantiation: tag.c:repo_for_each_pack_data_next Unexecuted instantiation: diff.c:repo_for_each_pack_data_next Unexecuted instantiation: list-objects.c:repo_for_each_pack_data_next Unexecuted instantiation: midx.c:repo_for_each_pack_data_next Unexecuted instantiation: object-file.c:repo_for_each_pack_data_next Unexecuted instantiation: object-name.c:repo_for_each_pack_data_next Unexecuted instantiation: odb.c:repo_for_each_pack_data_next Unexecuted instantiation: source.c:repo_for_each_pack_data_next Unexecuted instantiation: source-files.c:repo_for_each_pack_data_next Unexecuted instantiation: pack-check.c:repo_for_each_pack_data_next Unexecuted instantiation: pack-mtimes.c:repo_for_each_pack_data_next Unexecuted instantiation: pack-revindex.c:repo_for_each_pack_data_next Unexecuted instantiation: pack-write.c:repo_for_each_pack_data_next Unexecuted instantiation: path.c:repo_for_each_pack_data_next Unexecuted instantiation: revision.c:repo_for_each_pack_data_next Unexecuted instantiation: commit-graph.c:repo_for_each_pack_data_next Unexecuted instantiation: connected.c:repo_for_each_pack_data_next Unexecuted instantiation: fetch-pack.c:repo_for_each_pack_data_next Unexecuted instantiation: fsck.c:repo_for_each_pack_data_next Unexecuted instantiation: transport-helper.c:repo_for_each_pack_data_next |
229 | | |
230 | | /* |
231 | | * Load and iterate through all packs of the given repository. This helper |
232 | | * function will yield packfiles from all object sources connected to the |
233 | | * repository. |
234 | | */ |
235 | | #define repo_for_each_pack(repo, p) \ |
236 | 0 | for (struct repo_for_each_pack_data eack_pack_data = repo_for_eack_pack_data_init(repo); \ |
237 | 0 | ((p) = (eack_pack_data.entry ? eack_pack_data.entry->pack : NULL)); \ |
238 | 0 | repo_for_each_pack_data_next(&eack_pack_data)) |
239 | | |
240 | | int packfile_store_read_object_stream(struct odb_read_stream **out, |
241 | | struct packfile_store *store, |
242 | | const struct object_id *oid); |
243 | | |
244 | | /* |
245 | | * Try to read the object identified by its ID from the object store and |
246 | | * populate the object info with its data. Returns 1 in case the object was |
247 | | * not found, 0 if it was and read successfully, and a negative error code in |
248 | | * case the object was corrupted. |
249 | | */ |
250 | | int packfile_store_read_object_info(struct packfile_store *store, |
251 | | const struct object_id *oid, |
252 | | struct object_info *oi, |
253 | | enum object_info_flags flags); |
254 | | |
255 | | /* |
256 | | * Open the packfile and add it to the store if it isn't yet known. Returns |
257 | | * either the newly opened packfile or the preexisting packfile. Returns a |
258 | | * `NULL` pointer in case the packfile could not be opened. |
259 | | */ |
260 | | struct packed_git *packfile_store_load_pack(struct packfile_store *store, |
261 | | const char *idx_path, int local); |
262 | | |
263 | | int packfile_store_freshen_object(struct packfile_store *store, |
264 | | const struct object_id *oid); |
265 | | |
266 | | enum kept_pack_type { |
267 | | KEPT_PACK_ON_DISK = (1 << 0), |
268 | | KEPT_PACK_IN_CORE = (1 << 1), |
269 | | }; |
270 | | |
271 | | /* |
272 | | * Count the number objects contained in the given packfile store. If |
273 | | * successful, the number of objects will be written to the `out` pointer. |
274 | | * |
275 | | * Return 0 on success, a negative error code otherwise. |
276 | | */ |
277 | | int packfile_store_count_objects(struct packfile_store *store, |
278 | | enum odb_count_objects_flags flags, |
279 | | unsigned long *out); |
280 | | |
281 | | /* |
282 | | * Retrieve the cache of kept packs from the given packfile store. Accepts a |
283 | | * combination of `kept_pack_type` flags. The cache is computed on demand and |
284 | | * will be recomputed whenever the flags change. |
285 | | */ |
286 | | struct packed_git **packfile_store_get_kept_pack_cache(struct packfile_store *store, |
287 | | unsigned flags); |
288 | | |
289 | | struct pack_window { |
290 | | struct pack_window *next; |
291 | | unsigned char *base; |
292 | | off_t offset; |
293 | | size_t len; |
294 | | unsigned int last_used; |
295 | | unsigned int inuse_cnt; |
296 | | }; |
297 | | |
298 | | struct pack_entry { |
299 | | off_t offset; |
300 | | struct packed_git *p; |
301 | | }; |
302 | | |
303 | | /* |
304 | | * Generate the filename to be used for a pack file with checksum "sha1" and |
305 | | * extension "ext". The result is written into the strbuf "buf", overwriting |
306 | | * any existing contents. A pointer to buf->buf is returned as a convenience. |
307 | | * |
308 | | * Example: odb_pack_name(out, sha1, "idx") => ".git/objects/pack/pack-1234..idx" |
309 | | */ |
310 | | char *odb_pack_name(struct repository *r, struct strbuf *buf, |
311 | | const unsigned char *hash, const char *ext); |
312 | | |
313 | | /* |
314 | | * Return the basename of the packfile, omitting any containing directory |
315 | | * (e.g., "pack-1234abcd[...].pack"). |
316 | | */ |
317 | | const char *pack_basename(struct packed_git *p); |
318 | | |
319 | | /* |
320 | | * Parse the pack idx file found at idx_path and create a packed_git struct |
321 | | * which can be used with find_pack_entry_one(). |
322 | | * |
323 | | * You probably don't want to use this function! It skips most of the normal |
324 | | * sanity checks (including whether we even have the matching .pack file), |
325 | | * and does not add the resulting packed_git struct to the internal list of |
326 | | * packs. You probably want add_packed_git() instead. |
327 | | */ |
328 | | struct packed_git *parse_pack_index(struct repository *r, unsigned char *sha1, |
329 | | const char *idx_path); |
330 | | |
331 | | typedef void each_file_in_pack_dir_fn(const char *full_path, size_t full_path_len, |
332 | | const char *file_name, void *data); |
333 | | void for_each_file_in_pack_subdir(const char *objdir, |
334 | | const char *subdir, |
335 | | each_file_in_pack_dir_fn fn, |
336 | | void *data); |
337 | | void for_each_file_in_pack_dir(const char *objdir, |
338 | | each_file_in_pack_dir_fn fn, |
339 | | void *data); |
340 | | |
341 | | /* |
342 | | * Iterate over all accessible packed objects without respect to reachability. |
343 | | * By default, this includes both local and alternate packs. |
344 | | * |
345 | | * Note that some objects may appear twice if they are found in multiple packs. |
346 | | * Each pack is visited in an unspecified order. By default, objects within a |
347 | | * pack are visited in pack-idx order (i.e., sorted by oid). |
348 | | */ |
349 | | typedef int each_packed_object_fn(const struct object_id *oid, |
350 | | struct packed_git *pack, |
351 | | uint32_t pos, |
352 | | void *data); |
353 | | int for_each_object_in_pack(struct packed_git *p, |
354 | | each_packed_object_fn, void *data, |
355 | | unsigned flags); |
356 | | |
357 | | /* |
358 | | * Iterate through all packed objects in the given packfile store and invoke |
359 | | * the callback function for each of them. If an object info request is given, |
360 | | * then the object info will be read for every individual object and passed to |
361 | | * the callback as if `packfile_store_read_object_info()` was called for the |
362 | | * object. |
363 | | * |
364 | | * The flags parameter is a combination of `odb_for_each_object_flags`. |
365 | | */ |
366 | | int packfile_store_for_each_object(struct packfile_store *store, |
367 | | const struct object_info *request, |
368 | | odb_for_each_object_cb cb, |
369 | | void *cb_data, |
370 | | unsigned flags); |
371 | | |
372 | | /* A hook to report invalid files in pack directory */ |
373 | 0 | #define PACKDIR_FILE_PACK 1 |
374 | 0 | #define PACKDIR_FILE_IDX 2 |
375 | 0 | #define PACKDIR_FILE_GARBAGE 4 |
376 | | extern void (*report_garbage)(unsigned seen_bits, const char *path); |
377 | | |
378 | | void pack_report(struct repository *repo); |
379 | | |
380 | | /* |
381 | | * mmap the index file for the specified packfile (if it is not |
382 | | * already mmapped). Return 0 on success. |
383 | | */ |
384 | | int open_pack_index(struct packed_git *); |
385 | | |
386 | | /* |
387 | | * munmap the index file for the specified packfile (if it is |
388 | | * currently mmapped). |
389 | | */ |
390 | | void close_pack_index(struct packed_git *); |
391 | | |
392 | | int close_pack_fd(struct packed_git *p); |
393 | | |
394 | | uint32_t get_pack_fanout(struct packed_git *p, uint32_t value); |
395 | | |
396 | | struct object_database; |
397 | | |
398 | | unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *); |
399 | | void close_pack_windows(struct packed_git *); |
400 | | void close_pack(struct packed_git *); |
401 | | void unuse_pack(struct pack_window **); |
402 | | void clear_delta_base_cache(void); |
403 | | struct packed_git *add_packed_git(struct repository *r, const char *path, |
404 | | size_t path_len, int local); |
405 | | |
406 | | /* |
407 | | * Unlink the .pack and associated extension files. |
408 | | * Does not unlink if 'force_delete' is false and the pack-file is |
409 | | * marked as ".keep". |
410 | | */ |
411 | | void unlink_pack_path(const char *pack_name, int force_delete); |
412 | | |
413 | | /* |
414 | | * Make sure that a pointer access into an mmap'd index file is within bounds, |
415 | | * and can provide at least 8 bytes of data. |
416 | | * |
417 | | * Note that this is only necessary for variable-length segments of the file |
418 | | * (like the 64-bit extended offset table), as we compare the size to the |
419 | | * fixed-length parts when we open the file. |
420 | | */ |
421 | | void check_pack_index_ptr(const struct packed_git *p, const void *ptr); |
422 | | |
423 | | /* |
424 | | * Perform binary search on a pack-index for a given oid. Packfile is expected to |
425 | | * have a valid pack-index. |
426 | | * |
427 | | * See 'bsearch_hash' for more information. |
428 | | */ |
429 | | int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32_t *result); |
430 | | |
431 | | /* |
432 | | * Write the oid of the nth object within the specified packfile into the first |
433 | | * parameter. Open the index if it is not already open. Returns 0 on success, |
434 | | * negative otherwise. |
435 | | */ |
436 | | int nth_packed_object_id(struct object_id *, struct packed_git *, uint32_t n); |
437 | | |
438 | | /* |
439 | | * Return the offset of the nth object within the specified packfile. |
440 | | * The index must already be opened. |
441 | | */ |
442 | | off_t nth_packed_object_offset(const struct packed_git *, uint32_t n); |
443 | | |
444 | | /* |
445 | | * If the object named by oid is present in the specified packfile, |
446 | | * return its offset within the packfile; otherwise, return 0. |
447 | | */ |
448 | | off_t find_pack_entry_one(const struct object_id *oid, struct packed_git *); |
449 | | |
450 | | int is_pack_valid(struct packed_git *); |
451 | | void *unpack_entry(struct repository *r, struct packed_git *, off_t, enum object_type *, unsigned long *); |
452 | | unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep); |
453 | | unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t); |
454 | | int unpack_object_header(struct packed_git *, struct pack_window **, off_t *, unsigned long *); |
455 | | off_t get_delta_base(struct packed_git *p, struct pack_window **w_curs, |
456 | | off_t *curpos, enum object_type type, |
457 | | off_t delta_obj_offset); |
458 | | |
459 | | int packfile_read_object_stream(struct odb_read_stream **out, |
460 | | const struct object_id *oid, |
461 | | struct packed_git *pack, |
462 | | off_t offset); |
463 | | |
464 | | void release_pack_memory(size_t); |
465 | | |
466 | | /* global flag to enable extra checks when accessing packed objects */ |
467 | | extern int do_check_packed_object_crc; |
468 | | |
469 | | /* |
470 | | * Look up the object info for a specific offset in the packfile. |
471 | | * Returns zero on success, a negative error code otherwise. |
472 | | */ |
473 | | int packed_object_info(struct packed_git *pack, |
474 | | off_t offset, struct object_info *); |
475 | | |
476 | | void mark_bad_packed_object(struct packed_git *, const struct object_id *); |
477 | | const struct packed_git *has_packed_and_bad(struct repository *, const struct object_id *); |
478 | | |
479 | | int has_object_pack(struct repository *r, const struct object_id *oid); |
480 | | int has_object_kept_pack(struct repository *r, const struct object_id *oid, |
481 | | unsigned flags); |
482 | | |
483 | | /* |
484 | | * Return 1 if an object in a promisor packfile is or refers to the given |
485 | | * object, 0 otherwise. |
486 | | */ |
487 | | int is_promisor_object(struct repository *r, const struct object_id *oid); |
488 | | |
489 | | /* |
490 | | * Expose a function for fuzz testing. |
491 | | * |
492 | | * load_idx() parses a block of memory as a packfile index and puts the results |
493 | | * into a struct packed_git. |
494 | | * |
495 | | * This function should not be used directly. It is exposed here only so that we |
496 | | * have a convenient entry-point for fuzz testing. For real uses, you should |
497 | | * probably use open_pack_index() instead. |
498 | | */ |
499 | | int load_idx(const char *path, const unsigned int hashsz, void *idx_map, |
500 | | size_t idx_size, struct packed_git *p); |
501 | | |
502 | | /* |
503 | | * Parse a --pack_header option as accepted by index-pack and unpack-objects, |
504 | | * turning it into the matching bytes we'd find in a pack. |
505 | | */ |
506 | | int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *len); |
507 | | |
508 | | #endif |