diff --git a/Makefile b/Makefile index 180e1e0..afa5d08 100644 --- a/Makefile +++ b/Makefile @@ -368,7 +368,7 @@ ifeq ($(uname_O),Cygwin) # There are conflicting reports about this. # On some boxes NO_MMAP is needed, and not so elsewhere. # Try commenting this out if you suspect MMAP is more efficient - NO_MMAP = YesPlease + #NO_MMAP = YesPlease NO_IPV6 = YesPlease X = .exe endif diff --git a/index-pack.c b/index-pack.c index 5f6d128..f1d11a0 100644 --- a/index-pack.c +++ b/index-pack.c @@ -277,25 +277,27 @@ static void *get_data_from_pack(struct object_entry *obj) { unsigned long from = obj[0].offset + obj[0].hdr_size; unsigned long len = obj[1].offset - from; - unsigned char *src, *data; + unsigned pg_offset = from % getpagesize(); + unsigned char *map, *data; z_stream stream; int st; - src = xmalloc(len); - if (pread(pack_fd, src, len, from) != len) - die("cannot pread pack file: %s", strerror(errno)); + map = mmap(NULL, len + pg_offset, PROT_READ, MAP_PRIVATE, + pack_fd, from - pg_offset); + if (map == MAP_FAILED) + die("cannot mmap pack file: %s", strerror(errno)); data = xmalloc(obj->size); memset(&stream, 0, sizeof(stream)); stream.next_out = data; stream.avail_out = obj->size; - stream.next_in = src; + stream.next_in = map + pg_offset; stream.avail_in = len; inflateInit(&stream); while ((st = inflate(&stream, Z_FINISH)) == Z_OK); inflateEnd(&stream); if (st != Z_STREAM_END || stream.total_out != obj->size) die("serious inflate inconsistency"); - free(src); + munmap(map, len + pg_offset); return data; } diff --git a/t/t5610-clone-fail.sh b/t/t5610-clone-fail.sh new file mode 100755 index 0000000..d46c255 --- /dev/null +++ b/t/t5610-clone-fail.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# + +test_description='test git-clone failure on cygwin using pread() +' + +. ./test-lib.sh + +# Need a repo to clone +test_create_repo foo2 + +GIT_AUTHOR_EMAIL=xxxxxxxx@yyyyyyyy.yyyyy.yyyyyyy.yyy +GIT_COMMITTER_EMAIL=xxxxxxxx@yyyyyyyy.yyyyy.yyyyyyy.yyy +export GIT_AUTHOR_EMAIL +export GIT_COMMITTER_EMAIL + +(cd foo2 && echo "Hello" > file && git add file && git commit -m 'add file' >/dev/null 2>&1) +(cd foo2 && echo "Hello2" >> file && git commit -a -m 'test' >/dev/null 2>&1) + +test_expect_success \ + 'clone with resolving' \ + 'git-clone foo2 bar2' + +test_done