#include "commit.h"
#include "tag.h"
#include "tree.h"
-#include <sys/time.h>
-#include <signal.h>
static const char index_pack_usage[] =
"git-index-pack [-v] [-o <index-file>] [{ ---keep | --keep=<msg> }] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }";
static unsigned char input_buffer[4096];
static unsigned long input_offset, input_len, consumed_bytes;
static SHA_CTX input_ctx;
-static int input_fd, output_fd, mmap_fd;
+static int input_fd, output_fd, pack_fd;
/* Discard current buffer used content. */
static void flush(void)
if (output_fd >= 0)
write_or_die(output_fd, input_buffer, input_offset);
SHA1_Update(&input_ctx, input_buffer, input_offset);
- memcpy(input_buffer, input_buffer + input_offset, input_len);
+ memmove(input_buffer, input_buffer + input_offset, input_len);
input_offset = 0;
}
}
output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
if (output_fd < 0)
die("unable to create %s: %s\n", pack_name, strerror(errno));
- mmap_fd = output_fd;
+ pack_fd = output_fd;
} else {
input_fd = open(pack_name, O_RDONLY);
if (input_fd < 0)
die("cannot open packfile '%s': %s",
pack_name, strerror(errno));
output_fd = -1;
- mmap_fd = input_fd;
+ pack_fd = input_fd;
}
SHA1_Init(&input_ctx);
return pack_name;
case OBJ_TAG:
break;
default:
- bad_object(obj->offset, "bad object type %d", obj->type);
+ bad_object(obj->offset, "unknown object type %d", obj->type);
}
obj->hdr_size = consumed_bytes - obj->offset;
{
unsigned long from = obj[0].offset + obj[0].hdr_size;
unsigned long len = obj[1].offset - from;
- unsigned pg_offset = from % getpagesize();
- unsigned char *map, *data;
+ unsigned long rdy = 0;
+ unsigned char *src, *data;
z_stream stream;
int st;
- map = mmap(NULL, len + pg_offset, PROT_READ, MAP_PRIVATE,
- mmap_fd, from - pg_offset);
- if (map == MAP_FAILED)
- die("cannot mmap pack file: %s", strerror(errno));
+ src = xmalloc(len);
+ data = src;
+ do {
+ ssize_t n = pread(pack_fd, data + rdy, len - rdy, from + rdy);
+ if (n <= 0)
+ die("cannot pread pack file: %s", strerror(errno));
+ rdy += n;
+ } while (rdy < len);
data = xmalloc(obj->size);
memset(&stream, 0, sizeof(stream));
stream.next_out = data;
stream.avail_out = obj->size;
- stream.next_in = map + pg_offset;
+ stream.next_in = src;
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");
- munmap(map, len + pg_offset);
+ free(src);
return data;
}
/* If input_fd is a file, we should have reached its end now. */
if (fstat(input_fd, &st))
die("cannot fstat packfile: %s", strerror(errno));
- if (S_ISREG(st.st_mode) && st.st_size != consumed_bytes)
+ if (S_ISREG(st.st_mode) &&
+ lseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size)
die("pack has junk at the end");
if (!nr_deltas)
struct delta_entry *d = sorted_by_pos[i];
void *data;
unsigned long size;
- char type[10];
- enum object_type obj_type;
+ enum object_type type;
int j, first, last;
if (objects[d->obj_no].real_type != OBJ_REF_DELTA)
continue;
- data = read_sha1_file(d->base.sha1, type, &size);
+ data = read_sha1_file(d->base.sha1, &type, &size);
if (!data)
continue;
- if (!strcmp(type, blob_type)) obj_type = OBJ_BLOB;
- else if (!strcmp(type, tree_type)) obj_type = OBJ_TREE;
- else if (!strcmp(type, commit_type)) obj_type = OBJ_COMMIT;
- else if (!strcmp(type, tag_type)) obj_type = OBJ_TAG;
- else die("base object %s is of type '%s'",
- sha1_to_hex(d->base.sha1), type);
find_delta_children(&d->base, &first, &last);
for (j = first; j <= last; j++) {
struct object_entry *child = objects + deltas[j].obj_no;
if (child->real_type == OBJ_REF_DELTA)
- resolve_delta(child, data, size, obj_type);
+ resolve_delta(child, data, size, type);
}
- append_obj_to_pack(data, size, obj_type);
+ append_obj_to_pack(data, size, type);
free(data);
if (verbose)
percent = display_progress(nr_resolved_deltas,
/* Rewrite pack header with updated object number */
if (lseek(output_fd, 0, SEEK_SET) != 0)
die("cannot seek back: %s", strerror(errno));
- if (xread(output_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
+ if (read_in_full(output_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
die("cannot read pack header back: %s", strerror(errno));
hdr.hdr_entries = htonl(nr_objects);
if (lseek(output_fd, 0, SEEK_SET) != 0)
const char *keep_name, const char *keep_msg,
unsigned char *sha1)
{
- char *report = "pack";
+ const char *report = "pack";
char name[PATH_MAX];
int err;
char buf[48];
int len = snprintf(buf, sizeof(buf), "%s\t%s\n",
report, sha1_to_hex(sha1));
- xwrite(1, buf, len);
+ write_or_die(1, buf, len);
/*
* Let's just mimic git-unpack-objects here and write
fix_thin_pack = 1;
} else if (!strcmp(arg, "--keep")) {
keep_msg = "";
- } else if (!strncmp(arg, "--keep=", 7)) {
+ } else if (!prefixcmp(arg, "--keep=")) {
keep_msg = arg + 7;
- } else if (!strncmp(arg, "--pack_header=", 14)) {
+ } else if (!prefixcmp(arg, "--pack_header=")) {
struct pack_header *hdr;
char *c;