summaryrefslogtreecommitdiff
path: root/builtin-tar-tree.c
diff options
context:
space:
mode:
authorFranck Bui-Huu <vagabon.xyz@gmail.com>2006-09-07 15:12:03 +0200
committerJunio C Hamano <junkio@cox.net>2006-09-09 11:57:37 -0700
commitefd8696cd7ccfa5042ef710e89fe0d10efdcd085 (patch)
treebab63aafd8ddba67add58670a8f73b6400c8d41c /builtin-tar-tree.c
parent4df096a5ca24f2f39042c51cf51b8a2bec66a2b5 (diff)
downloadgit-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.c67
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)