int nr_objects, err, i;
 
        /* Header consistency check */
-       hdr = p->pack_base;
+       pack_base = p->windows->base;
+       hdr = (struct pack_header*)pack_base;
        if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
                return error("Packfile %s signature mismatch", p->pack_name);
        if (!pack_version_ok(hdr->hdr_version))
                             num_packed_objects(p));
 
        SHA1_Init(&ctx);
-       pack_base = p->pack_base;
        SHA1_Update(&ctx, pack_base, pack_size - 20);
        SHA1_Final(sha1, &ctx);
        if (hashcmp(sha1, (unsigned char *)pack_base + pack_size - 20))
        int nr_objects, i;
        unsigned int chain_histogram[MAX_CHAIN];
 
-       hdr = p->pack_base;
+       hdr = (struct pack_header*)p->windows->base;
        nr_objects = ntohl(hdr->hdr_entries);
        memset(chain_histogram, 0, sizeof(chain_histogram));
 
 
        struct packed_git *p, *lru = NULL;
 
        for (p = packed_git; p; p = p->next) {
-               if (p->pack_use_cnt || !p->pack_base)
+               if (!p->windows || p->windows->inuse_cnt)
                        continue;
-               if (!lru || p->pack_last_used < lru->pack_last_used)
+               if (!lru || p->windows->last_used < lru->windows->last_used)
                        lru = p;
        }
        if (!lru)
                return 0;
-       munmap(lru->pack_base, lru->pack_size);
-       lru->pack_base = NULL;
+       munmap(lru->windows->base, lru->windows->len);
+       free(lru->windows);
+       lru->windows = NULL;
        return 1;
 }
 
 void unuse_packed_git(struct packed_git *p)
 {
-       p->pack_use_cnt--;
+       if (p->windows)
+               p->windows->inuse_cnt--;
 }
 
 int use_packed_git(struct packed_git *p)
                        die("packfile %s not a regular file", p->pack_name);
                p->pack_size = st.st_size;
        }
-       if (!p->pack_base) {
+       if (!p->windows) {
                int fd;
                struct stat st;
-               void *map;
+               struct pack_window *win;
                struct pack_header *hdr;
 
                pack_mapped += p->pack_size;
                }
                if (st.st_size != p->pack_size)
                        die("packfile %s size mismatch.", p->pack_name);
-               map = mmap(NULL, p->pack_size, PROT_READ, MAP_PRIVATE, fd, 0);
+               win = xcalloc(1, sizeof(*win));
+               win->len = p->pack_size;
+               win->base = mmap(NULL, p->pack_size, PROT_READ, MAP_PRIVATE, fd, 0);
                close(fd);
-               if (map == MAP_FAILED)
+               if (win->base == MAP_FAILED)
                        die("packfile %s cannot be mapped.", p->pack_name);
-               p->pack_base = map;
+               p->windows = win;
 
                /* Check if we understand this pack file.  If we don't we're
                 * likely too old to handle it.
                 */
-               hdr = map;
+               hdr = (struct pack_header*)win->base;
                if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
                        die("packfile %s isn't actually a pack.", p->pack_name);
                if (!pack_version_ok(hdr->hdr_version))
                 */
                if (hashcmp((unsigned char *)(p->index_base) +
                            p->index_size - 40,
-                           (unsigned char *)p->pack_base +
+                           p->windows->base +
                            p->pack_size - 20)) {
                        die("packfile %s does not match index.", p->pack_name);
                }
        }
-       p->pack_last_used = pack_used_ctr++;
-       p->pack_use_cnt++;
+       p->windows->last_used = pack_used_ctr++;
+       p->windows->inuse_cnt++;
        return 0;
 }
 
        p->pack_size = st.st_size;
        p->index_base = idx_map;
        p->next = NULL;
-       p->pack_base = NULL;
-       p->pack_last_used = 0;
-       p->pack_use_cnt = 0;
+       p->windows = NULL;
        p->pack_local = local;
        if ((path_len > 44) && !get_sha1_hex(path + path_len - 44, sha1))
                hashcpy(p->sha1, sha1);
        p->pack_size = 0;
        p->index_base = idx_map;
        p->next = NULL;
-       p->pack_base = NULL;
-       p->pack_last_used = 0;
-       p->pack_use_cnt = 0;
+       p->windows = NULL;
        hashcpy(p->sha1, sha1);
        return p;
 }
                                    unsigned long delta_obj_offset,
                                    unsigned long *base_obj_offset)
 {
-       unsigned char *base_info = (unsigned char *) p->pack_base + offset;
+       unsigned char *base_info = p->windows->base + offset;
        unsigned long base_offset;
 
        /* there must be at least 20 bytes left regardless of delta type */
 
                memset(&stream, 0, sizeof(stream));
 
-               stream.next_in = (unsigned char *) p->pack_base + offset;
+               stream.next_in = p->windows->base + offset;
                stream.avail_in = p->pack_size - offset;
                stream.next_out = delta_head;
                stream.avail_out = sizeof(delta_head);
        if (p->pack_size <= offset)
                die("object offset outside of pack file");
 
-       used = unpack_object_header_gently((unsigned char *)p->pack_base +
-                                          offset,
+       used = unpack_object_header_gently(p->windows->base + offset,
                                           p->pack_size - offset, type, sizep);
        if (!used)
                die("object offset outside of pack file");
                        if (p->pack_size <= offset + 20)
                                die("pack file %s records an incomplete delta base",
                                    p->pack_name);
-                       next_sha1 = (unsigned char *) p->pack_base + offset;
+                       next_sha1 = p->windows->base + offset;
                        if (*delta_chain_length == 0)
                                hashcpy(base_sha1, next_sha1);
                        offset = find_pack_entry_one(next_sha1, p);
        buffer = xmalloc(size + 1);
        buffer[size] = 0;
        memset(&stream, 0, sizeof(stream));
-       stream.next_in = (unsigned char*)p->pack_base + offset;
+       stream.next_in = p->windows->base + offset;
        stream.avail_in = p->pack_size - offset;
        stream.next_out = buffer;
        stream.avail_out = size;