2 * Copyright (C) 2009-2012 the libgit2 contributors
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
11 #include "delta-apply.h"
12 #include "sha1_lookup.h"
19 static int packfile_open(struct git_pack_file
*p
);
20 static git_off_t
nth_packed_object_offset(const struct git_pack_file
*p
, uint32_t n
);
21 int packfile_unpack_compressed(
23 struct git_pack_file
*p
,
29 /* Can find the offset of an object given
30 * a prefix of an identifier.
31 * Throws GIT_EAMBIGUOUSOIDPREFIX if short oid
32 * is ambiguous within the pack.
33 * This method assumes that len is between
34 * GIT_OID_MINPREFIXLEN and GIT_OID_HEXSZ.
36 static int pack_entry_find_offset(
37 git_off_t
*offset_out
,
39 struct git_pack_file
*p
,
40 const git_oid
*short_oid
,
43 static int packfile_error(const char *message
)
45 giterr_set(GITERR_ODB
, "Invalid pack file - %s", message
);
49 /***********************************************************
53 ***********************************************************/
55 static void pack_index_free(struct git_pack_file
*p
)
61 if (p
->index_map
.data
) {
62 git_futils_mmap_free(&p
->index_map
);
63 p
->index_map
.data
= NULL
;
67 static int pack_index_check(const char *path
, struct git_pack_file
*p
)
69 struct git_pack_idx_header
*hdr
;
70 uint32_t version
, nr
, i
, *index
;
75 /* TODO: properly open the file without access time using O_NOATIME */
76 git_file fd
= git_futils_open_ro(path
);
80 if (p_fstat(fd
, &st
) < 0 ||
81 !S_ISREG(st
.st_mode
) ||
82 !git__is_sizet(st
.st_size
) ||
83 (idx_size
= (size_t)st
.st_size
) < 4 * 256 + 20 + 20)
86 giterr_set(GITERR_OS
, "Failed to check pack index.");
90 error
= git_futils_mmap_ro(&p
->index_map
, fd
, 0, idx_size
);
97 hdr
= idx_map
= p
->index_map
.data
;
99 if (hdr
->idx_signature
== htonl(PACK_IDX_SIGNATURE
)) {
100 version
= ntohl(hdr
->idx_version
);
102 if (version
< 2 || version
> 2) {
103 git_futils_mmap_free(&p
->index_map
);
104 return packfile_error("unsupported index version");
114 index
+= 2; /* skip index header */
116 for (i
= 0; i
< 256; i
++) {
117 uint32_t n
= ntohl(index
[i
]);
119 git_futils_mmap_free(&p
->index_map
);
120 return packfile_error("index is non-monotonic");
128 * - 256 index entries 4 bytes each
129 * - 24-byte entries * nr (20-byte sha1 + 4-byte offset)
130 * - 20-byte SHA1 of the packfile
131 * - 20-byte SHA1 file checksum
133 if (idx_size
!= 4*256 + nr
* 24 + 20 + 20) {
134 git_futils_mmap_free(&p
->index_map
);
135 return packfile_error("index is corrupted");
137 } else if (version
== 2) {
140 * - 8 bytes of header
141 * - 256 index entries 4 bytes each
142 * - 20-byte sha1 entry * nr
143 * - 4-byte crc entry * nr
144 * - 4-byte offset entry * nr
145 * - 20-byte SHA1 of the packfile
146 * - 20-byte SHA1 file checksum
147 * And after the 4-byte offset table might be a
148 * variable sized table containing 8-byte entries
149 * for offsets larger than 2^31.
151 unsigned long min_size
= 8 + 4*256 + nr
*(20 + 4 + 4) + 20 + 20;
152 unsigned long max_size
= min_size
;
155 max_size
+= (nr
- 1)*8;
157 if (idx_size
< min_size
|| idx_size
> max_size
) {
158 git_futils_mmap_free(&p
->index_map
);
159 return packfile_error("wrong index size");
163 p
->index_version
= version
;
168 static int pack_index_open(struct git_pack_file
*p
)
172 size_t name_len
, offset
;
174 if (p
->index_map
.data
)
177 idx_name
= git__strdup(p
->pack_name
);
178 GITERR_CHECK_ALLOC(idx_name
);
180 name_len
= strlen(idx_name
);
181 offset
= name_len
- strlen(".pack");
182 assert(offset
< name_len
); /* make sure no underflow */
184 strncpy(idx_name
+ offset
, ".idx", name_len
- offset
);
186 error
= pack_index_check(idx_name
, p
);
192 static unsigned char *pack_window_open(
193 struct git_pack_file
*p
,
194 git_mwindow
**w_cursor
,
198 if (p
->mwf
.fd
== -1 && packfile_open(p
) < 0)
201 /* Since packfiles end in a hash of their content and it's
202 * pointless to ask for an offset into the middle of that
203 * hash, and the pack_window_contains function above wouldn't match
204 * don't allow an offset too close to the end of the file.
206 if (offset
> (p
->mwf
.size
- 20))
209 return git_mwindow_open(&p
->mwf
, w_cursor
, offset
, 20, left
);
212 static int packfile_unpack_header1(
213 unsigned long *usedp
,
216 const unsigned char *buf
,
220 unsigned long size
, c
;
221 unsigned long used
= 0;
224 *type
= (c
>> 4) & 7;
231 if (bitsizeof(long) <= shift
) {
237 size
+= (c
& 0x7f) << shift
;
241 *sizep
= (size_t)size
;
246 int git_packfile_unpack_header(
249 git_mwindow_file
*mwf
,
250 git_mwindow
**w_curs
,
258 /* pack_window_open() assures us we have [base, base + 20) available
259 * as a range that we can look at at. (Its actually the hash
260 * size that is assured.) With our object header encoding
261 * the maximum deflated object size is 2^137, which is just
262 * insane, so we know won't exceed what we have been given.
264 // base = pack_window_open(p, w_curs, *curpos, &left);
265 base
= git_mwindow_open(mwf
, w_curs
, *curpos
, 20, &left
);
269 ret
= packfile_unpack_header1(&used
, size_p
, type_p
, base
, left
);
270 git_mwindow_close(w_curs
);
271 if (ret
== GIT_EBUFS
)
274 return packfile_error("header length is zero");
280 int git_packfile_resolve_header(
283 struct git_pack_file
*p
,
286 git_mwindow
*w_curs
= NULL
;
287 git_off_t curpos
= offset
;
290 git_off_t base_offset
;
293 error
= git_packfile_unpack_header(&size
, &type
, &p
->mwf
, &w_curs
, &curpos
);
294 git_mwindow_close(&w_curs
);
298 if (type
== GIT_OBJ_OFS_DELTA
|| type
== GIT_OBJ_REF_DELTA
) {
301 base_offset
= get_delta_base(p
, &w_curs
, &curpos
, type
, offset
);
302 git_mwindow_close(&w_curs
);
303 error
= packfile_unpack_compressed(&delta
, p
, &w_curs
, &curpos
, size
, type
);
304 git_mwindow_close(&w_curs
);
307 error
= git__delta_read_header(delta
.data
, delta
.len
, &base_size
, size_p
);
308 git__free(delta
.data
);
314 while (type
== GIT_OBJ_OFS_DELTA
|| type
== GIT_OBJ_REF_DELTA
) {
315 curpos
= base_offset
;
316 error
= git_packfile_unpack_header(&size
, &type
, &p
->mwf
, &w_curs
, &curpos
);
317 git_mwindow_close(&w_curs
);
320 if (type
!= GIT_OBJ_OFS_DELTA
&& type
!= GIT_OBJ_REF_DELTA
)
322 base_offset
= get_delta_base(p
, &w_curs
, &curpos
, type
, base_offset
);
323 git_mwindow_close(&w_curs
);
330 static int packfile_unpack_delta(
332 struct git_pack_file
*p
,
333 git_mwindow
**w_curs
,
336 git_otype delta_type
,
337 git_off_t obj_offset
)
339 git_off_t base_offset
;
340 git_rawobj base
, delta
;
343 base_offset
= get_delta_base(p
, w_curs
, curpos
, delta_type
, obj_offset
);
344 git_mwindow_close(w_curs
);
345 if (base_offset
== 0)
346 return packfile_error("delta offset is zero");
347 if (base_offset
< 0) /* must actually be an error code */
348 return (int)base_offset
;
350 error
= git_packfile_unpack(&base
, p
, &base_offset
);
353 * TODO: git.git tries to load the base from other packfiles
356 * We'll need to do this in order to support thin packs.
361 error
= packfile_unpack_compressed(&delta
, p
, w_curs
, curpos
, delta_size
, delta_type
);
362 git_mwindow_close(w_curs
);
364 git__free(base
.data
);
368 obj
->type
= base
.type
;
369 error
= git__delta_apply(obj
, base
.data
, base
.len
, delta
.data
, delta
.len
);
371 git__free(base
.data
);
372 git__free(delta
.data
);
374 /* TODO: we might want to cache this. eventually */
375 //add_delta_base_cache(p, base_offset, base, base_size, *type);
377 return error
; /* error set by git__delta_apply */
380 int git_packfile_unpack(
382 struct git_pack_file
*p
,
383 git_off_t
*obj_offset
)
385 git_mwindow
*w_curs
= NULL
;
386 git_off_t curpos
= *obj_offset
;
393 * TODO: optionally check the CRC on the packfile
398 obj
->type
= GIT_OBJ_BAD
;
400 error
= git_packfile_unpack_header(&size
, &type
, &p
->mwf
, &w_curs
, &curpos
);
401 git_mwindow_close(&w_curs
);
407 case GIT_OBJ_OFS_DELTA
:
408 case GIT_OBJ_REF_DELTA
:
409 error
= packfile_unpack_delta(
410 obj
, p
, &w_curs
, &curpos
,
411 size
, type
, *obj_offset
);
418 error
= packfile_unpack_compressed(
419 obj
, p
, &w_curs
, &curpos
,
424 error
= packfile_error("invalid packfile type in header");;
428 *obj_offset
= curpos
;
432 static void *use_git_alloc(void *opaq
, unsigned int count
, unsigned int size
)
435 return git__calloc(count
, size
);
438 static void use_git_free(void *opaq
, void *ptr
)
444 int git_packfile_stream_open(git_packfile_stream
*obj
, struct git_pack_file
*p
, git_off_t curpos
)
448 memset(obj
, 0, sizeof(git_packfile_stream
));
449 obj
->curpos
= curpos
;
451 obj
->zstream
.zalloc
= use_git_alloc
;
452 obj
->zstream
.zfree
= use_git_free
;
453 obj
->zstream
.next_in
= Z_NULL
;
454 obj
->zstream
.next_out
= Z_NULL
;
455 st
= inflateInit(&obj
->zstream
);
458 giterr_set(GITERR_ZLIB
, "Failed to inflate packfile");
465 ssize_t
git_packfile_stream_read(git_packfile_stream
*obj
, void *buffer
, size_t len
)
474 in
= pack_window_open(obj
->p
, &obj
->mw
, obj
->curpos
, &obj
->zstream
.avail_in
);
478 obj
->zstream
.next_out
= buffer
;
479 obj
->zstream
.avail_out
= len
;
480 obj
->zstream
.next_in
= in
;
482 st
= inflate(&obj
->zstream
, Z_SYNC_FLUSH
);
483 git_mwindow_close(&obj
->mw
);
485 obj
->curpos
+= obj
->zstream
.next_in
- in
;
486 written
= len
- obj
->zstream
.avail_out
;
488 if (st
!= Z_OK
&& st
!= Z_STREAM_END
) {
489 giterr_set(GITERR_ZLIB
, "Failed to inflate packfile");
493 if (st
== Z_STREAM_END
)
497 /* If we didn't write anything out but we're not done, we need more data */
498 if (!written
&& st
!= Z_STREAM_END
)
505 void git_packfile_stream_free(git_packfile_stream
*obj
)
507 inflateEnd(&obj
->zstream
);
510 int packfile_unpack_compressed(
512 struct git_pack_file
*p
,
513 git_mwindow
**w_curs
,
520 unsigned char *buffer
, *in
;
522 buffer
= git__calloc(1, size
+ 1);
523 GITERR_CHECK_ALLOC(buffer
);
525 memset(&stream
, 0, sizeof(stream
));
526 stream
.next_out
= buffer
;
527 stream
.avail_out
= (uInt
)size
+ 1;
528 stream
.zalloc
= use_git_alloc
;
529 stream
.zfree
= use_git_free
;
531 st
= inflateInit(&stream
);
534 giterr_set(GITERR_ZLIB
, "Failed to inflate packfile");
540 in
= pack_window_open(p
, w_curs
, *curpos
, &stream
.avail_in
);
542 st
= inflate(&stream
, Z_FINISH
);
543 git_mwindow_close(w_curs
);
545 if (!stream
.avail_out
)
546 break; /* the payload is larger than it should be */
548 if (st
== Z_BUF_ERROR
&& in
== NULL
) {
554 *curpos
+= stream
.next_in
- in
;
555 } while (st
== Z_OK
|| st
== Z_BUF_ERROR
);
559 if ((st
!= Z_STREAM_END
) || stream
.total_out
!= size
) {
561 giterr_set(GITERR_ZLIB
, "Failed to inflate packfile");
572 * curpos is where the data starts, delta_obj_offset is the where the
575 git_off_t
get_delta_base(
576 struct git_pack_file
*p
,
577 git_mwindow
**w_curs
,
580 git_off_t delta_obj_offset
)
582 unsigned int left
= 0;
583 unsigned char *base_info
;
584 git_off_t base_offset
;
587 base_info
= pack_window_open(p
, w_curs
, *curpos
, &left
);
588 /* Assumption: the only reason this would fail is because the file is too small */
589 if (base_info
== NULL
)
591 /* pack_window_open() assured us we have [base_info, base_info + 20)
592 * as a range that we can look at without walking off the
593 * end of the mapped window. Its actually the hash size
594 * that is assured. An OFS_DELTA longer than the hash size
595 * is stupid, as then a REF_DELTA would be smaller to store.
597 if (type
== GIT_OBJ_OFS_DELTA
) {
599 unsigned char c
= base_info
[used
++];
600 base_offset
= c
& 127;
605 if (!base_offset
|| MSB(base_offset
, 7))
606 return 0; /* overflow */
607 c
= base_info
[used
++];
608 base_offset
= (base_offset
<< 7) + (c
& 127);
610 base_offset
= delta_obj_offset
- base_offset
;
611 if (base_offset
<= 0 || base_offset
>= delta_obj_offset
)
612 return 0; /* out of bound */
614 } else if (type
== GIT_OBJ_REF_DELTA
) {
615 /* If we have the cooperative cache, search in it first */
618 struct git_pack_entry key
;
620 git_oid_fromraw(&key
.sha1
, base_info
);
621 pos
= git_vector_bsearch(&p
->cache
, &key
);
624 return ((struct git_pack_entry
*)git_vector_get(&p
->cache
, pos
))->offset
;
627 /* The base entry _must_ be in the same pack */
628 if (pack_entry_find_offset(&base_offset
, &unused
, p
, (git_oid
*)base_info
, GIT_OID_HEXSZ
) < 0)
629 return packfile_error("base entry delta is not in the same pack");
637 /***********************************************************
641 ***********************************************************/
643 static struct git_pack_file
*packfile_alloc(size_t extra
)
645 struct git_pack_file
*p
= git__calloc(1, sizeof(*p
) + extra
);
652 void packfile_free(struct git_pack_file
*p
)
656 /* clear_delta_base_cache(); */
657 git_mwindow_free_all(&p
->mwf
);
658 git_mwindow_file_deregister(&p
->mwf
);
665 git__free(p
->bad_object_sha1
);
669 static int packfile_open(struct git_pack_file
*p
)
672 struct git_pack_header hdr
;
674 unsigned char *idx_sha1
;
676 assert(p
->index_map
.data
);
678 if (!p
->index_map
.data
&& pack_index_open(p
) < 0)
679 return git_odb__error_notfound("failed to open packfile", NULL
);
681 /* TODO: open with noatime */
682 p
->mwf
.fd
= git_futils_open_ro(p
->pack_name
);
688 if (p_fstat(p
->mwf
.fd
, &st
) < 0 ||
689 git_mwindow_file_register(&p
->mwf
) < 0)
692 /* If we created the struct before we had the pack we lack size. */
694 if (!S_ISREG(st
.st_mode
))
696 p
->mwf
.size
= (git_off_t
)st
.st_size
;
697 } else if (p
->mwf
.size
!= st
.st_size
)
701 /* We leave these file descriptors open with sliding mmap;
702 * there is no point keeping them open across exec(), though.
704 fd_flag
= fcntl(p
->mwf
.fd
, F_GETFD
, 0);
708 fd_flag
|= FD_CLOEXEC
;
709 if (fcntl(p
->pack_fd
, F_SETFD
, fd_flag
) == -1)
713 /* Verify we recognize this pack file format. */
714 if (p_read(p
->mwf
.fd
, &hdr
, sizeof(hdr
)) < 0 ||
715 hdr
.hdr_signature
!= htonl(PACK_SIGNATURE
) ||
716 !pack_version_ok(hdr
.hdr_version
))
719 /* Verify the pack matches its index. */
720 if (p
->num_objects
!= ntohl(hdr
.hdr_entries
) ||
721 p_lseek(p
->mwf
.fd
, p
->mwf
.size
- GIT_OID_RAWSZ
, SEEK_SET
) == -1 ||
722 p_read(p
->mwf
.fd
, sha1
.id
, GIT_OID_RAWSZ
) < 0)
725 idx_sha1
= ((unsigned char *)p
->index_map
.data
) + p
->index_map
.len
- 40;
727 if (git_oid_cmp(&sha1
, (git_oid
*)idx_sha1
) == 0)
731 giterr_set(GITERR_OS
, "Invalid packfile '%s'", p
->pack_name
);
737 int git_packfile_check(struct git_pack_file
**pack_out
, const char *path
)
740 struct git_pack_file
*p
;
744 path_len
= strlen(path
);
745 p
= packfile_alloc(path_len
+ 2);
746 GITERR_CHECK_ALLOC(p
);
749 * Make sure a corresponding .pack file exists and that
750 * the index looks sane.
752 path_len
-= strlen(".idx");
755 return git_odb__error_notfound("invalid packfile path", NULL
);
758 memcpy(p
->pack_name
, path
, path_len
);
760 strcpy(p
->pack_name
+ path_len
, ".keep");
761 if (git_path_exists(p
->pack_name
) == true)
764 strcpy(p
->pack_name
+ path_len
, ".pack");
765 if (p_stat(p
->pack_name
, &st
) < 0 || !S_ISREG(st
.st_mode
)) {
767 return git_odb__error_notfound("packfile not found", NULL
);
770 /* ok, it looks sane as far as we can check without
771 * actually mapping the pack file.
773 p
->mwf
.size
= st
.st_size
;
775 p
->mtime
= (git_time_t
)st
.st_mtime
;
777 /* see if we can parse the sha1 oid in the packfile name */
779 git_oid_fromstr(&p
->sha1
, path
+ path_len
- GIT_OID_HEXSZ
) < 0)
780 memset(&p
->sha1
, 0x0, GIT_OID_RAWSZ
);
787 /***********************************************************
789 * PACKFILE ENTRY SEARCH INTERNALS
791 ***********************************************************/
793 static git_off_t
nth_packed_object_offset(const struct git_pack_file
*p
, uint32_t n
)
795 const unsigned char *index
= p
->index_map
.data
;
797 if (p
->index_version
== 1) {
798 return ntohl(*((uint32_t *)(index
+ 24 * n
)));
801 index
+= 8 + p
->num_objects
* (20 + 4);
802 off
= ntohl(*((uint32_t *)(index
+ 4 * n
)));
803 if (!(off
& 0x80000000))
805 index
+= p
->num_objects
* 4 + (off
& 0x7fffffff) * 8;
806 return (((uint64_t)ntohl(*((uint32_t *)(index
+ 0)))) << 32) |
807 ntohl(*((uint32_t *)(index
+ 4)));
811 static int git__memcmp4(const void *a
, const void *b
) {
812 return memcmp(a
, b
, 4);
815 int git_pack_foreach_entry(
816 struct git_pack_file
*p
,
817 git_odb_foreach_cb cb
,
820 const unsigned char *index
= p
->index_map
.data
, *current
;
826 if ((error
= pack_index_open(p
)) < 0)
829 assert(p
->index_map
.data
);
831 index
= p
->index_map
.data
;
834 if (p
->index_version
> 1) {
840 if (p
->oids
== NULL
) {
841 git_vector offsets
, oids
;
844 if ((error
= git_vector_init(&oids
, p
->num_objects
, NULL
)))
847 if ((error
= git_vector_init(&offsets
, p
->num_objects
, git__memcmp4
)))
850 if (p
->index_version
> 1) {
851 const unsigned char *off
= index
+ 24 * p
->num_objects
;
852 for (i
= 0; i
< p
->num_objects
; i
++)
853 git_vector_insert(&offsets
, (void*)&off
[4 * i
]);
854 git_vector_sort(&offsets
);
855 git_vector_foreach(&offsets
, i
, current
)
856 git_vector_insert(&oids
, (void*)&index
[5 * (current
- off
)]);
858 for (i
= 0; i
< p
->num_objects
; i
++)
859 git_vector_insert(&offsets
, (void*)&index
[24 * i
]);
860 git_vector_sort(&offsets
);
861 git_vector_foreach(&offsets
, i
, current
)
862 git_vector_insert(&oids
, (void*)¤t
[4]);
864 git_vector_free(&offsets
);
865 p
->oids
= (git_oid
**)oids
.contents
;
868 for (i
= 0; i
< p
->num_objects
; i
++)
869 if (cb(p
->oids
[i
], data
))
875 static int pack_entry_find_offset(
876 git_off_t
*offset_out
,
878 struct git_pack_file
*p
,
879 const git_oid
*short_oid
,
882 const uint32_t *level1_ofs
= p
->index_map
.data
;
883 const unsigned char *index
= p
->index_map
.data
;
884 unsigned hi
, lo
, stride
;
886 const unsigned char *current
= 0;
893 if ((error
= pack_index_open(p
)) < 0)
896 assert(p
->index_map
.data
);
898 index
= p
->index_map
.data
;
899 level1_ofs
= p
->index_map
.data
;
902 if (p
->index_version
> 1) {
908 hi
= ntohl(level1_ofs
[(int)short_oid
->id
[0]]);
909 lo
= ((short_oid
->id
[0] == 0x0) ? 0 : ntohl(level1_ofs
[(int)short_oid
->id
[0] - 1]));
911 if (p
->index_version
> 1) {
918 #ifdef INDEX_DEBUG_LOOKUP
919 printf("%02x%02x%02x... lo %u hi %u nr %d\n",
920 short_oid
->id
[0], short_oid
->id
[1], short_oid
->id
[2], lo
, hi
, p
->num_objects
);
923 /* Use git.git lookup code */
924 pos
= sha1_entry_pos(index
, stride
, 0, lo
, hi
, p
->num_objects
, short_oid
->id
);
927 /* An object matching exactly the oid was found */
929 current
= index
+ pos
* stride
;
931 /* No object was found */
932 /* pos refers to the object with the "closest" oid to short_oid */
934 if (pos
< (int)p
->num_objects
) {
935 current
= index
+ pos
* stride
;
937 if (!git_oid_ncmp(short_oid
, (const git_oid
*)current
, len
))
942 if (found
&& len
!= GIT_OID_HEXSZ
&& pos
+ 1 < (int)p
->num_objects
) {
943 /* Check for ambiguousity */
944 const unsigned char *next
= current
+ stride
;
946 if (!git_oid_ncmp(short_oid
, (const git_oid
*)next
, len
)) {
952 return git_odb__error_notfound("failed to find offset for pack entry", short_oid
);
954 return git_odb__error_ambiguous("found multiple offsets for pack entry");
955 *offset_out
= nth_packed_object_offset(p
, pos
);
956 git_oid_fromraw(found_oid
, current
);
958 #ifdef INDEX_DEBUG_LOOKUP
960 unsigned char hex_sha1
[GIT_OID_HEXSZ
+ 1];
961 git_oid_fmt(hex_sha1
, found_oid
);
962 hex_sha1
[GIT_OID_HEXSZ
] = '\0';
963 printf("found lo=%d %s\n", lo
, hex_sha1
);
969 int git_pack_entry_find(
970 struct git_pack_entry
*e
,
971 struct git_pack_file
*p
,
972 const git_oid
*short_oid
,
981 if (len
== GIT_OID_HEXSZ
&& p
->num_bad_objects
) {
983 for (i
= 0; i
< p
->num_bad_objects
; i
++)
984 if (git_oid_cmp(short_oid
, &p
->bad_object_sha1
[i
]) == 0)
985 return packfile_error("bad object found in packfile");
988 error
= pack_entry_find_offset(&offset
, &found_oid
, p
, short_oid
, len
);
992 /* we found a unique entry in the index;
993 * make sure the packfile backing the index
994 * still exists on disk */
995 if (p
->mwf
.fd
== -1 && (error
= packfile_open(p
)) < 0)
1001 git_oid_cpy(&e
->sha1
, &found_oid
);