Skip to content

Commit

Permalink
Make read-tree actually unpack the whole tree.
Browse files Browse the repository at this point in the history
I needed this to make a "sparse" archive conversion from my old
BitKeeper tree data. The scripts to do the conversion are just
incredibly ugly, but they seem to validate the notion that you
can actually use this silly 'git' thing to save your history in.
  • Loading branch information
Linus Torvalds committed Apr 8, 2005
1 parent 8bc9a0c commit e497ea2
Showing 1 changed file with 41 additions and 1 deletion.
42 changes: 41 additions & 1 deletion read-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,32 @@
*/
#include "cache.h"

static void create_directories(const char *path)
{
int len = strlen(path);
char *buf = malloc(len + 1);
const char *slash = path;

while ((slash = strchr(slash+1, '/')) != NULL) {
len = slash - path;
memcpy(buf, path, len);
buf[len] = 0;
mkdir(buf, 0700);
}
}

static int create_file(const char *path)
{
int fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
if (fd < 0) {
if (errno == ENOENT) {
create_directories(path);
fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
}
}
return fd;
}

static int unpack(unsigned char *sha1)
{
void *buffer;
Expand All @@ -20,12 +46,26 @@ static int unpack(unsigned char *sha1)
int len = strlen(buffer)+1;
unsigned char *sha1 = buffer + len;
char *path = strchr(buffer, ' ')+1;
char *data;
unsigned long filesize;
unsigned int mode;
int fd;

if (size < len + 20 || sscanf(buffer, "%o", &mode) != 1)
usage("corrupt 'tree' file");
buffer = sha1 + 20;
size -= len + 20;
printf("%o %s (%s)\n", mode, path, sha1_to_hex(sha1));
data = read_sha1_file(sha1, type, &filesize);
if (!data || strcmp(type, "blob"))
usage("tree file refers to bad file data");
fd = create_file(path);
if (fd < 0)
usage("unable to create file");
if (write(fd, data, filesize) != filesize)
usage("unable to write file");
fchmod(fd, mode);
close(fd);
free(data);
}
return 0;
}
Expand Down

0 comments on commit e497ea2

Please sign in to comment.