summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2017-12-28 22:08:47 (GMT)
committerJunio C Hamano <gitster@pobox.com>2017-12-28 22:08:47 (GMT)
commit2546de27c31c65cd4a94782cc9939a662d7f837c (patch)
tree6a1fcda6c8fa8f5ed7e55c5b11518030f0ced722
parent58d1772c8562c4777414d9b97de127ae5b35ad81 (diff)
parente967ca38473a05abf3e8f7a025c6b9bee487aa4f (diff)
downloadgit-2546de27c31c65cd4a94782cc9939a662d7f837c.zip
git-2546de27c31c65cd4a94782cc9939a662d7f837c.tar.gz
git-2546de27c31c65cd4a94782cc9939a662d7f837c.tar.bz2
Merge branch 'jt/transport-hide-vtable'
Code clean-up. * jt/transport-hide-vtable: transport: make transport vtable more private clone, fetch: remove redundant transport check
-rw-r--r--builtin/clone.c3
-rw-r--r--builtin/fetch.c3
-rw-r--r--transport-helper.c23
-rw-r--r--transport-internal.h61
-rw-r--r--transport.c69
-rw-r--r--transport.h54
6 files changed, 120 insertions, 93 deletions
diff --git a/builtin/clone.c b/builtin/clone.c
index 6ad0ab3..2da71db 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1083,9 +1083,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
warning(_("--local is ignored"));
transport->cloning = 1;
- if (!transport->get_refs_list || (!is_local && !transport->fetch))
- die(_("Don't know how to clone %s"), transport->url);
-
transport_set_option(transport, TRANS_OPT_KEEP, "yes");
if (option_depth)
diff --git a/builtin/fetch.c b/builtin/fetch.c
index e656746..7bbcd26 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1095,9 +1095,6 @@ static int do_fetch(struct transport *transport,
tags = TAGS_UNSET;
}
- if (!transport->get_refs_list || !transport->fetch)
- die(_("Don't know how to fetch from %s"), transport->url);
-
/* if not appending, truncate FETCH_HEAD */
if (!append && !dry_run) {
retcode = truncate_fetch_head();
diff --git a/transport-helper.c b/transport-helper.c
index 413cd7b..5080150 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -11,6 +11,7 @@
#include "sigchain.h"
#include "argv-array.h"
#include "refs.h"
+#include "transport-internal.h"
static int debug;
@@ -650,7 +651,7 @@ static int fetch(struct transport *transport,
if (process_connect(transport, 0)) {
do_take_over(transport);
- return transport->fetch(transport, nr_heads, to_fetch);
+ return transport->vtable->fetch(transport, nr_heads, to_fetch);
}
count = 0;
@@ -990,7 +991,7 @@ static int push_refs(struct transport *transport,
if (process_connect(transport, 1)) {
do_take_over(transport);
- return transport->push_refs(transport, remote_refs, flags);
+ return transport->vtable->push_refs(transport, remote_refs, flags);
}
if (!remote_refs) {
@@ -1038,7 +1039,7 @@ static struct ref *get_refs_list(struct transport *transport, int for_push)
if (process_connect(transport, for_push)) {
do_take_over(transport);
- return transport->get_refs_list(transport, for_push);
+ return transport->vtable->get_refs_list(transport, for_push);
}
if (data->push && for_push)
@@ -1086,6 +1087,15 @@ static struct ref *get_refs_list(struct transport *transport, int for_push)
return ret;
}
+static struct transport_vtable vtable = {
+ set_helper_option,
+ get_refs_list,
+ fetch,
+ push_refs,
+ connect_helper,
+ release_helper
+};
+
int transport_helper_init(struct transport *transport, const char *name)
{
struct helper_data *data = xcalloc(1, sizeof(*data));
@@ -1097,12 +1107,7 @@ int transport_helper_init(struct transport *transport, const char *name)
debug = 1;
transport->data = data;
- transport->set_option = set_helper_option;
- transport->get_refs_list = get_refs_list;
- transport->fetch = fetch;
- transport->push_refs = push_refs;
- transport->disconnect = release_helper;
- transport->connect = connect_helper;
+ transport->vtable = &vtable;
transport->smart_options = &(data->transport_options);
return 0;
}
diff --git a/transport-internal.h b/transport-internal.h
new file mode 100644
index 0000000..3c1a29d
--- /dev/null
+++ b/transport-internal.h
@@ -0,0 +1,61 @@
+#ifndef TRANSPORT_INTERNAL_H
+#define TRANSPORT_INTERNAL_H
+
+struct ref;
+struct transport;
+
+struct transport_vtable {
+ /**
+ * Returns 0 if successful, positive if the option is not
+ * recognized or is inapplicable, and negative if the option
+ * is applicable but the value is invalid.
+ **/
+ int (*set_option)(struct transport *connection, const char *name,
+ const char *value);
+ /**
+ * Returns a list of the remote side's refs. In order to allow
+ * the transport to try to share connections, for_push is a
+ * hint as to whether the ultimate operation is a push or a fetch.
+ *
+ * If the transport is able to determine the remote hash for
+ * the ref without a huge amount of effort, it should store it
+ * in the ref's old_sha1 field; otherwise it should be all 0.
+ **/
+ struct ref *(*get_refs_list)(struct transport *transport, int for_push);
+
+ /**
+ * Fetch the objects for the given refs. Note that this gets
+ * an array, and should ignore the list structure.
+ *
+ * If the transport did not get hashes for refs in
+ * get_refs_list(), it should set the old_sha1 fields in the
+ * provided refs now.
+ **/
+ int (*fetch)(struct transport *transport, int refs_nr, struct ref **refs);
+
+ /**
+ * Push the objects and refs. Send the necessary objects, and
+ * then, for any refs where peer_ref is set and
+ * peer_ref->new_oid is different from old_oid, tell the
+ * remote side to update each ref in the list from old_oid to
+ * peer_ref->new_oid.
+ *
+ * Where possible, set the status for each ref appropriately.
+ *
+ * The transport must modify new_sha1 in the ref to the new
+ * value if the remote accepted the change. Note that this
+ * could be a different value from peer_ref->new_oid if the
+ * process involved generating new commits.
+ **/
+ int (*push_refs)(struct transport *transport, struct ref *refs, int flags);
+ int (*connect)(struct transport *connection, const char *name,
+ const char *executable, int fd[2]);
+
+ /** get_refs_list(), fetch(), and push_refs() can keep
+ * resources (such as a connection) reserved for further
+ * use. disconnect() releases these resources.
+ **/
+ int (*disconnect)(struct transport *connection);
+};
+
+#endif
diff --git a/transport.c b/transport.c
index 7cc39b7..fc80226 100644
--- a/transport.c
+++ b/transport.c
@@ -17,6 +17,7 @@
#include "string-list.h"
#include "sha1-array.h"
#include "sigchain.h"
+#include "transport-internal.h"
static void set_upstreams(struct transport *transport, struct ref *refs,
int pretend)
@@ -607,6 +608,15 @@ static int disconnect_git(struct transport *transport)
return 0;
}
+static struct transport_vtable taken_over_vtable = {
+ NULL,
+ get_refs_via_connect,
+ fetch_refs_via_pack,
+ git_transport_push,
+ NULL,
+ disconnect_git
+};
+
void transport_take_over(struct transport *transport,
struct child_process *child)
{
@@ -624,11 +634,7 @@ void transport_take_over(struct transport *transport,
data->got_remote_heads = 0;
transport->data = data;
- transport->set_option = NULL;
- transport->get_refs_list = get_refs_via_connect;
- transport->fetch = fetch_refs_via_pack;
- transport->push_refs = git_transport_push;
- transport->disconnect = disconnect_git;
+ transport->vtable = &taken_over_vtable;
transport->smart_options = &(data->options);
transport->cannot_reuse = 1;
@@ -751,6 +757,24 @@ void transport_check_allowed(const char *type)
die("transport '%s' not allowed", type);
}
+static struct transport_vtable bundle_vtable = {
+ NULL,
+ get_refs_from_bundle,
+ fetch_refs_from_bundle,
+ NULL,
+ NULL,
+ close_bundle
+};
+
+static struct transport_vtable builtin_smart_vtable = {
+ NULL,
+ get_refs_via_connect,
+ fetch_refs_via_pack,
+ git_transport_push,
+ connect_git,
+ disconnect_git
+};
+
struct transport *transport_get(struct remote *remote, const char *url)
{
const char *helper;
@@ -787,9 +811,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
transport_check_allowed("file");
ret->data = data;
- ret->get_refs_list = get_refs_from_bundle;
- ret->fetch = fetch_refs_from_bundle;
- ret->disconnect = close_bundle;
+ ret->vtable = &bundle_vtable;
ret->smart_options = NULL;
} else if (!is_url(url)
|| starts_with(url, "file://")
@@ -804,12 +826,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
*/
struct git_transport_data *data = xcalloc(1, sizeof(*data));
ret->data = data;
- ret->set_option = NULL;
- ret->get_refs_list = get_refs_via_connect;
- ret->fetch = fetch_refs_via_pack;
- ret->push_refs = git_transport_push;
- ret->connect = connect_git;
- ret->disconnect = disconnect_git;
+ ret->vtable = &builtin_smart_vtable;
ret->smart_options = &(data->options);
data->conn = NULL;
@@ -843,9 +860,9 @@ int transport_set_option(struct transport *transport,
git_reports = set_git_option(transport->smart_options,
name, value);
- if (transport->set_option)
- protocol_reports = transport->set_option(transport, name,
- value);
+ if (transport->vtable->set_option)
+ protocol_reports = transport->vtable->set_option(transport,
+ name, value);
/* If either report is 0, report 0 (success). */
if (!git_reports || !protocol_reports)
@@ -968,7 +985,7 @@ int transport_push(struct transport *transport,
*reject_reasons = 0;
transport_verify_remote_names(refspec_nr, refspec);
- if (transport->push_refs) {
+ if (transport->vtable->push_refs) {
struct ref *remote_refs;
struct ref *local_refs = get_local_heads();
int match_flags = MATCH_REFS_NONE;
@@ -981,7 +998,7 @@ int transport_push(struct transport *transport,
if (check_push_refs(local_refs, refspec_nr, refspec) < 0)
return -1;
- remote_refs = transport->get_refs_list(transport, 1);
+ remote_refs = transport->vtable->get_refs_list(transport, 1);
if (flags & TRANSPORT_PUSH_ALL)
match_flags |= MATCH_REFS_ALL;
@@ -1056,7 +1073,7 @@ int transport_push(struct transport *transport,
}
if (!(flags & TRANSPORT_RECURSE_SUBMODULES_ONLY))
- push_ret = transport->push_refs(transport, remote_refs, flags);
+ push_ret = transport->vtable->push_refs(transport, remote_refs, flags);
else
push_ret = 0;
err = push_had_errors(remote_refs);
@@ -1090,7 +1107,7 @@ int transport_push(struct transport *transport,
const struct ref *transport_get_remote_refs(struct transport *transport)
{
if (!transport->got_remote_refs) {
- transport->remote_refs = transport->get_refs_list(transport, 0);
+ transport->remote_refs = transport->vtable->get_refs_list(transport, 0);
transport->got_remote_refs = 1;
}
@@ -1127,7 +1144,7 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs)
heads[nr_heads++] = rm;
}
- rc = transport->fetch(transport, nr_heads, heads);
+ rc = transport->vtable->fetch(transport, nr_heads, heads);
free(heads);
return rc;
@@ -1144,8 +1161,8 @@ void transport_unlock_pack(struct transport *transport)
int transport_connect(struct transport *transport, const char *name,
const char *exec, int fd[2])
{
- if (transport->connect)
- return transport->connect(transport, name, exec, fd);
+ if (transport->vtable->connect)
+ return transport->vtable->connect(transport, name, exec, fd);
else
die("Operation not supported by protocol");
}
@@ -1153,8 +1170,8 @@ int transport_connect(struct transport *transport, const char *name,
int transport_disconnect(struct transport *transport)
{
int ret = 0;
- if (transport->disconnect)
- ret = transport->disconnect(transport);
+ if (transport->vtable->disconnect)
+ ret = transport->vtable->disconnect(transport);
free(transport);
return ret;
}
diff --git a/transport.h b/transport.h
index ab4fe7f..731c78b 100644
--- a/transport.h
+++ b/transport.h
@@ -30,6 +30,8 @@ enum transport_family {
};
struct transport {
+ const struct transport_vtable *vtable;
+
struct remote *remote;
const char *url;
void *data;
@@ -59,58 +61,6 @@ struct transport {
*/
const struct string_list *push_options;
- /**
- * Returns 0 if successful, positive if the option is not
- * recognized or is inapplicable, and negative if the option
- * is applicable but the value is invalid.
- **/
- int (*set_option)(struct transport *connection, const char *name,
- const char *value);
-
- /**
- * Returns a list of the remote side's refs. In order to allow
- * the transport to try to share connections, for_push is a
- * hint as to whether the ultimate operation is a push or a fetch.
- *
- * If the transport is able to determine the remote hash for
- * the ref without a huge amount of effort, it should store it
- * in the ref's old_sha1 field; otherwise it should be all 0.
- **/
- struct ref *(*get_refs_list)(struct transport *transport, int for_push);
-
- /**
- * Fetch the objects for the given refs. Note that this gets
- * an array, and should ignore the list structure.
- *
- * If the transport did not get hashes for refs in
- * get_refs_list(), it should set the old_sha1 fields in the
- * provided refs now.
- **/
- int (*fetch)(struct transport *transport, int refs_nr, struct ref **refs);
-
- /**
- * Push the objects and refs. Send the necessary objects, and
- * then, for any refs where peer_ref is set and
- * peer_ref->new_oid is different from old_oid, tell the
- * remote side to update each ref in the list from old_oid to
- * peer_ref->new_oid.
- *
- * Where possible, set the status for each ref appropriately.
- *
- * The transport must modify new_sha1 in the ref to the new
- * value if the remote accepted the change. Note that this
- * could be a different value from peer_ref->new_oid if the
- * process involved generating new commits.
- **/
- int (*push_refs)(struct transport *transport, struct ref *refs, int flags);
- int (*connect)(struct transport *connection, const char *name,
- const char *executable, int fd[2]);
-
- /** get_refs_list(), fetch(), and push_refs() can keep
- * resources (such as a connection) reserved for further
- * use. disconnect() releases these resources.
- **/
- int (*disconnect)(struct transport *connection);
char *pack_lockfile;
signed verbose : 3;
/**