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
This commit is contained in:
@ -1083,9 +1083,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
warning(_("--local is ignored"));
|
warning(_("--local is ignored"));
|
||||||
transport->cloning = 1;
|
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");
|
transport_set_option(transport, TRANS_OPT_KEEP, "yes");
|
||||||
|
|
||||||
if (option_depth)
|
if (option_depth)
|
||||||
|
@ -1095,9 +1095,6 @@ static int do_fetch(struct transport *transport,
|
|||||||
tags = TAGS_UNSET;
|
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 not appending, truncate FETCH_HEAD */
|
||||||
if (!append && !dry_run) {
|
if (!append && !dry_run) {
|
||||||
retcode = truncate_fetch_head();
|
retcode = truncate_fetch_head();
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "sigchain.h"
|
#include "sigchain.h"
|
||||||
#include "argv-array.h"
|
#include "argv-array.h"
|
||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
|
#include "transport-internal.h"
|
||||||
|
|
||||||
static int debug;
|
static int debug;
|
||||||
|
|
||||||
@ -650,7 +651,7 @@ static int fetch(struct transport *transport,
|
|||||||
|
|
||||||
if (process_connect(transport, 0)) {
|
if (process_connect(transport, 0)) {
|
||||||
do_take_over(transport);
|
do_take_over(transport);
|
||||||
return transport->fetch(transport, nr_heads, to_fetch);
|
return transport->vtable->fetch(transport, nr_heads, to_fetch);
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
@ -990,7 +991,7 @@ static int push_refs(struct transport *transport,
|
|||||||
|
|
||||||
if (process_connect(transport, 1)) {
|
if (process_connect(transport, 1)) {
|
||||||
do_take_over(transport);
|
do_take_over(transport);
|
||||||
return transport->push_refs(transport, remote_refs, flags);
|
return transport->vtable->push_refs(transport, remote_refs, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!remote_refs) {
|
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)) {
|
if (process_connect(transport, for_push)) {
|
||||||
do_take_over(transport);
|
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)
|
if (data->push && for_push)
|
||||||
@ -1086,6 +1087,15 @@ static struct ref *get_refs_list(struct transport *transport, int for_push)
|
|||||||
return ret;
|
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)
|
int transport_helper_init(struct transport *transport, const char *name)
|
||||||
{
|
{
|
||||||
struct helper_data *data = xcalloc(1, sizeof(*data));
|
struct helper_data *data = xcalloc(1, sizeof(*data));
|
||||||
@ -1097,12 +1107,7 @@ int transport_helper_init(struct transport *transport, const char *name)
|
|||||||
debug = 1;
|
debug = 1;
|
||||||
|
|
||||||
transport->data = data;
|
transport->data = data;
|
||||||
transport->set_option = set_helper_option;
|
transport->vtable = &vtable;
|
||||||
transport->get_refs_list = get_refs_list;
|
|
||||||
transport->fetch = fetch;
|
|
||||||
transport->push_refs = push_refs;
|
|
||||||
transport->disconnect = release_helper;
|
|
||||||
transport->connect = connect_helper;
|
|
||||||
transport->smart_options = &(data->transport_options);
|
transport->smart_options = &(data->transport_options);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
61
transport-internal.h
Normal file
61
transport-internal.h
Normal file
@ -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
|
69
transport.c
69
transport.c
@ -17,6 +17,7 @@
|
|||||||
#include "string-list.h"
|
#include "string-list.h"
|
||||||
#include "sha1-array.h"
|
#include "sha1-array.h"
|
||||||
#include "sigchain.h"
|
#include "sigchain.h"
|
||||||
|
#include "transport-internal.h"
|
||||||
|
|
||||||
static void set_upstreams(struct transport *transport, struct ref *refs,
|
static void set_upstreams(struct transport *transport, struct ref *refs,
|
||||||
int pretend)
|
int pretend)
|
||||||
@ -607,6 +608,15 @@ static int disconnect_git(struct transport *transport)
|
|||||||
return 0;
|
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,
|
void transport_take_over(struct transport *transport,
|
||||||
struct child_process *child)
|
struct child_process *child)
|
||||||
{
|
{
|
||||||
@ -624,11 +634,7 @@ void transport_take_over(struct transport *transport,
|
|||||||
data->got_remote_heads = 0;
|
data->got_remote_heads = 0;
|
||||||
transport->data = data;
|
transport->data = data;
|
||||||
|
|
||||||
transport->set_option = NULL;
|
transport->vtable = &taken_over_vtable;
|
||||||
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->smart_options = &(data->options);
|
transport->smart_options = &(data->options);
|
||||||
|
|
||||||
transport->cannot_reuse = 1;
|
transport->cannot_reuse = 1;
|
||||||
@ -751,6 +757,24 @@ void transport_check_allowed(const char *type)
|
|||||||
die("transport '%s' not allowed", 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)
|
struct transport *transport_get(struct remote *remote, const char *url)
|
||||||
{
|
{
|
||||||
const char *helper;
|
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));
|
struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
|
||||||
transport_check_allowed("file");
|
transport_check_allowed("file");
|
||||||
ret->data = data;
|
ret->data = data;
|
||||||
ret->get_refs_list = get_refs_from_bundle;
|
ret->vtable = &bundle_vtable;
|
||||||
ret->fetch = fetch_refs_from_bundle;
|
|
||||||
ret->disconnect = close_bundle;
|
|
||||||
ret->smart_options = NULL;
|
ret->smart_options = NULL;
|
||||||
} else if (!is_url(url)
|
} else if (!is_url(url)
|
||||||
|| starts_with(url, "file://")
|
|| 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));
|
struct git_transport_data *data = xcalloc(1, sizeof(*data));
|
||||||
ret->data = data;
|
ret->data = data;
|
||||||
ret->set_option = NULL;
|
ret->vtable = &builtin_smart_vtable;
|
||||||
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->smart_options = &(data->options);
|
ret->smart_options = &(data->options);
|
||||||
|
|
||||||
data->conn = NULL;
|
data->conn = NULL;
|
||||||
@ -843,9 +860,9 @@ int transport_set_option(struct transport *transport,
|
|||||||
git_reports = set_git_option(transport->smart_options,
|
git_reports = set_git_option(transport->smart_options,
|
||||||
name, value);
|
name, value);
|
||||||
|
|
||||||
if (transport->set_option)
|
if (transport->vtable->set_option)
|
||||||
protocol_reports = transport->set_option(transport, name,
|
protocol_reports = transport->vtable->set_option(transport,
|
||||||
value);
|
name, value);
|
||||||
|
|
||||||
/* If either report is 0, report 0 (success). */
|
/* If either report is 0, report 0 (success). */
|
||||||
if (!git_reports || !protocol_reports)
|
if (!git_reports || !protocol_reports)
|
||||||
@ -968,7 +985,7 @@ int transport_push(struct transport *transport,
|
|||||||
*reject_reasons = 0;
|
*reject_reasons = 0;
|
||||||
transport_verify_remote_names(refspec_nr, refspec);
|
transport_verify_remote_names(refspec_nr, refspec);
|
||||||
|
|
||||||
if (transport->push_refs) {
|
if (transport->vtable->push_refs) {
|
||||||
struct ref *remote_refs;
|
struct ref *remote_refs;
|
||||||
struct ref *local_refs = get_local_heads();
|
struct ref *local_refs = get_local_heads();
|
||||||
int match_flags = MATCH_REFS_NONE;
|
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)
|
if (check_push_refs(local_refs, refspec_nr, refspec) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
remote_refs = transport->get_refs_list(transport, 1);
|
remote_refs = transport->vtable->get_refs_list(transport, 1);
|
||||||
|
|
||||||
if (flags & TRANSPORT_PUSH_ALL)
|
if (flags & TRANSPORT_PUSH_ALL)
|
||||||
match_flags |= MATCH_REFS_ALL;
|
match_flags |= MATCH_REFS_ALL;
|
||||||
@ -1056,7 +1073,7 @@ int transport_push(struct transport *transport,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(flags & TRANSPORT_RECURSE_SUBMODULES_ONLY))
|
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
|
else
|
||||||
push_ret = 0;
|
push_ret = 0;
|
||||||
err = push_had_errors(remote_refs);
|
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)
|
const struct ref *transport_get_remote_refs(struct transport *transport)
|
||||||
{
|
{
|
||||||
if (!transport->got_remote_refs) {
|
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;
|
transport->got_remote_refs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1127,7 +1144,7 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs)
|
|||||||
heads[nr_heads++] = rm;
|
heads[nr_heads++] = rm;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = transport->fetch(transport, nr_heads, heads);
|
rc = transport->vtable->fetch(transport, nr_heads, heads);
|
||||||
|
|
||||||
free(heads);
|
free(heads);
|
||||||
return rc;
|
return rc;
|
||||||
@ -1144,8 +1161,8 @@ void transport_unlock_pack(struct transport *transport)
|
|||||||
int transport_connect(struct transport *transport, const char *name,
|
int transport_connect(struct transport *transport, const char *name,
|
||||||
const char *exec, int fd[2])
|
const char *exec, int fd[2])
|
||||||
{
|
{
|
||||||
if (transport->connect)
|
if (transport->vtable->connect)
|
||||||
return transport->connect(transport, name, exec, fd);
|
return transport->vtable->connect(transport, name, exec, fd);
|
||||||
else
|
else
|
||||||
die("Operation not supported by protocol");
|
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 transport_disconnect(struct transport *transport)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
if (transport->disconnect)
|
if (transport->vtable->disconnect)
|
||||||
ret = transport->disconnect(transport);
|
ret = transport->vtable->disconnect(transport);
|
||||||
free(transport);
|
free(transport);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
54
transport.h
54
transport.h
@ -30,6 +30,8 @@ enum transport_family {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct transport {
|
struct transport {
|
||||||
|
const struct transport_vtable *vtable;
|
||||||
|
|
||||||
struct remote *remote;
|
struct remote *remote;
|
||||||
const char *url;
|
const char *url;
|
||||||
void *data;
|
void *data;
|
||||||
@ -59,58 +61,6 @@ struct transport {
|
|||||||
*/
|
*/
|
||||||
const struct string_list *push_options;
|
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;
|
char *pack_lockfile;
|
||||||
signed verbose : 3;
|
signed verbose : 3;
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user