X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=tar-tree.c;h=fc60a90873d1928ce3ada6d26f0a0ae571d43773;hb=20fc9bc5e4fdd4b1f7fd98fbd2e91879f945d7e1;hp=11bbc81e36d6e3ac16ff7f113b01d9d651f7edd3;hpb=86da1c567da0421649cb1e8e999311012c764337;p=git.git diff --git a/tar-tree.c b/tar-tree.c index 11bbc81e..fc60a908 100644 --- a/tar-tree.c +++ b/tar-tree.c @@ -3,7 +3,7 @@ */ #include #include "cache.h" -#include "diff.h" +#include "tree-walk.h" #include "commit.h" #include "strbuf.h" #include "tar.h" @@ -94,7 +94,6 @@ static void write_blocked(void *buf, unsigned long size) } if (size) { memcpy(block + offset, buf, size); - buf += size; offset += size; } tail = offset % RECORDSIZE; @@ -161,6 +160,16 @@ static unsigned int ustar_header_chksum(const struct ustar_header *header) return chksum; } +static int get_path_prefix(const struct strbuf *path, int maxlen) +{ + int i = path->len; + if (i > maxlen) + i = maxlen; + while (i > 0 && path->buf[i] != '/') + i--; + return i; +} + static void write_entry(const unsigned char *sha1, struct strbuf *path, unsigned int mode, void *buffer, unsigned long size) { @@ -195,9 +204,17 @@ static void write_entry(const unsigned char *sha1, struct strbuf *path, return; } if (path->len > sizeof(header.name)) { - sprintf(header.name, "%s.data", sha1_to_hex(sha1)); - strbuf_append_ext_header(&ext_header, "path", - path->buf, path->len); + int plen = get_path_prefix(path, sizeof(header.prefix)); + int rest = path->len - plen - 1; + if (plen > 0 && rest <= sizeof(header.name)) { + memcpy(header.prefix, path->buf, plen); + memcpy(header.name, path->buf + plen + 1, rest); + } else { + sprintf(header.name, "%s.data", + sha1_to_hex(sha1)); + strbuf_append_ext_header(&ext_header, "path", + path->buf, path->len); + } } else memcpy(header.name, path->buf, path->len); } @@ -296,6 +313,7 @@ int main(int argc, char **argv) current_path.len = current_path.eof = 0; setup_git_directory(); + git_config(git_default_config); switch (argc) { case 3: @@ -317,7 +335,7 @@ int main(int argc, char **argv) } else archive_time = time(NULL); - tree.buf = read_object_with_reference(sha1, "tree", &tree.size, + tree.buf = read_object_with_reference(sha1, tree_type, &tree.size, tree_sha1); if (!tree.buf) die("not a reference to a tag, commit or tree object: %s",