git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mark Thomas <markbt@efaref.net>
To: git@vger.kernel.org
Cc: Mark Thomas <markbt@efaref.net>
Subject: [RFC 1/4] upload-file: Add upload-file command
Date: Sat,  4 Mar 2017 19:18:58 +0000	[thread overview]
Message-ID: <20170304191901.9622-2-markbt@efaref.net> (raw)
In-Reply-To: <20170304191901.9622-1-markbt@efaref.net>

The upload-file command allows a remote to request specific files by sha1.

Signed-off-by: Mark Thomas <markbt@efaref.net>
---
 .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


  reply	other threads:[~2017-03-04 19:36 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-04 19:18 [RFC 0/4] Shallow clones with on-demand fetch Mark Thomas
2017-03-04 19:18 ` Mark Thomas [this message]
2017-03-04 19:18 ` [RFC 2/4] on-demand: Fetch missing files from remote Mark Thomas
2017-03-04 19:19 ` [RFC 3/4] upload-pack: Send all commits if client requests on-demand Mark Thomas
2017-03-04 19:19 ` [RFC 4/4] clone: Request on-demand shallow clones Mark Thomas
2017-03-06 19:16 ` [RFC 0/4] Shallow clones with on-demand fetch Jonathan Tan
2017-03-06 20:01   ` Stefan Beller
2017-03-06 19:18 ` Junio C Hamano
2017-03-07  9:42   ` Jeff King

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=20170304191901.9622-2-markbt@efaref.net \
    --to=markbt@efaref.net \
    --cc=git@vger.kernel.org \
    /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).