The upload-file command allows a remote to request specific files by sha1.
Signed-off-by: Mark Thomas <[email protected]>
---
.gitignore | 1 +
Makefile | 2 ++
daemon.c | 6 +++++
upload-file.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 96 insertions(+)
create mode 100644 upload-file.c
diff --git a/.gitignore b/.gitignore
index 833ef3b..c2db9c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -165,6 +165,7 @@
/git-update-ref
/git-update-server-info
/git-upload-archive
+/git-upload-file
/git-upload-pack
/git-var
/git-verify-commit
diff --git a/Makefile b/Makefile
index 9ec6065..1b84322 100644
--- a/Makefile
+++ b/Makefile
@@ -597,6 +597,7 @@ PROGRAM_OBJS += sh-i18n--envsubst.o
PROGRAM_OBJS += shell.o
PROGRAM_OBJS += show-index.o
PROGRAM_OBJS += upload-pack.o
+PROGRAM_OBJS += upload-file.o
PROGRAM_OBJS += remote-testsvn.o
# Binary suffix, set to .exe for Windows builds
@@ -668,6 +669,7 @@ BINDIR_PROGRAMS_NEED_X += git-upload-pack
BINDIR_PROGRAMS_NEED_X += git-receive-pack
BINDIR_PROGRAMS_NEED_X += git-upload-archive
BINDIR_PROGRAMS_NEED_X += git-shell
+BINDIR_PROGRAMS_NEED_X += git-upload-file
BINDIR_PROGRAMS_NO_X += git-cvsserver
diff --git a/daemon.c b/daemon.c
index 473e6b6..8b5b026 100644
--- a/daemon.c
+++ b/daemon.c
@@ -479,6 +479,11 @@ static int upload_pack(void)
return run_service_command(argv);
}
+static int upload_file(void)
+{
+ const char *argv[] = { "upload-file", ".", NULL };
+ return run_service_command(argv);
+}
static int upload_archive(void)
{
static const char *argv[] = { "upload-archive", ".", NULL };
@@ -494,6 +499,7 @@ static int receive_pack(void)
static struct daemon_service daemon_service[] = {
{ "upload-archive", "uploadarch", upload_archive, 0, 1 },
{ "upload-pack", "uploadpack", upload_pack, 1, 1 },
+ { "upload-file", "uploadfile", upload_file, 1, 1 },
{ "receive-pack", "receivepack", receive_pack, 0, 1 },
};
diff --git a/upload-file.c b/upload-file.c
new file mode 100644
index 0000000..cb2bfe8
--- /dev/null
+++ b/upload-file.c
@@ -0,0 +1,87 @@
+
+#include "cache.h"
+#include "exec_cmd.h"
+#include "parse-options.h"
+#include "pkt-line.h"
+
+static const char * const upload_file_usage[] = {
+ N_("git upload-file [<options>] <dir>"),
+ NULL
+};
+
+
+static void upload_file(void)
+{
+ for (;;) {
+ char *line = packet_read_line(0, NULL);
+ const char *arg;
+ if (!line)
+ break;
+
+ if (skip_prefix(line, "info ", &arg)) {
+ unsigned char sha1[20];
+ void *buffer;
+ enum object_type type;
+ unsigned long size;
+
+ if (get_sha1_hex(arg, sha1))
+ die("invalid sha: %s", arg);
+
+ buffer = read_sha1_file(sha1, &type, &size);
+ if (buffer) {
+ packet_write_fmt(1, "found %s %d %ld\n",
sha1_to_hex(sha1), type, size);
+ free(buffer);
+ } else {
+ packet_write_fmt(1, "missing %s\n",
sha1_to_hex(sha1));
+ }
+ }
+
+ if (skip_prefix(line, "get ", &arg)) {
+ unsigned char sha1[20];
+ void *buffer;
+ enum object_type type;
+ unsigned long size;
+
+ if (get_sha1_hex(arg, sha1))
+ die("invalid sha: %s", arg);
+
+ buffer = read_sha1_file(sha1, &type, &size);
+ if (buffer) {
+ packet_write_fmt(1, "found %s %d %ld\n",
sha1_to_hex(sha1), type, size);
+ write_or_die(1, buffer, size);
+ free(buffer);
+ } else {
+ packet_write_fmt(1, "missing %s\n",
sha1_to_hex(sha1));
+ }
+
+ }
+
+ if (!strcmp(line, "end"))
+ break;
+ }
+}
+
+int cmd_main(int argc, const char **argv)
+{
+ const char *dir;
+ struct option options[] = {
+ OPT_END()
+ };
+
+ packet_trace_identity("upload-file");
+
+ argc = parse_options(argc, argv, NULL, options, upload_file_usage, 0);
+
+ if (argc != 1)
+ usage_with_options(upload_file_usage, options);
+
+ setup_path();
+
+ dir = argv[0];
+
+ if (!enter_repo(dir, 0))
+ die("'%s' does not appear to be a git repository", dir);
+
+ upload_file();
+ return 0;
+}
--
2.7.4