git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/2] archive: allow remote to have more formats than we understand.

From
Junio C Hamano <junkio@cox.net>
Date
Sep 10, 2006, 07:09 UTC
Message-ID
<7vpse4tcyc.fsf@assigned-by-dhcp.cox.net>

This fixes git-archive --remote not to parse archiver arguments; otherwise if the remote end implements formats other than the one known locally we will not be able to access that format.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 * At first sight, this should not matter that much, but (1) we
   do not really parse and validate the arguments when dealing
   with remote site, and (2) we have no way validating them if
   we wanted to, given that the remote end might be running
   different version of git.
   Having said that, you would realize that once we start
   refactoring things this way, "git archive --remote=foo" is
   not archive driver anymore.  There is nothing that prevents
   us saying "git archive --remote=foo --command=rev-list HEAD",
   other than that the remote archive protocol insists the
   command invoked at the remote end to be "git archive" itself.
 archive.h         |    1 -
 builtin-archive.c |   79 ++++++++++++++++++++++++++++++++---------------------
 2 files changed, 47 insertions(+), 33 deletions(-)
diff --git a/archive.h b/archive.h
index d8cca73..e0782b9 100644
--- a/archive.h
+++ b/archive.h
@@ -19,7 +19,6 @@ typedef void *(*parse_extra_args_fn_t)(i
 
 struct archiver {
 	const char *name;
-	const char *remote;
 	struct archiver_args args;
 	write_archive_fn_t write_archive;
 	parse_extra_args_fn_t parse_extra;
diff --git a/builtin-archive.c b/builtin-archive.c
index b944737..c70488c 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -26,7 +26,7 @@ struct archiver archivers[] = {
 	},
 };
 
-static int run_remote_archiver(struct archiver *ar, int argc,
+static int run_remote_archiver(const char *remote, int argc,
 			       const char **argv)
 {
 	char *url, buf[1024];
@@ -35,16 +35,13 @@ static int run_remote_archiver(struct ar
 
 	sprintf(buf, "git-upload-archive");
 
-	url = xstrdup(ar->remote);
+	url = xstrdup(remote);
 	pid = git_connect(fd, url, buf);
 	if (pid < 0)
 		return pid;
 
-	for (i = 1; i < argc; i++) {
-		if (!strncmp(argv[i], "--remote=", 9))
-			continue;
+	for (i = 1; i < argc; i++)
 		packet_write(fd[1], "argument %s\n", argv[i]);
-	}
 	packet_flush(fd[1]);
 
 	len = packet_read_line(fd[0], buf, sizeof(buf));
@@ -150,17 +147,16 @@ int parse_archive_args(int argc, const c
 	const char *extra_argv[MAX_EXTRA_ARGS];
 	int extra_argc = 0;
 	const char *format = NULL; /* might want to default to "tar" */
-	const char *remote = NULL;
 	const char *base = "";
-	int list = 0;
 	int i;
 
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
 
 		if (!strcmp(arg, "--list") || !strcmp(arg, "-l")) {
-			list = 1;
-			continue;
+			for (i = 0; i < ARRAY_SIZE(archivers); i++)
+				printf("%s\n", archivers[i].name);
+			exit(0);
 		}
 		if (!strncmp(arg, "--format=", 9)) {
 			format = arg + 9;
@@ -170,10 +166,6 @@ int parse_archive_args(int argc, const c
 			base = arg + 9;
 			continue;
 		}
-		if (!strncmp(arg, "--remote=", 9)) {
-			remote = arg + 9;
-			continue;
-		}
 		if (!strcmp(arg, "--")) {
 			i++;
 			break;
@@ -187,44 +179,67 @@ int parse_archive_args(int argc, const c
 		break;
 	}
 
-	if (list) {
-		if (!remote) {
-			for (i = 0; i < ARRAY_SIZE(archivers); i++)
-				printf("%s\n", archivers[i].name);
-			exit(0);
-		}
-		die("--list and --remote are mutually exclusive");
-	}
-
-	if (argc - i < 1)
+	/* We need at least one parameter -- tree-ish */
+	if (argc - 1 < i)
 		usage(archive_usage);
 	if (!format)
 		die("You must specify an archive format");
 	if (init_archiver(format, ar) < 0)
 		die("Unknown archive format '%s'", format);
 
-	if (extra_argc && !remote) {
-		if (!ar->parse_extra) {
+	if (extra_argc) {
+		if (!ar->parse_extra)
 			die("%s", default_parse_extra(ar, extra_argv));
-		}
 		ar->args.extra = ar->parse_extra(extra_argc, extra_argv);
 	}
-	ar->remote = remote;
 	ar->args.base = base;
 
 	return i;
 }
 
+static const char *remote_request(int *ac, const char **av)
+{
+	int ix, iy, cnt = *ac;
+	int no_more_options = 0;
+	const char *remote = NULL;
+
+	for (ix = iy = 1; ix < cnt; ix++) {
+		const char *arg = av[ix];
+		if (!strcmp(arg, "--"))
+			no_more_options = 1;
+		if (!no_more_options) {
+			if (!strncmp(arg, "--remote=", 9)) {
+				if (remote)
+					die("Multiple --remote specified");
+				remote = arg + 9;
+				continue;
+			}
+			if (arg[0] != '-')
+				no_more_options = 1;
+		}
+		if (ix != iy)
+			av[iy] = arg;
+		iy++;
+	}
+	if (remote) {
+		av[--cnt] = NULL;
+		*ac = cnt;
+	}
+	return remote;
+}
+
 int cmd_archive(int argc, const char **argv, const char *prefix)
 {
 	struct archiver ar;
 	int tree_idx;
+	const char *remote = NULL;
 
-	tree_idx = parse_archive_args(argc, argv, &ar);
-
-	if (ar.remote)
-		return run_remote_archiver(&ar, argc, argv);
+	remote = remote_request(&argc, argv);
+	if (remote)
+		return run_remote_archiver(remote, argc, argv);
 
+	memset(&ar, 0, sizeof(ar));
+	tree_idx = parse_archive_args(argc, argv, &ar);
 	if (prefix == NULL)
 		prefix = setup_git_directory();
 
-- 
1.4.2.gc52f
Next: Junio C Hamano
Message 1 of 28 in “archive: allow remote to have more formats than we understand.”
  1. 1/2 archive: allow remote to have more formats than we understand.Junio C Hamano, Sep 10, 2006
  2. 2/2 Add --verbose to git-archiveJunio C Hamano, Sep 10, 2006
  3. 1/3 Move sideband client side support into reusable form.Junio C Hamano, Sep 10, 2006
  4. Franck Bui-HuuSep 10, 2006
  5. Move sideband server side support into reusable form.Junio C Hamano, Sep 10, 2006
  6. 3/3 Add sideband status report to git-archive protocolJunio C Hamano, Sep 10, 2006
  7. git-upload-archive: add config option to allow only specified formatsRene Scharfe, Sep 10, 2006
  8. Rene ScharfeSep 10, 2006
  9. Junio C HamanoSep 10, 2006
  10. Rene ScharfeSep 11, 2006
  11. Jakub NarebskiSep 11, 2006
  12. Franck Bui-HuuSep 10, 2006
  13. Rene ScharfeSep 11, 2006
  14. Franck Bui-HuuSep 10, 2006
  15. Junio C HamanoSep 10, 2006
  16. Franck Bui-HuuSep 11, 2006
  17. Junio C HamanoSep 12, 2006
  18. Franck Bui-HuuSep 12, 2006
  19. Franck Bui-HuuSep 12, 2006
  20. connect.c: finish_connect(): allow null pid parameterFranck Bui-Huu, Sep 12, 2006
  21. Junio C HamanoSep 13, 2006
  22. Test return value of finish_connect()Franck Bui-Huu, Sep 13, 2006
  23. git_connect: change return type to pid_tFranck Bui-Huu, Sep 13, 2006
  24. Junio C HamanoSep 12, 2006
  25. Rene ScharfeSep 10, 2006
  26. Franck Bui-HuuSep 10, 2006
  27. Junio C HamanoSep 10, 2006
  28. Franck Bui-HuuSep 10, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.