aboutsummaryrefslogtreecommitdiffstats
path: root/archive.c
diff options
context:
space:
mode:
authorRene Scharfe <rene.scharfe@lsrfire.ath.cx>2008-07-25 12:41:22 +0200
committerJunio C Hamano <gitster@pobox.com>2008-07-25 17:18:06 -0700
commitc0885435537e4b93709d2bf39ce36454186057a1 (patch)
tree7e8dbc44200a562b31baad57d7a55f09d52c35f1 /archive.c
parent6e94e6835f397cd2602ca1eb12002e51aa6b0500 (diff)
downloadgit-c0885435537e4b93709d2bf39ce36454186057a1.tar.gz
archive: move parameter parsing code to archive.c
write_archive() in archive.c is the only callsite for the command line parsing functions located in builtin-archive.c. Move them to the place where they are used, un-export them and make them static, as hinted at by Stephan. Cc: Stephan Beyer <s-beyer@gmx.net> Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'archive.c')
-rw-r--r--archive.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/archive.c b/archive.c
index 75eb257760..c4662a2830 100644
--- a/archive.c
+++ b/archive.c
@@ -1,8 +1,19 @@
#include "cache.h"
#include "commit.h"
+#include "tree-walk.h"
#include "attr.h"
#include "archive.h"
+static const char archive_usage[] = \
+"git archive --format=<fmt> [--prefix=<prefix>/] [--verbose] [<extra>] <tree-ish> [path...]";
+
+#define USES_ZLIB_COMPRESSION 1
+
+const struct archiver archivers[] = {
+ { "tar", write_tar_archive },
+ { "zip", write_zip_archive, USES_ZLIB_COMPRESSION },
+};
+
static void format_subst(const struct commit *commit,
const char *src, size_t len,
struct strbuf *buf)
@@ -156,6 +167,132 @@ int write_archive_entries(struct archiver_args *args,
return err;
}
+static const struct archiver *lookup_archiver(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(archivers); i++) {
+ if (!strcmp(name, archivers[i].name))
+ return &archivers[i];
+ }
+ return NULL;
+}
+
+static void parse_pathspec_arg(const char **pathspec,
+ struct archiver_args *ar_args)
+{
+ ar_args->pathspec = get_pathspec(ar_args->base, pathspec);
+}
+
+static void parse_treeish_arg(const char **argv,
+ struct archiver_args *ar_args, const char *prefix)
+{
+ const char *name = argv[0];
+ const unsigned char *commit_sha1;
+ time_t archive_time;
+ struct tree *tree;
+ const struct commit *commit;
+ unsigned char sha1[20];
+
+ if (get_sha1(name, sha1))
+ die("Not a valid object name");
+
+ commit = lookup_commit_reference_gently(sha1, 1);
+ if (commit) {
+ commit_sha1 = commit->object.sha1;
+ archive_time = commit->date;
+ } else {
+ commit_sha1 = NULL;
+ archive_time = time(NULL);
+ }
+
+ tree = parse_tree_indirect(sha1);
+ if (tree == NULL)
+ die("not a tree object");
+
+ if (prefix) {
+ unsigned char tree_sha1[20];
+ unsigned int mode;
+ int err;
+
+ err = get_tree_entry(tree->object.sha1, prefix,
+ tree_sha1, &mode);
+ if (err || !S_ISDIR(mode))
+ die("current working directory is untracked");
+
+ tree = parse_tree_indirect(tree_sha1);
+ }
+ ar_args->tree = tree;
+ ar_args->commit_sha1 = commit_sha1;
+ ar_args->commit = commit;
+ ar_args->time = archive_time;
+}
+
+static int parse_archive_args(int argc, const char **argv,
+ const struct archiver **ar, struct archiver_args *args)
+{
+ const char *format = "tar";
+ const char *base = "";
+ int compression_level = -1;
+ int verbose = 0;
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+
+ if (!strcmp(arg, "--list") || !strcmp(arg, "-l")) {
+ for (i = 0; i < ARRAY_SIZE(archivers); i++)
+ printf("%s\n", archivers[i].name);
+ exit(0);
+ }
+ if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) {
+ verbose = 1;
+ continue;
+ }
+ if (!prefixcmp(arg, "--format=")) {
+ format = arg + 9;
+ continue;
+ }
+ if (!prefixcmp(arg, "--prefix=")) {
+ base = arg + 9;
+ continue;
+ }
+ if (!strcmp(arg, "--")) {
+ i++;
+ break;
+ }
+ if (arg[0] == '-' && isdigit(arg[1]) && arg[2] == '\0') {
+ compression_level = arg[1] - '0';
+ continue;
+ }
+ if (arg[0] == '-')
+ die("Unknown argument: %s", arg);
+ break;
+ }
+
+ /* We need at least one parameter -- tree-ish */
+ if (argc - 1 < i)
+ usage(archive_usage);
+ *ar = lookup_archiver(format);
+ if (!*ar)
+ die("Unknown archive format '%s'", format);
+
+ args->compression_level = Z_DEFAULT_COMPRESSION;
+ if (compression_level != -1) {
+ if ((*ar)->flags & USES_ZLIB_COMPRESSION)
+ args->compression_level = compression_level;
+ else {
+ die("Argument not supported for format '%s': -%d",
+ format, compression_level);
+ }
+ }
+ args->verbose = verbose;
+ args->base = base;
+ args->baselen = strlen(base);
+
+ return i;
+}
+
int write_archive(int argc, const char **argv, const char *prefix,
int setup_prefix)
{