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

[RFC 04/16] Add cat-blob report fifo from fast-import to remote-helper.

From
Florian Achleitner <florian.achleitner.2.6.31@gmail.com>
Date
Jul 26, 2012, 07:32 UTC
Message-ID
<1343287957-22040-5-git-send-email-florian.achleitner.2.6.31@gmail.com>
In-Reply-To
<1343287957-22040-4-git-send-email-florian.achleitner.2.6.31@gmail.com>

For some fast-import commands (e.g. cat-blob) an answer-channel is required. For this purpose a fifo (aka named pipe) (mkfifo) is created (.git/fast-import-report-fifo) by the transport-helper when fetch via import is requested. The remote-helper and fast-import open the ends of the pipe.

The filename of the fifo is passed to the remote-helper via it's environment, helpers that don't use fast-import can simply ignore it. Add a new command line option --cat-blob-pipe to fast-import, for this purpose.

Use argv_arrays in get_helper and get_importer.
Opening the pipe with O_RDWR prevents blocking open calls on both ends.
Signed-off-by: Florian Achleitner <florian.achleitner.2.6.31@gmail.com>
---
 fast-import.c      |   14 ++++++++++++
 transport-helper.c |   64 ++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 63 insertions(+), 15 deletions(-)
diff --git a/fast-import.c b/fast-import.c
index eed97c8..7619449 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -3180,6 +3180,15 @@ static void option_cat_blob_fd(const char *fd)
 	cat_blob_fd = (int) n;
 }
 
+static void option_cat_blob_pipe(const char *name)
+{
+	int report_fd = open(name, O_RDWR);
+	if(report_fd < 0) {
+		die("Unable to open fast-import back-pipe! %s", strerror(errno));
+	}
+	cat_blob_fd = report_fd;
+}
+
 static void option_export_pack_edges(const char *edges)
 {
 	if (pack_edges)
@@ -3337,6 +3346,11 @@ static void parse_argv(void)
 			continue;
 		}
 
+		if(!prefixcmp(a + 2, "cat-blob-pipe=")) {
+			option_cat_blob_pipe(a + 2 + strlen("cat-blob-pipe="));
+			continue;
+		}
+
 		die("unknown option %s", a);
 	}
 	if (i != global_argc)
diff --git a/transport-helper.c b/transport-helper.c
index 61c928f..616db91 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -10,6 +10,7 @@
 #include "string-list.h"
 #include "thread-utils.h"
 #include "sigchain.h"
+#include "argv-array.h"
 
 static int debug;
 
@@ -17,6 +18,7 @@ struct helper_data {
 	const char *name;
 	struct child_process *helper;
 	FILE *out;
+	char *report_fifo;
 	unsigned fetch : 1,
 		import : 1,
 		export : 1,
@@ -101,6 +103,7 @@ static void do_take_over(struct transport *transport)
 static struct child_process *get_helper(struct transport *transport)
 {
 	struct helper_data *data = transport->data;
+	struct argv_array argv = ARGV_ARRAY_INIT;
 	struct strbuf buf = STRBUF_INIT;
 	struct child_process *helper;
 	const char **refspecs = NULL;
@@ -111,6 +114,7 @@ static struct child_process *get_helper(struct transport *transport)
 	char git_dir_buf[sizeof(GIT_DIR_ENVIRONMENT) + PATH_MAX + 1];
 	const char *helper_env[] = {
 		git_dir_buf,
+		NULL,	/* placeholder */
 		NULL
 	};
 
@@ -122,17 +126,23 @@ static struct child_process *get_helper(struct transport *transport)
 	helper->in = -1;
 	helper->out = -1;
 	helper->err = 0;
-	helper->argv = xcalloc(4, sizeof(*helper->argv));
-	strbuf_addf(&buf, "git-remote-%s", data->name);
-	helper->argv[0] = strbuf_detach(&buf, NULL);
-	helper->argv[1] = transport->remote->name;
-	helper->argv[2] = remove_ext_force(transport->url);
+	argv_array_pushf(&argv, "git-remote-%s", data->name);
+	argv_array_push(&argv, transport->remote->name);
+	argv_array_push(&argv, remove_ext_force(transport->url));
+	helper->argv = argv.argv;
 	helper->git_cmd = 0;
 	helper->silent_exec_failure = 1;
 
 	snprintf(git_dir_buf, sizeof(git_dir_buf), "%s=%s", GIT_DIR_ENVIRONMENT, get_git_dir());
 	helper->env = helper_env;
 
+	strbuf_init(&buf, 0);
+	strbuf_addf(&buf, "%s/fast-import-report-fifo", get_git_dir());
+	data->report_fifo = strbuf_detach(&buf, NULL);
+	strbuf_init(&buf, 0);
+	strbuf_addf(&buf, "GIT_REPORT_FIFO=%s", data->report_fifo);
+	helper_env[1] = strbuf_detach(&buf, NULL);
+
 	code = start_command(helper);
 	if (code < 0 && errno == ENOENT)
 		die("Unable to find remote helper for '%s'", data->name);
@@ -141,6 +151,8 @@ static struct child_process *get_helper(struct transport *transport)
 
 	data->helper = helper;
 	data->no_disconnect_req = 0;
+	free((void*) helper_env[1]);
+	argv_array_clear(&argv);
 
 	/*
 	 * Open the output as FILE* so strbuf_getline() can be used.
@@ -237,13 +249,13 @@ static int disconnect_helper(struct transport *transport)
 			xwrite(data->helper->in, "\n", 1);
 			sigchain_pop(SIGPIPE);
 		}
+
 		close(data->helper->in);
 		close(data->helper->out);
 		fclose(data->out);
 		res = finish_command(data->helper);
-		free((char *)data->helper->argv[0]);
-		free(data->helper->argv);
 		free(data->helper);
+		free(data->report_fifo);
 		data->helper = NULL;
 	}
 	return res;
@@ -373,16 +385,18 @@ static int fetch_with_fetch(struct transport *transport,
 	return 0;
 }
 
-static int get_importer(struct transport *transport, struct child_process *fastimport)
+static int get_importer(struct transport *transport, struct child_process *fastimport, struct argv_array *argv)
 {
 	struct child_process *helper = get_helper(transport);
+	struct helper_data *data = transport->data;
 	memset(fastimport, 0, sizeof(*fastimport));
 	fastimport->in = helper->out;
-	fastimport->argv = xcalloc(5, sizeof(*fastimport->argv));
-	fastimport->argv[0] = "fast-import";
-	fastimport->argv[1] = "--quiet";
-
+	argv_array_push(argv, "fast-import");
+	argv_array_push(argv, "--quiet");
+	argv_array_pushf(argv, "--cat-blob-pipe=%s", data->report_fifo);
+	fastimport->argv = argv->argv;
 	fastimport->git_cmd = 1;
+
 	return start_command(fastimport);
 }
 
@@ -421,10 +435,30 @@ static int fetch_with_import(struct transport *transport,
 	int i;
 	struct ref *posn;
 	struct strbuf buf = STRBUF_INIT;
+	struct argv_array importer_argv = ARGV_ARRAY_INIT;
+	struct stat fifostat;
+
+	/* create a fifo for back-reporting of fast-import to the remote helper,
+	 * if it doesn't exist. */
+	if(!stat(data->report_fifo, &fifostat)) {
+		if(S_ISFIFO(fifostat.st_mode)) {		/* exists and is fifo, unlink and recreate, to be sure that permissions are ok.. */
+			if (debug)
+				fprintf(stderr, "Debug: Remote helper: Unlinked existing fifo.\n");
+			if(unlink(data->report_fifo))
+				die_errno("Couldn't unlink fifo %s", data->report_fifo);
+		}
+		else
+			die("Fifo %s used by some other file.", data->report_fifo);
+	}
+	if(mkfifo(data->report_fifo, 0660))
+		die_errno("Couldn't create fifo %s", data->report_fifo);
+	if (debug)
+		fprintf(stderr, "Debug: Remote helper: Mkfifo %s\n", data->report_fifo);
+
 
 	get_helper(transport);
 
-	if (get_importer(transport, &fastimport))
+	if (get_importer(transport, &fastimport, &importer_argv))
 		die("Couldn't run fast-import");
 
 	for (i = 0; i < nr_heads; i++) {
@@ -441,8 +475,8 @@ static int fetch_with_import(struct transport *transport,
 
 	if (finish_command(&fastimport))
 		die("Error while running fast-import");
-	free(fastimport.argv);
-	fastimport.argv = NULL;
+
+	argv_array_clear(&importer_argv);
 
 	for (i = 0; i < nr_heads; i++) {
 		char *private;
-- 
1.7.9.5
Previous: Florian AchleitnerNext: Florian Achleitner
Message 5 of 47 in “[RFC 00/16] GSOC remote-svn, rewritten patch series”
  1. Florian AchleitnerJul 26, 2012
  2. 01/16 Implement a remote helper for svn in C.Florian Achleitner, Jul 26, 2012
  3. 02/16 Integrate remote-svn into svn-fe/Makefile.Florian Achleitner, Jul 26, 2012
  4. 03/16 Add svndump_init_fd to allow reading dumps from arbitrary FDs.Florian Achleitner, Jul 26, 2012
  5. 04/16 Add cat-blob report fifo from fast-import to remote-helper.Florian Achleitner, Jul 26, 2012
  6. 05/16 remote-svn, vcs-svn: Enable fetching to private refs.Florian Achleitner, Jul 26, 2012
  7. 06/16 Add a symlink 'git-remote-svn' in base dir.Florian Achleitner, Jul 26, 2012
  8. 07/16 Allow reading svn dumps from files via file:// urls.Florian Achleitner, Jul 26, 2012
  9. 08/16 vcs-svn: add fast_export_note to create notesFlorian Achleitner, Jul 26, 2012
  10. 09/16 Create a note for every imported commit containing svn metadata.Florian Achleitner, Jul 26, 2012
  11. 10/16 When debug==1, start fast-import with "--stats" instead of "--quiet".Florian Achleitner, Jul 26, 2012
  12. 11/16 Add explanatory comment for transport-helpers refs mapping.Florian Achleitner, Jul 26, 2012
  13. 12/16 remote-svn: add incremental import.Florian Achleitner, Jul 26, 2012
  14. 13/16 Add a svnrdump-simulator replaying a dump file for testing.Florian Achleitner, Jul 26, 2012
  15. 14/16 transport-helper: add import|export-marks to fast-import command line.Florian Achleitner, Jul 26, 2012
  16. 15/16 remote-svn: add marks-file regeneration.Florian Achleitner, Jul 26, 2012
  17. 16/16 Add a test script for remote-svn.Florian Achleitner, Jul 26, 2012
  18. Florian AchleitnerJul 26, 2012
  19. Jonathan NiederJul 28, 2012
  20. Jonathan NiederJul 26, 2012
  21. Florian AchleitnerJul 26, 2012
  22. Jonathan NiederJul 26, 2012
  23. Florian AchleitnerJul 26, 2012
  24. 00/16 GSOC remote-svn, rewritten patch seriesFlorian Achleitner, Jul 30, 2012
  25. 01/16 Implement a remote helper for svn in C.Florian Achleitner, Jul 30, 2012
  26. 02/16 Integrate remote-svn into svn-fe/Makefile.Florian Achleitner, Jul 30, 2012
  27. 03/16 Add svndump_init_fd to allow reading dumps from arbitrary FDs.Florian Achleitner, Jul 30, 2012
  28. 04/16 Add cat-blob report fifo from fast-import to remote-helper.Florian Achleitner, Jul 30, 2012
  29. 05/16 remote-svn, vcs-svn: Enable fetching to private refs.Florian Achleitner, Jul 30, 2012
  30. 06/16 Add a symlink 'git-remote-svn' in base dir.Florian Achleitner, Jul 30, 2012
  31. 07/16 Allow reading svn dumps from files via file:// urls.Florian Achleitner, Jul 30, 2012
  32. 08/16 vcs-svn: add fast_export_note to create notesFlorian Achleitner, Jul 30, 2012
  33. 09/16 Create a note for every imported commit containing svn metadata.Florian Achleitner, Jul 30, 2012
  34. 10/16 When debug==1, start fast-import with "--stats" instead of "--quiet".Florian Achleitner, Jul 30, 2012
  35. 11/16 Add explanatory comment for transport-helpers refs mapping.Florian Achleitner, Jul 30, 2012
  36. 12/16 remote-svn: add incremental import.Florian Achleitner, Jul 30, 2012
  37. 13/16 Add a svnrdump-simulator replaying a dump file for testing.Florian Achleitner, Jul 30, 2012
  38. 14/16 transport-helper: add import|export-marks to fast-import command line.Florian Achleitner, Jul 30, 2012
  39. 15/16 remote-svn: add marks-file regeneration.Florian Achleitner, Jul 30, 2012
  40. 16/16 Add a test script for remote-svn.Florian Achleitner, Jul 30, 2012
  41. Jonathan NiederJul 30, 2012
  42. Junio C HamanoJul 30, 2012
  43. Junio C HamanoJul 30, 2012
  44. Jonathan NiederJul 30, 2012
  45. Florian AchleitnerJul 30, 2012
  46. Junio C HamanoJul 30, 2012
  47. Florian AchleitnerJul 31, 2012

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.