[RFC/PATCH 5/6] Let transport_helper_init() decide if a remote helper program can be used

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Teach the transport-helper mechanism to verify that the remote helper
program is available, before finalizing the transport setup.
If the remote helper is NOT available, transport_helper_init() returns -1,
and transport_get() falls back to trying a native transport.

This patch introduces a subtle, but important change in the handling of
remotes and their URLs:

Before this patch, we only invoke transport_helper_init() _after_ we find
that the transport-helper mechanism is appropriate for this remote
(i.e. the remote is "foreign", or is handled by the curl helper).

This patch moves the decision point into transport_helper_init(): If the
remote is not obviously using a native transport (URL starts with "file:",
"git:" or "ssh:"), then we first call transport_helper_init(), and only if
it returns error (meaning that no appropriate remote helper program was
found) do we fall back to native transport handling.

Signed-off-by: Johan Herland <johan@xxxxxxxxxxx>
---
 transport-helper.c |   22 ++++++++++++++++++++--
 transport.c        |   11 ++++++-----
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/transport-helper.c b/transport-helper.c
index d3ce984..de30727 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -5,6 +5,7 @@
 #include "commit.h"
 #include "diff.h"
 #include "revision.h"
+#include "help.h"
 
 struct helper_data
 {
@@ -279,11 +280,18 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons
 
 int transport_helper_init(struct transport *transport)
 {
-	struct helper_data *data = xcalloc(sizeof(*data), 1);
+	struct helper_data *data;
+	struct strbuf buf = STRBUF_INIT;
+	char *cmd;
+
+	if (!transport->remote)
+		return -1;
 
+	data = xcalloc(sizeof(*data), 1);
 	if (transport->remote->foreign_vcs) {
 		data->name = xstrdup(transport->remote->foreign_vcs);
-		transport->url = transport->remote->foreign_vcs;
+		if (!transport->url)
+			transport->url = transport->remote->foreign_vcs;
 	} else {
 		char *eom = strchr(transport->url, ':');
 		if (!eom) {
@@ -293,6 +301,16 @@ int transport_helper_init(struct transport *transport)
 		data->name = xstrndup(transport->url, eom - transport->url);
 	}
 
+	strbuf_addf(&buf, "remote-%s", data->name);
+	cmd = strbuf_detach(&buf, NULL);
+	if (!is_git_command_or_alias(cmd)) {
+		warning("Could not find remote helper command \"git %s\". Assuming native remote.", cmd);
+		free(cmd);
+		free(data->name);
+		free(data);
+		return -1;
+	}
+
 	transport->data = data;
 	transport->get_refs_list = get_refs_list;
 	transport->fetch = fetch;
diff --git a/transport.c b/transport.c
index 81a28bc..b7033eb 100644
--- a/transport.c
+++ b/transport.c
@@ -794,11 +794,12 @@ struct transport *transport_get(struct remote *remote, const char *url)
 		ret->fetch = fetch_objs_via_rsync;
 		ret->push = rsync_transport_push;
 
-	} else if (!url
-	        || !prefixcmp(url, "http://";)
-	        || !prefixcmp(url, "https://";)
-	        || !prefixcmp(url, "ftp://";)) {
-		transport_helper_init(ret);
+	} else if ((!url
+	         || (prefixcmp(url, "git:")
+	          && prefixcmp(url, "ssh:")
+	          && prefixcmp(url, "file:")))
+	        && !transport_helper_init(ret)) {
+		/* no-op, ret is initialized by transport_helper_init() */
 
 	} else if (url && is_local(url) && is_file(url)) {
 		struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
-- 
1.6.4.rc3.138.ga6b98.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]