First cut at git-unpack-objects
So far it just reads the header and generates the list of objects. It also sorts them by the order they are written in the pack file, since that ends up being the same order we got them originally, and is thus "most recent first".
This commit is contained in:
parent
49397104f2
commit
bad50dc80f
3
Makefile
3
Makefile
@ -36,7 +36,7 @@ PROG= git-update-cache git-diff-files git-init-db git-write-tree \
|
||||
git-diff-helper git-tar-tree git-local-pull git-write-blob \
|
||||
git-get-tar-commit-id git-mkdelta git-apply git-stripspace \
|
||||
git-cvs2git git-diff-stages git-rev-parse git-patch-id \
|
||||
git-pack-objects
|
||||
git-pack-objects git-unpack-objects
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
@ -124,6 +124,7 @@ git-diff-stages: diff-stages.c
|
||||
git-rev-parse: rev-parse.c
|
||||
git-patch-id: patch-id.c
|
||||
git-pack-objects: pack-objects.c
|
||||
git-unpack-objects: unpack-objects.c
|
||||
|
||||
git-http-pull: LIBS += -lcurl
|
||||
git-rev-list: LIBS += -lssl
|
||||
|
105
unpack-objects.c
Normal file
105
unpack-objects.c
Normal file
@ -0,0 +1,105 @@
|
||||
#include "cache.h"
|
||||
|
||||
static int nr_entries;
|
||||
static const char *base_name;
|
||||
static const char unpack_usage[] = "git-unpack-objects basename";
|
||||
|
||||
struct pack_entry {
|
||||
unsigned int offset;
|
||||
unsigned char sha1[20];
|
||||
};
|
||||
|
||||
static struct pack_entry **pack_list;
|
||||
|
||||
static void *map_file(const char *suffix, unsigned long *sizep)
|
||||
{
|
||||
static char pathname[PATH_MAX];
|
||||
unsigned long len;
|
||||
int fd;
|
||||
struct stat st;
|
||||
void *map;
|
||||
|
||||
len = snprintf(pathname, PATH_MAX, "%s.%s", base_name, suffix);
|
||||
if (len >= PATH_MAX)
|
||||
die("bad pack base-name");
|
||||
fd = open(pathname, O_RDONLY);
|
||||
if (fd < 0 || fstat(fd, &st))
|
||||
die("unable to open '%s'", pathname);
|
||||
len = st.st_size;
|
||||
if (!len)
|
||||
die("bad pack file '%s'", pathname);
|
||||
map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (-1 == (int)(long)map)
|
||||
die("unable to mmap '%s'", pathname);
|
||||
close(fd);
|
||||
*sizep = len;
|
||||
return map;
|
||||
}
|
||||
|
||||
static int sort_by_offset(const void *_a, const void *_b)
|
||||
{
|
||||
struct pack_entry *a = *(struct pack_entry **)_a;
|
||||
struct pack_entry *b = *(struct pack_entry **)_b;
|
||||
unsigned int o1, o2;
|
||||
|
||||
o1 = ntohl(a->offset);
|
||||
o2 = ntohl(b->offset);
|
||||
return o1 < o2 ? -1 : 1;
|
||||
}
|
||||
|
||||
static int check_index(void *index, unsigned long idx_size)
|
||||
{
|
||||
unsigned int *array = index;
|
||||
unsigned int nr;
|
||||
int i;
|
||||
|
||||
if (idx_size < 4*256)
|
||||
return error("index file too small");
|
||||
nr = 0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
unsigned int n = ntohl(array[i]);
|
||||
if (n < nr)
|
||||
return error("non-monotonic index");
|
||||
nr = n;
|
||||
}
|
||||
if (idx_size != 4*256 + nr * 24) {
|
||||
printf("idx_size=%d, expected %d (%d)\n", idx_size, 4*256 + nr * 24, nr);
|
||||
return error("wrong index file size");
|
||||
}
|
||||
|
||||
nr_entries = nr;
|
||||
pack_list = xmalloc(nr * sizeof(struct pack_entry *));
|
||||
for (i = 0; i < nr; i++)
|
||||
pack_list[i] = index + 4*256 + i*24;
|
||||
|
||||
qsort(pack_list, nr, sizeof(*pack_list), sort_by_offset);
|
||||
|
||||
printf("%d entries\n", nr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
unsigned long idx_size, pack_size;
|
||||
void *index, *pack;
|
||||
|
||||
for (i = 1 ; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
|
||||
if (*arg == '-') {
|
||||
/* Maybe we'll have some flags here some day.. */
|
||||
usage(unpack_usage);
|
||||
}
|
||||
if (base_name)
|
||||
usage(unpack_usage);
|
||||
base_name = arg;
|
||||
}
|
||||
if (!base_name)
|
||||
usage(unpack_usage);
|
||||
index = map_file("idx", &idx_size);
|
||||
pack = map_file("pack", &pack_size);
|
||||
if (check_index(index, idx_size) < 0)
|
||||
die("bad index file");
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user