diff options
author | Franck Bui-Huu <vagabon.xyz@gmail.com> | 2006-09-07 15:12:03 +0200 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-09-09 11:57:37 -0700 |
commit | efd8696cd7ccfa5042ef710e89fe0d10efdcd085 (patch) | |
tree | bab63aafd8ddba67add58670a8f73b6400c8d41c /builtin-tar-tree.c | |
parent | 4df096a5ca24f2f39042c51cf51b8a2bec66a2b5 (diff) | |
download | git-efd8696cd7ccfa5042ef710e89fe0d10efdcd085.tar.gz |
git-archive: wire up TAR format.
This is based on Rene Scharfe's earlier patch, but uses the
archiver support introduced by the previous patch.
Signed-off-by: Franck Bui-Huu <vagabon.xyz@gmail.com>
Acked-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'builtin-tar-tree.c')
-rw-r--r-- | builtin-tar-tree.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c index fa666f78c5..c20eb0e364 100644 --- a/builtin-tar-tree.c +++ b/builtin-tar-tree.c @@ -9,6 +9,7 @@ #include "tar.h" #include "builtin.h" #include "pkt-line.h" +#include "archive.h" #define RECORDSIZE (512) #define BLOCKSIZE (RECORDSIZE * 20) @@ -338,6 +339,72 @@ static int generate_tar(int argc, const char **argv, const char *prefix) return 0; } +static int write_tar_entry(const unsigned char *sha1, + const char *base, int baselen, + const char *filename, unsigned mode, int stage) +{ + static struct strbuf path; + int filenamelen = strlen(filename); + void *buffer; + char type[20]; + unsigned long size; + + if (!path.alloc) { + path.buf = xmalloc(PATH_MAX); + path.alloc = PATH_MAX; + path.len = path.eof = 0; + } + if (path.alloc < baselen + filenamelen) { + free(path.buf); + path.buf = xmalloc(baselen + filenamelen); + path.alloc = baselen + filenamelen; + } + memcpy(path.buf, base, baselen); + memcpy(path.buf + baselen, filename, filenamelen); + path.len = baselen + filenamelen; + if (S_ISDIR(mode)) { + strbuf_append_string(&path, "/"); + buffer = NULL; + size = 0; + } else { + buffer = read_sha1_file(sha1, type, &size); + if (!buffer) + die("cannot read %s", sha1_to_hex(sha1)); + } + + write_entry(sha1, &path, mode, buffer, size); + free(buffer); + + return READ_TREE_RECURSIVE; +} + +int write_tar_archive(struct archiver_args *args) +{ + int plen = strlen(args->base); + + git_config(git_tar_config); + + archive_time = args->time; + + if (args->commit_sha1) + write_global_extended_header(args->commit_sha1); + + if (args->base && plen > 0 && args->base[plen - 1] == '/') { + char *base = strdup(args->base); + int baselen = strlen(base); + + while (baselen > 0 && base[baselen - 1] == '/') + base[--baselen] = '\0'; + write_tar_entry(args->tree->object.sha1, "", 0, base, 040777, 0); + free(base); + } + read_tree_recursive(args->tree, args->base, plen, 0, + args->pathspec, write_tar_entry); + write_trailer(); + + return 0; +} + static const char *exec = "git-upload-tar"; static int remote_tar(int argc, const char **argv) |