#include "commit.h"
#include "tag.h"
#include "tree.h"
+#include "progress.h"
+#include "decorate.h"
static int dry_run, quiet, recover, has_errors;
static const char unpack_usage[] = "git-unpack-objects [-n] [-q] [-r] < pack-file";
static off_t consumed_bytes;
static SHA_CTX ctx;
+struct obj_buffer {
+ char *buffer;
+ unsigned long size;
+};
+
+static struct decoration obj_decorate;
+
+static struct obj_buffer *lookup_object_buffer(struct object *base)
+{
+ return lookup_decoration(&obj_decorate, base);
+}
+
/*
* Make sure at least "min" bytes are available in the buffer, and
* return the pointer to the buffer.
offset = 0;
}
do {
- int ret = xread(0, buffer + len, sizeof(buffer) - len);
+ ssize_t ret = xread(0, buffer + len, sizeof(buffer) - len);
if (ret <= 0) {
if (!ret)
die("early EOF");
void *delta_data, *base;
unsigned long base_size;
unsigned char base_sha1[20];
+ struct object *obj;
if (type == OBJ_REF_DELTA) {
hashcpy(base_sha1, fill(20));
}
}
+ obj = lookup_object(base_sha1);
+ if (obj) {
+ struct obj_buffer *obj_buf = lookup_object_buffer(obj);
+ if (obj_buf) {
+ resolve_delta(nr, obj->type, obj_buf->buffer, obj_buf->size, delta_data, delta_size);
+ return;
+ }
+ }
+
base = read_sha1_file(base_sha1, &type, &base_size);
if (!base) {
error("failed to read delta-pack base object %s",
free(base);
}
-static void unpack_one(unsigned nr, unsigned total)
+static void unpack_one(unsigned nr)
{
unsigned shift;
unsigned char *pack, c;
size += (c & 0x7f) << shift;
shift += 7;
}
- if (!quiet) {
- static unsigned long last_sec;
- static unsigned last_percent;
- struct timeval now;
- unsigned percentage = ((nr+1) * 100) / total;
-
- gettimeofday(&now, NULL);
- if (percentage != last_percent || now.tv_sec != last_sec) {
- last_sec = now.tv_sec;
- last_percent = percentage;
- fprintf(stderr, "%4u%% (%u/%u) done\r",
- percentage, (nr+1), total);
- }
- }
+
switch (type) {
case OBJ_COMMIT:
case OBJ_TREE:
static void unpack_all(void)
{
int i;
+ struct progress *progress = NULL;
struct pack_header *hdr = fill(sizeof(struct pack_header));
unsigned nr_objects = ntohl(hdr->hdr_entries);
die("bad pack file");
if (!pack_version_ok(hdr->hdr_version))
die("unknown pack file version %d", ntohl(hdr->hdr_version));
- fprintf(stderr, "Unpacking %d objects\n", nr_objects);
+ use(sizeof(struct pack_header));
+ if (!quiet)
+ progress = start_progress("Unpacking objects", nr_objects);
obj_list = xmalloc(nr_objects * sizeof(*obj_list));
- use(sizeof(struct pack_header));
- for (i = 0; i < nr_objects; i++)
- unpack_one(i, nr_objects);
+ for (i = 0; i < nr_objects; i++) {
+ unpack_one(i);
+ display_progress(progress, i + 1);
+ }
+ stop_progress(&progress);
+
if (delta_list)
die("unresolved deltas left after unpacking");
}
}
/* All done */
- if (!quiet)
- fprintf(stderr, "\n");
return has_errors;
}