summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4df096a)
raw | patch | inline | side by side (parent: 4df096a)
author | Franck Bui-Huu <vagabon.xyz@gmail.com> | |
Thu, 7 Sep 2006 13:12:03 +0000 (15:12 +0200) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Sat, 9 Sep 2006 18:57:37 +0000 (11:57 -0700) |
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>
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>
archive.h | patch | blob | history | |
builtin-archive.c | patch | blob | history | |
builtin-tar-tree.c | patch | blob | history |
diff --git a/archive.h b/archive.h
index 24b016f001117715999baf9eaa486164ba15567e..5c3f29b8df2722805c5009c99c64a39191f14fb1 100644 (file)
--- a/archive.h
+++ b/archive.h
extern void parse_pathspec_arg(const char **pathspec,
struct archiver_args *args);
+/*
+ * Archive-format specific backends.
+ */
+extern int write_tar_archive(struct archiver_args *);
#endif /* ARCHIVE_H */
diff --git a/builtin-archive.c b/builtin-archive.c
index f6bc269fdc7e79d601e18cdb53511e6139fb1b7b..c6423b9c48b4d84269343e30c790d5c82dc9cd83 100644 (file)
--- a/builtin-archive.c
+++ b/builtin-archive.c
"git-archive --format=<fmt> [--prefix=<prefix>/] [<extra>] <tree-ish> [path...]";
struct archiver archivers[] = {
- { "" /* dummy */ },
+ { .name = "tar", .write_archive = write_tar_archive },
};
static int run_remote_archiver(struct archiver *ar, int argc,
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index fa666f78c5b5e44617495abb2716eded8407626c..c20eb0e364d683ef03978851619a79cb7840c379 100644 (file)
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
#include "tar.h"
#include "builtin.h"
#include "pkt-line.h"
+#include "archive.h"
#define RECORDSIZE (512)
#define BLOCKSIZE (RECORDSIZE * 20)
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)