summaryrefslogtreecommitdiff
path: root/unpack-objects.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-25 22:59:31 (GMT)
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-25 22:59:31 (GMT)
commit745369583105c8a048a765f8b5cbf7e7ebd1f982 (patch)
treeebe7f828b440ddc514810c01da7b902ce7c2ed67 /unpack-objects.c
parentd38c3721a1813048a6c7c1597b0c2e5b18517f9d (diff)
downloadgit-745369583105c8a048a765f8b5cbf7e7ebd1f982.zip
git-745369583105c8a048a765f8b5cbf7e7ebd1f982.tar.gz
git-745369583105c8a048a765f8b5cbf7e7ebd1f982.tar.bz2
git-unpack-objects: start parsing the actual packed data
So far we just print out the type and size.
Diffstat (limited to 'unpack-objects.c')
-rw-r--r--unpack-objects.c63
1 files changed, 58 insertions, 5 deletions
diff --git a/unpack-objects.c b/unpack-objects.c
index 73d0c2d..7b175c9 100644
--- a/unpack-objects.c
+++ b/unpack-objects.c
@@ -1,5 +1,7 @@
#include "cache.h"
+#include "object.h"
+static int dry_run;
static int nr_entries;
static const char *base_name;
static const char unpack_usage[] = "git-unpack-objects basename";
@@ -9,6 +11,9 @@ struct pack_entry {
unsigned char sha1[20];
};
+static void *pack_base;
+static unsigned long pack_size;
+
static struct pack_entry **pack_list;
static void *map_file(const char *suffix, unsigned long *sizep)
@@ -63,7 +68,7 @@ static int check_index(void *index, unsigned long idx_size)
nr = n;
}
if (idx_size != 4*256 + nr * 24) {
- printf("idx_size=%d, expected %d (%d)\n", idx_size, 4*256 + nr * 24, nr);
+ printf("idx_size=%lu, expected %u (%u)\n", idx_size, 4*256 + nr * 24, nr);
return error("wrong index file size");
}
@@ -78,17 +83,64 @@ static int check_index(void *index, unsigned long idx_size)
return 0;
}
+static void unpack_entry(struct pack_entry *entry)
+{
+ unsigned long size;
+ unsigned long offset;
+ unsigned char *pack;
+
+ /* Have we done this one already due to deltas based on it? */
+ if (lookup_object(entry->sha1))
+ return;
+
+ offset = ntohl(entry->offset);
+ if (offset > pack_size - 5)
+ die("object offset outside of pack file");
+ pack = pack_base + offset;
+ offset = pack_size - offset;
+ switch (*pack) {
+ case 'C': case 'T': case 'B':
+ size = (pack[1] << 24) + (pack[2] << 16) + (pack[3] << 8) + pack[4];
+ printf("%s %c %lu\n", sha1_to_hex(entry->sha1), *pack, size);
+ break;
+ case 'D':
+ printf("%s D", sha1_to_hex(entry->sha1));
+ printf(" %s\n", sha1_to_hex(pack+1));
+ break;
+ default:
+ die("corrupted pack file");
+ }
+}
+
+/*
+ * We unpack from the end, older files first. Now, usually
+ * there are deltas etc, so we'll not actually write the
+ * objects in that order, but we might as well try..
+ */
+static void unpack_all(void)
+{
+ int i = nr_entries;
+
+ while (--i >= 0) {
+ struct pack_entry *entry = pack_list[i];
+ unpack_entry(entry);
+ }
+}
+
int main(int argc, char **argv)
{
int i;
- unsigned long idx_size, pack_size;
- void *index, *pack;
+ unsigned long idx_size;
+ void *index;
for (i = 1 ; i < argc; i++) {
const char *arg = argv[i];
if (*arg == '-') {
- /* Maybe we'll have some flags here some day.. */
+ if (!strcmp(arg, "-n")) {
+ dry_run = 1;
+ continue;
+ }
usage(unpack_usage);
}
if (base_name)
@@ -98,8 +150,9 @@ int main(int argc, char **argv)
if (!base_name)
usage(unpack_usage);
index = map_file("idx", &idx_size);
- pack = map_file("pack", &pack_size);
+ pack_base = map_file("pack", &pack_size);
if (check_index(index, idx_size) < 0)
die("bad index file");
+ unpack_all();
return 0;
}