From: "Franck Bui-Huu" <vagabon.xyz@gmail.com>
To: "Rene Scharfe" <rene.scharfe@lsrfire.ath.cx>
Cc: "Git Mailing List" <git@vger.kernel.org>,
"Junio C Hamano" <junkio@cox.net>
Subject: Re: [PATCH][RFC] Add git-archive-tree
Date: Sat, 2 Sep 2006 17:24:45 +0200 [thread overview]
Message-ID: <cda58cb80609020824ja524444uc9fe65ea2e4febba@mail.gmail.com> (raw)
In-Reply-To: <44F977C0.4060901@lsrfire.ath.cx>
Hi,
2006/9/2, Rene Scharfe <rene.scharfe@lsrfire.ath.cx>:
> git-archive-tree is a command to make tar and ZIP archives of a git tree.
> It helps prevent a proliferation of git-{format}-tree commands. This is
> useful e.g. for remote archive fetching because we only need to write a
> single upload and a single download program that simply pass on the
> format option to git-archive-tree.
OK, Rene you beat me. I started to cook up something this morning but
had no time to go further.
I sent a starting implementation just because it seems complementary
to the one you sent a couple hours ago: it supports '--remote' option.
But it does _not_ have path spec support you introduced. I think it's
cool feature but I would have to dig into git's internal to implement
it, which would have taken me a while.
>From now, do you think we should import my work into your version or
'vice verca' ?
-- >8 --
Subject: [PATCH] Add git-archive (other implementation)
Signed-off-by: Franck Bui-Huu <vagabon.xyz@gmail.com>
---
.gitignore | 1
Makefile | 1
builtin-archive.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++
builtin.h | 1
generate-cmdlist.sh | 1
git.c | 1
6 files changed, 176 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
index 78cb671..a3e7ca1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ git-apply
git-applymbox
git-applypatch
git-archimport
+git-archive
git-bisect
git-branch
git-cat-file
diff --git a/Makefile b/Makefile
index 164dbcf..8d963e0 100644
--- a/Makefile
+++ b/Makefile
@@ -266,6 +266,7 @@ LIB_OBJS = \
BUILTIN_OBJS = \
builtin-add.o \
builtin-apply.o \
+ builtin-archive.o \
builtin-cat-file.o \
builtin-checkout-index.o \
builtin-check-ref-format.o \
diff --git a/builtin-archive.c b/builtin-archive.c
new file mode 100644
index 0000000..47898ee
--- /dev/null
+++ b/builtin-archive.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2006 Franck Bui-Huu
+ */
+#include "cache.h"
+#include "builtin.h"
+#include "exec_cmd.h"
+#include "pkt-line.h"
+
+#define MAX_ARGS 32
+
+static const char *extra_argv[MAX_ARGS];
+static int extra_argc = 1;
+static const char *base;
+static const char *remote;
+
+static const char archive_usage[] = \
+"git-archive -f <format> [extra] [--remote=<repo>] [--prefix=<base>]
<tree-ish>";
+
+/* archiver's options */
+#define NEED_BASE (1<<0)
+
+struct archiver_info {
+ const char *name;
+ int (*fn)(int argc, const char **argv, const char *prefix);
+ int options;
+};
+
+static struct archiver_info archivers[] = {
+ { "tar", cmd_tar_tree, NEED_BASE },
+ { "zip", cmd_zip_tree, NEED_BASE },
+};
+
+static int run_remote_archiver(struct archiver_info *ar, char *url)
+{
+ int fd[2], len, rv;
+ char buf[1024];
+ pid_t pid;
+
+ /*
+ * For now, remote operations does not support extra options
+ */
+ if (extra_argc > 2)
+ die("Remote operation does not support extra options yet.");
+
+ sprintf(buf, "git-upload-%s", ar->name);
+ pid = git_connect(fd, url, buf);
+ if (pid < 0)
+ return pid;
+
+ packet_write(fd[1], "want %s\n", extra_argv[1]);
+ if (base)
+ packet_write(fd[1], "base %s\n", base);
+ packet_flush(fd[1]);
+
+ len = packet_read_line(fd[0], buf, sizeof(buf));
+ if (!len)
+ die("git-archive: expected ACK/NAK, got EOF");
+ if (buf[len-1] == '\n')
+ buf[--len] = 0;
+ if (strcmp(buf, "ACK")) {
+ if (len > 5 && !strncmp(buf, "NACK ", 5))
+ die("git-archive: NACK %s", buf + 5);
+ die("git-archive: protocol error");
+ }
+ if (packet_read_line(fd[0], buf, sizeof(buf)))
+ die("git-archive: expected a flush");
+
+ /* Now, start reading from fd[0] and spit it out to stdout */
+ rv = copy_fd(fd[0], 1);
+ close(fd[0]);
+
+ return !!(rv | finish_connect(pid));
+}
+
+void insert_extra_option(const char *option, int idx)
+{
+ const char **argv = extra_argv; /* some shortcuts... */
+ int argc = extra_argc;
+
+ if (argc > MAX_ARGS - 2)
+ die("Too many args");
+ if (idx > MAX_ARGS - 1)
+ die("idx overflow extra_argv buffer !");
+
+ /* insert at last position ? */
+ if (idx < 0) {
+ argv[argc++] = option;
+ argv[argc] = NULL;
+ } else {
+ argv += idx;
+ memmove(argv + 1, argv, argc * sizeof(*argv));
+ *argv = option;
+ }
+ extra_argc++;
+}
+
+int run_archiver(const char *format)
+{
+ struct archiver_info *ar;
+ char buf[32];
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(archivers); i++) {
+ ar = &archivers[i];
+ if (strcmp(format, ar->name))
+ continue;
+ goto found;
+ }
+ return error("Unknown archive format '%s'\n", format);
+found:
+ if (remote) {
+ char *url = strdup(remote+9); /* --remote=<repo> */
+ return run_remote_archiver(ar, url);
+ }
+ if (base) {
+ i = 1;
+ if (ar->options & NEED_BASE) {
+ base += 9; /* --prefix=<base> */
+ i = -1;
+ }
+ insert_extra_option(base, i);
+ }
+ sprintf(buf, "%s-tree", ar->name);
+ extra_argv[0] = buf;
+
+ return ar->fn(extra_argc, extra_argv, setup_git_directory());
+}
+
+static int show_list_formats(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(archivers); i++) {
+ printf("%s\n", archivers[i].name);
+ }
+ return 0;
+}
+
+int cmd_archive(int argc, const char **argv, const char *prefix)
+{
+ static const char *format;
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+
+ if (!strcmp(arg, "--list") || !strcmp(arg, "-l")) {
+ return show_list_formats();
+ }
+ if (!strncmp(arg, "--format=", 9)) {
+ format = arg+9;
+ continue;
+ }
+ if (!strncmp(arg, "--prefix=", 9)) {
+ base = arg;
+ continue;
+ }
+ if (!strncmp(arg, "--remote=", 9)) {
+ remote = arg;
+ continue;
+ }
+ if (extra_argc > MAX_ARGS - 2)
+ die("Too many options");
+ extra_argv[extra_argc++] = arg;
+ }
+
+ if (!format)
+ die("You must specify an archive format");
+
+ return run_archiver(format);
+}
diff --git a/builtin.h b/builtin.h
index 25431d7..50852cd 100644
--- a/builtin.h
+++ b/builtin.h
@@ -15,6 +15,7 @@ extern int write_tree(unsigned char *sha
extern int cmd_add(int argc, const char **argv, const char *prefix);
extern int cmd_apply(int argc, const char **argv, const char *prefix);
+extern int cmd_archive(int argc, const char **argv, const char *prefix);
extern int cmd_cat_file(int argc, const char **argv, const char *prefix);
extern int cmd_checkout_index(int argc, const char **argv, const char *prefix);
extern int cmd_check_ref_format(int argc, const char **argv, const
char *prefix);
diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh
index ec1eda2..5450918 100755
--- a/generate-cmdlist.sh
+++ b/generate-cmdlist.sh
@@ -12,6 +12,7 @@ struct cmdname_help common_cmds[] = {"
sort <<\EOF |
add
apply
+archive
bisect
branch
checkout
diff --git a/git.c b/git.c
index 403fb3a..ddb1620 100644
--- a/git.c
+++ b/git.c
@@ -218,6 +218,7 @@ static void handle_internal_command(int
} commands[] = {
{ "add", cmd_add, RUN_SETUP },
{ "apply", cmd_apply },
+ { "archive", cmd_archive },
{ "cat-file", cmd_cat_file, RUN_SETUP },
{ "checkout-index", cmd_checkout_index, RUN_SETUP },
{ "check-ref-format", cmd_check_ref_format },
--
1.4.2.g8ed9-dirty
--
VGER BF report: U 0.5
next prev parent reply other threads:[~2006-09-02 15:24 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-02 12:23 [PATCH][RFC] Add git-archive-tree Rene Scharfe
2006-09-02 12:37 ` [PATCH] Add support for tgz archive format Rene Scharfe
2006-09-02 13:10 ` [PATCH][RFC] Add git-archive-tree Rene Scharfe
2006-09-02 20:13 ` Franck Bui-Huu
2006-09-04 18:22 ` Rene Scharfe
2006-09-04 20:09 ` Junio C Hamano
2006-09-04 22:02 ` Rene Scharfe
2006-09-04 22:20 ` Junio C Hamano
2006-09-05 11:43 ` Franck Bui-Huu
2006-09-02 21:19 ` Junio C Hamano
2006-09-02 14:17 ` Rene Scharfe
2006-09-02 15:24 ` Franck Bui-Huu [this message]
2006-09-02 16:08 ` Rene Scharfe
2006-09-02 21:27 ` Junio C Hamano
2006-09-06 18:05 ` Rene Scharfe
2006-09-06 21:47 ` Junio C Hamano
2006-09-17 11:54 ` Rene Scharfe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cda58cb80609020824ja524444uc9fe65ea2e4febba@mail.gmail.com \
--to=vagabon.xyz@gmail.com \
--cc=git@vger.kernel.org \
--cc=junkio@cox.net \
--cc=rene.scharfe@lsrfire.ath.cx \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).