From: "Franck Bui-Huu" <vagabon.xyz@gmail.com>
To: "Junio C Hamano" <junkio@cox.net>
Cc: "Rene Scharfe" <rene.scharfe@lsrfire.ath.cx>, git@vger.kernel.org
Subject: [PATCH 2/2] Add git-upload-archive
Date: Tue, 5 Sep 2006 14:22:27 +0200 [thread overview]
Message-ID: <cda58cb80609050522o30b9a28n596121a29eb7d482@mail.gmail.com> (raw)
This command implements the git archive protocol on the server
side. This command is not intended to be used by the end user.
Underlying git-archive command line options are sent over the
protocol from "git-archive --remote=...", just like upload-tar
currently does with "git-tar-tree=...".
As for "git-archive" command implementation, this new command
does not execute any existing "git-{tar,zip}-tree" but rely
on the archive API defined by "git-archive" patch. Hence we
get 2 good points:
- "git-archive" and "git-upload-archive" share all option
parsing code.
- All kind of git-upload-{tar,zip} could be removed.
Signed-off-by: Franck Bui-Huu <vagabon.xyz@gmail.com>
---
.gitignore | 1
Makefile | 1
builtin-upload-archive.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++
builtin.h | 1
daemon.c | 13 +++++-
git.c | 1
6 files changed, 117 insertions(+), 2 deletions(-)
diff --git a/.gitignore b/.gitignore
index a3e7ca1..fda9bf2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -119,6 +119,7 @@ git-unpack-objects
git-update-index
git-update-ref
git-update-server-info
+git-upload-archive
git-upload-pack
git-upload-tar
git-var
diff --git a/Makefile b/Makefile
index 51ed4dd..461e1d6 100644
--- a/Makefile
+++ b/Makefile
@@ -305,6 +305,7 @@ BUILTIN_OBJS = \
builtin-unpack-objects.o \
builtin-update-index.o \
builtin-update-ref.o \
+ builtin-upload-archive.o \
builtin-upload-tar.o \
builtin-verify-pack.o \
builtin-write-tree.o \
diff --git a/builtin-upload-archive.c b/builtin-upload-archive.c
new file mode 100644
index 0000000..5e389fc
--- /dev/null
+++ b/builtin-upload-archive.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2006 Franck Bui-Huu
+ */
+#include <time.h>
+#include "cache.h"
+#include "builtin.h"
+#include "archive.h"
+#include "pkt-line.h"
+
+#define MAX_ARGS 32
+
+static const char upload_archive_usage[] =
+ "git-upload-archive --format=fmt <repo>";
+
+static int NACK(const char *reason)
+{
+ packet_write(1, "NACK %s\n", reason);
+ packet_flush(1);
+ return -1;
+}
+
+int cmd_upload_archive(int argc, const char **argv, const char *prefix)
+{
+ struct archiver_struct *ar;
+ const char *sent_argv[MAX_ARGS];
+ const char *arg_cmd = "arguments ";
+ const char *reason;
+ char *p, buf[8192];
+ int treeish_idx;
+ int sent_argc;
+ int len;
+ int rv;
+
+ const char **pathspec;
+ struct tree *tree;
+ const unsigned char *commit_sha1;
+ time_t archive_time;
+
+ if (argc != 3)
+ usage(upload_archive_usage);
+
+ if (strlen(argv[2]) > sizeof(buf)) {
+ reason = "insanely long repository name";
+ goto nack;
+ }
+ strcpy(buf, argv[2]); /* enter-repo smudges its argument */
+
+ if (!enter_repo(buf, 0)) {
+ reason = "not a git archive";
+ goto nack;
+ }
+
+ len = packet_read_line(0, buf, sizeof(buf));
+ if (len < strlen(arg_cmd) || strncmp(arg_cmd, buf, strlen(arg_cmd))) {
+ reason = "expected 'arguments' command";
+ goto nack;
+ }
+ if (buf[len-1] == '\n')
+ buf[--len] = 0;
+
+ /* we can safely override 'arg_cmd' */
+ len = packet_read_line(0, buf, strlen(arg_cmd));
+ if (len) {
+ reason = "flush expected";
+ goto nack;
+ }
+ p = buf + strlen(arg_cmd);
+
+ /* put received line options in sent_argv[] */
+ sent_argv[0] = "git-upload-archive";
+ sent_argv[1] = argv[1]; /* --format=<fmt> */
+ sent_argc = 2;
+ while (p) {
+ if (sent_argc > MAX_ARGS - 2) {
+ reason = "Too many options (>29)";
+ goto nack;
+ }
+ sent_argv[sent_argc++] = strsep(&p, " ");
+ }
+ sent_argv[sent_argc] = NULL;
+
+ /* parse all options sent by the client */
+ treeish_idx = parse_archive_args(sent_argc, sent_argv, &ar, &reason);
+ if (treeish_idx < 0)
+ goto nack;
+
+ rv = parse_treeish_arg(sent_argv + treeish_idx, &tree, &commit_sha1,
+ &archive_time, prefix, &reason);
+ if (rv < 0)
+ goto nack;
+
+ pathspec = get_pathspec(ar->prefix, sent_argv + treeish_idx + 1);
+
+ packet_write(1, "ACK\n");
+ packet_flush(1);
+
+ return ar->write_archive(tree, commit_sha1, ar->prefix,
+ archive_time, pathspec);
+nack:
+ return NACK(reason);
+}
+
diff --git a/builtin.h b/builtin.h
index 2391afb..f3efb58 100644
--- a/builtin.h
+++ b/builtin.h
@@ -58,6 +58,7 @@ extern int cmd_zip_tree(int argc, const
extern int cmd_unpack_objects(int argc, const char **argv, const char *prefix);
extern int cmd_update_index(int argc, const char **argv, const char *prefix);
extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
+extern int cmd_upload_archive(int argc, const char **argv, const char *prefix);
extern int cmd_upload_tar(int argc, const char **argv, const char *prefix);
extern int cmd_version(int argc, const char **argv, const char *prefix);
extern int cmd_whatchanged(int argc, const char **argv, const char *prefix);
diff --git a/daemon.c b/daemon.c
index a4a08f3..c09280f 100644
--- a/daemon.c
+++ b/daemon.c
@@ -324,12 +324,21 @@ static int upload_pack(void)
return -1;
}
-static int upload_tar(void)
+static int upload_archive(const char *fmt)
{
- execl_git_cmd("upload-tar", ".", NULL);
+ char buf[64];
+
+ snprintf(buf, sizeof(buf), "--format=%s", fmt);
+
+ execl_git_cmd("upload-archive", buf, ".", NULL);
return -1;
}
+static int upload_tar(void)
+{
+ return upload_archive("tar");
+}
+
static struct daemon_service daemon_service[] = {
{ "upload-pack", "uploadpack", upload_pack, 1, 1 },
{ "upload-tar", "uploadtar", upload_tar, 0, 1 },
diff --git a/git.c b/git.c
index c62c5cf..315dc0b 100644
--- a/git.c
+++ b/git.c
@@ -261,6 +261,7 @@ static void handle_internal_command(int
{ "unpack-objects", cmd_unpack_objects, RUN_SETUP },
{ "update-index", cmd_update_index, RUN_SETUP },
{ "update-ref", cmd_update_ref, RUN_SETUP },
+ { "upload-archive", cmd_upload_archive },
{ "upload-tar", cmd_upload_tar },
{ "version", cmd_version },
{ "whatchanged", cmd_whatchanged, RUN_SETUP | USE_PAGER },
--
1.4.2.gbba4
reply other threads:[~2006-09-05 12:22 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=cda58cb80609050522o30b9a28n596121a29eb7d482@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