Support remote archive from all smart transports
Previously, remote archive required internal (non remote-helper) smart transport. Extend the remote archive to also support smart transports implemented by remote helpers. Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Ilari Liusvaara committed
Dec 9, 2009 at 17:26 UTC
b236752a8722c77b5a9b4ed488a992ee05252843
4 files changed
+55
-7
builtin-archive.c
+10
-7
@@ -5,6 +5,7 @@
5
#include "cache.h"
6
#include "builtin.h"
7
#include "archive.h"
8
+#include "transport.h"
9
#include "parse-options.h"
10
#include "pkt-line.h"
11
#include "sideband.h"
@@ -25,12 +26,16 @@ static void create_output_file(const char *output_file)
26
static int run_remote_archiver(int argc, const char **argv,
27
const char *remote, const char *exec)
28
{
28
- char *url, buf[LARGE_PACKET_MAX];
29
+ char buf[LARGE_PACKET_MAX];
30
int fd[2], i, len, rv;
30
- struct child_process *conn;
31
+ struct transport *transport;
32
+ struct remote *_remote;
33
32
- url = xstrdup(remote);
33
- conn = git_connect(fd, url, exec, 0);
34
+ _remote = remote_get(remote);
35
+ if (!_remote->url[0])
36
+ die("git archive: Remote with no URL");
37
+ transport = transport_get(_remote, _remote->url[0]);
38
+ transport_connect(transport, "git-upload-archive", exec, fd);
39
40
for (i = 1; i < argc; i++)
41
packet_write(fd[1], "argument %s\n", argv[i]);
@@ -53,9 +58,7 @@ static int run_remote_archiver(int argc, const char **argv,
58
59
/* Now, start reading from fd[0] and spit it out to stdout */
60
rv = recv_sideband("archive", fd[0], 1);
56
- close(fd[0]);
57
- close(fd[1]);
58
- rv |= finish_connect(conn);
61
+ rv |= transport_disconnect(transport);
62
63
return !!rv;
64
}
transport-helper.c
+19
@@ -467,6 +467,24 @@ static int process_connect(struct transport *transport,
467
return process_connect_service(transport, name, exec);
468
}
469
470
+static int connect_helper(struct transport *transport, const char *name,
471
+ const char *exec, int fd[2])
472
+{
473
+ struct helper_data *data = transport->data;
474
+
475
+ /* Get_helper so connect is inited. */
476
+ get_helper(transport);
477
+ if (!data->connect)
478
+ die("Operation not supported by protocol.");
479
+
480
+ if (!process_connect_service(transport, name, exec))
481
+ die("Can't connect to subservice %s.", name);
482
+
483
+ fd[0] = data->helper->out;
484
+ fd[1] = data->helper->in;
485
+ return 0;
486
+}
487
+
488
static int fetch(struct transport *transport,
489
int nr_heads, struct ref **to_fetch)
490
{
@@ -711,6 +729,7 @@ int transport_helper_init(struct transport *transport, const char *name)
729
transport->fetch = fetch;
730
transport->push_refs = push_refs;
731
transport->disconnect = release_helper;
732
+ transport->connect = connect_helper;
733
transport->smart_options = &(data->transport_options);
734
return 0;
735
}
transport.c
+21
@@ -756,6 +756,17 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
756
return ret;
757
}
758
759
+static int connect_git(struct transport *transport, const char *name,
760
+ const char *executable, int fd[2])
761
+{
762
+ struct git_transport_data *data = transport->data;
763
+ data->conn = git_connect(data->fd, transport->url,
764
+ executable, 0);
765
+ fd[0] = data->fd[0];
766
+ fd[1] = data->fd[1];
767
+ return 0;
768
+}
769
+
770
static int disconnect_git(struct transport *transport)
771
{
772
struct git_transport_data *data = transport->data;
@@ -901,6 +912,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
912
ret->get_refs_list = get_refs_via_connect;
913
ret->fetch = fetch_refs_via_pack;
914
ret->push_refs = git_transport_push;
915
+ ret->connect = connect_git;
916
ret->disconnect = disconnect_git;
917
ret->smart_options = &(data->options);
918
@@ -1061,6 +1073,15 @@ void transport_unlock_pack(struct transport *transport)
1073
}
1074
}
1075
1076
+int transport_connect(struct transport *transport, const char *name,
1077
+ const char *exec, int fd[2])
1078
+{
1079
+ if (transport->connect)
1080
+ return transport->connect(transport, name, exec, fd);
1081
+ else
1082
+ die("Operation not supported by protocol");
1083
+}
1084
+
1085
int transport_disconnect(struct transport *transport)
1086
{
1087
int ret = 0;
transport.h
+5
@@ -64,6 +64,8 @@ struct transport {
64
**/
65
int (*push_refs)(struct transport *transport, struct ref *refs, int flags);
66
int (*push)(struct transport *connection, int refspec_nr, const char **refspec, int flags);
67
+ int (*connect)(struct transport *connection, const char *name,
68
+ const char *executable, int fd[2]);
69
70
/** get_refs_list(), fetch(), and push_refs() can keep
71
* resources (such as a connection) reserved for futher
@@ -133,6 +135,9 @@ char *transport_anonymize_url(const char *url);
135
void transport_take_over(struct transport *transport,
136
struct child_process *child);
137
138
+int transport_connect(struct transport *transport, const char *name,
139
+ const char *exec, int fd[2]);
140
+
141
/* Transport methods defined outside transport.c */
142
int transport_helper_init(struct transport *transport, const char *name);
143