summaryrefslogtreecommitdiff
path: root/builtin-upload-tar.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-05-19 01:46:44 (GMT)
committerJunio C Hamano <junkio@cox.net>2006-05-20 00:48:34 (GMT)
commit217542640ed219c980fff2b3c307c4520120f20f (patch)
tree989b379b0f13db7392fd7671d57a86a90674b9ac /builtin-upload-tar.c
parent288c0384505e6c25cc1a162242919a0485d50a74 (diff)
downloadgit-217542640ed219c980fff2b3c307c4520120f20f.zip
git-217542640ed219c980fff2b3c307c4520120f20f.tar.gz
git-217542640ed219c980fff2b3c307c4520120f20f.tar.bz2
built-in tar-tree and remote tar-tree
This makes tar-tree a built-in. As an added bonus, you can now say: git tar-tree --remote=remote-repository <ent> [<base>] This does not work with git-daemon yet, but should work with localhost and git over ssh transports. Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'builtin-upload-tar.c')
-rw-r--r--builtin-upload-tar.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/builtin-upload-tar.c b/builtin-upload-tar.c
new file mode 100644
index 0000000..d4fa7b5
--- /dev/null
+++ b/builtin-upload-tar.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2006 Junio C Hamano
+ */
+#include "cache.h"
+#include "pkt-line.h"
+#include "exec_cmd.h"
+#include "builtin.h"
+
+static const char upload_tar_usage[] = "git-upload-tar <repo>";
+
+static int nak(const char *reason)
+{
+ packet_write(1, "NACK %s\n", reason);
+ packet_flush(1);
+ return 1;
+}
+
+int cmd_upload_tar(int argc, const char **argv, char **envp)
+{
+ int len;
+ const char *dir = argv[1];
+ char buf[8192];
+ unsigned char sha1[20];
+ char *base = NULL;
+ char hex[41];
+ int ac;
+ const char *av[4];
+
+ if (argc != 2)
+ usage(upload_tar_usage);
+ if (strlen(dir) < sizeof(buf)-1)
+ strcpy(buf, dir); /* enter-repo smudges its argument */
+ else
+ packet_write(1, "NACK insanely long repository name %s\n", dir);
+ if (!enter_repo(buf, 0)) {
+ packet_write(1, "NACK not a git archive %s\n", dir);
+ packet_flush(1);
+ return 1;
+ }
+
+ len = packet_read_line(0, buf, sizeof(buf));
+ if (len < 5 || strncmp("want ", buf, 5))
+ return nak("expected want");
+ if (buf[len-1] == '\n')
+ buf[--len] = 0;
+ if (get_sha1(buf + 5, sha1))
+ return nak("expected sha1");
+ strcpy(hex, sha1_to_hex(sha1));
+
+ len = packet_read_line(0, buf, sizeof(buf));
+ if (len) {
+ if (len < 5 || strncmp("base ", buf, 5))
+ return nak("expected (optional) base");
+ if (buf[len-1] == '\n')
+ buf[--len] = 0;
+ base = strdup(buf + 5);
+ len = packet_read_line(0, buf, sizeof(buf));
+ }
+ if (len)
+ return nak("expected flush");
+
+ packet_write(1, "ACK\n");
+ packet_flush(1);
+
+ ac = 0;
+ av[ac++] = "tar-tree";
+ av[ac++] = hex;
+ if (base)
+ av[ac++] = base;
+ av[ac++] = NULL;
+ execv_git_cmd(av);
+ /* should it return that is an error */
+ return 1;
+}