Refactor git transport options parsing
Refactor the transport options parsing so that protocols that aren't directly smart transports (file://, git://, ssh:// & co) can record the smart transport options for the case if it turns that transport can actually be smart. Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
25d5cc488a
commit
aa5af9749f
78
transport.c
78
transport.c
@ -395,41 +395,35 @@ static int close_bundle(struct transport *transport)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct git_transport_data {
|
struct git_transport_data {
|
||||||
unsigned thin : 1;
|
struct git_transport_options options;
|
||||||
unsigned keep : 1;
|
|
||||||
unsigned followtags : 1;
|
|
||||||
int depth;
|
|
||||||
struct child_process *conn;
|
struct child_process *conn;
|
||||||
int fd[2];
|
int fd[2];
|
||||||
const char *uploadpack;
|
|
||||||
const char *receivepack;
|
|
||||||
struct extra_have_objects extra_have;
|
struct extra_have_objects extra_have;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int set_git_option(struct transport *connection,
|
static int set_git_option(struct git_transport_options *opts,
|
||||||
const char *name, const char *value)
|
const char *name, const char *value)
|
||||||
{
|
{
|
||||||
struct git_transport_data *data = connection->data;
|
|
||||||
if (!strcmp(name, TRANS_OPT_UPLOADPACK)) {
|
if (!strcmp(name, TRANS_OPT_UPLOADPACK)) {
|
||||||
data->uploadpack = value;
|
opts->uploadpack = value;
|
||||||
return 0;
|
return 0;
|
||||||
} else if (!strcmp(name, TRANS_OPT_RECEIVEPACK)) {
|
} else if (!strcmp(name, TRANS_OPT_RECEIVEPACK)) {
|
||||||
data->receivepack = value;
|
opts->receivepack = value;
|
||||||
return 0;
|
return 0;
|
||||||
} else if (!strcmp(name, TRANS_OPT_THIN)) {
|
} else if (!strcmp(name, TRANS_OPT_THIN)) {
|
||||||
data->thin = !!value;
|
opts->thin = !!value;
|
||||||
return 0;
|
return 0;
|
||||||
} else if (!strcmp(name, TRANS_OPT_FOLLOWTAGS)) {
|
} else if (!strcmp(name, TRANS_OPT_FOLLOWTAGS)) {
|
||||||
data->followtags = !!value;
|
opts->followtags = !!value;
|
||||||
return 0;
|
return 0;
|
||||||
} else if (!strcmp(name, TRANS_OPT_KEEP)) {
|
} else if (!strcmp(name, TRANS_OPT_KEEP)) {
|
||||||
data->keep = !!value;
|
opts->keep = !!value;
|
||||||
return 0;
|
return 0;
|
||||||
} else if (!strcmp(name, TRANS_OPT_DEPTH)) {
|
} else if (!strcmp(name, TRANS_OPT_DEPTH)) {
|
||||||
if (!value)
|
if (!value)
|
||||||
data->depth = 0;
|
opts->depth = 0;
|
||||||
else
|
else
|
||||||
data->depth = atoi(value);
|
opts->depth = atoi(value);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -439,7 +433,8 @@ static int connect_setup(struct transport *transport, int for_push, int verbose)
|
|||||||
{
|
{
|
||||||
struct git_transport_data *data = transport->data;
|
struct git_transport_data *data = transport->data;
|
||||||
data->conn = git_connect(data->fd, transport->url,
|
data->conn = git_connect(data->fd, transport->url,
|
||||||
for_push ? data->receivepack : data->uploadpack,
|
for_push ? data->options.receivepack :
|
||||||
|
data->options.uploadpack,
|
||||||
verbose ? CONNECT_VERBOSE : 0);
|
verbose ? CONNECT_VERBOSE : 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -469,15 +464,15 @@ static int fetch_refs_via_pack(struct transport *transport,
|
|||||||
struct ref *refs_tmp = NULL;
|
struct ref *refs_tmp = NULL;
|
||||||
|
|
||||||
memset(&args, 0, sizeof(args));
|
memset(&args, 0, sizeof(args));
|
||||||
args.uploadpack = data->uploadpack;
|
args.uploadpack = data->options.uploadpack;
|
||||||
args.keep_pack = data->keep;
|
args.keep_pack = data->options.keep;
|
||||||
args.lock_pack = 1;
|
args.lock_pack = 1;
|
||||||
args.use_thin_pack = data->thin;
|
args.use_thin_pack = data->options.thin;
|
||||||
args.include_tag = data->followtags;
|
args.include_tag = data->options.followtags;
|
||||||
args.verbose = (transport->verbose > 0);
|
args.verbose = (transport->verbose > 0);
|
||||||
args.quiet = (transport->verbose < 0);
|
args.quiet = (transport->verbose < 0);
|
||||||
args.no_progress = args.quiet || (!transport->progress && !isatty(1));
|
args.no_progress = args.quiet || (!transport->progress && !isatty(1));
|
||||||
args.depth = data->depth;
|
args.depth = data->options.depth;
|
||||||
|
|
||||||
for (i = 0; i < nr_heads; i++)
|
for (i = 0; i < nr_heads; i++)
|
||||||
origh[i] = heads[i] = xstrdup(to_fetch[i]->name);
|
origh[i] = heads[i] = xstrdup(to_fetch[i]->name);
|
||||||
@ -734,7 +729,7 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
|
|||||||
memset(&args, 0, sizeof(args));
|
memset(&args, 0, sizeof(args));
|
||||||
args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR);
|
args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR);
|
||||||
args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
|
args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
|
||||||
args.use_thin_pack = data->thin;
|
args.use_thin_pack = data->options.thin;
|
||||||
args.verbose = !!(flags & TRANSPORT_PUSH_VERBOSE);
|
args.verbose = !!(flags & TRANSPORT_PUSH_VERBOSE);
|
||||||
args.quiet = !!(flags & TRANSPORT_PUSH_QUIET);
|
args.quiet = !!(flags & TRANSPORT_PUSH_QUIET);
|
||||||
args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
|
args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
|
||||||
@ -847,12 +842,14 @@ struct transport *transport_get(struct remote *remote, const char *url)
|
|||||||
ret->get_refs_list = get_refs_via_rsync;
|
ret->get_refs_list = get_refs_via_rsync;
|
||||||
ret->fetch = fetch_objs_via_rsync;
|
ret->fetch = fetch_objs_via_rsync;
|
||||||
ret->push = rsync_transport_push;
|
ret->push = rsync_transport_push;
|
||||||
|
ret->smart_options = NULL;
|
||||||
} else if (is_local(url) && is_file(url)) {
|
} else if (is_local(url) && is_file(url)) {
|
||||||
struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
|
struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
|
||||||
ret->data = data;
|
ret->data = data;
|
||||||
ret->get_refs_list = get_refs_from_bundle;
|
ret->get_refs_list = get_refs_from_bundle;
|
||||||
ret->fetch = fetch_refs_from_bundle;
|
ret->fetch = fetch_refs_from_bundle;
|
||||||
ret->disconnect = close_bundle;
|
ret->disconnect = close_bundle;
|
||||||
|
ret->smart_options = NULL;
|
||||||
} else if (!is_url(url)
|
} else if (!is_url(url)
|
||||||
|| !prefixcmp(url, "file://")
|
|| !prefixcmp(url, "file://")
|
||||||
|| !prefixcmp(url, "git://")
|
|| !prefixcmp(url, "git://")
|
||||||
@ -862,20 +859,14 @@ struct transport *transport_get(struct remote *remote, const char *url)
|
|||||||
/* These are builtin smart transports. */
|
/* These are builtin smart transports. */
|
||||||
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 = set_git_option;
|
ret->set_option = NULL;
|
||||||
ret->get_refs_list = get_refs_via_connect;
|
ret->get_refs_list = get_refs_via_connect;
|
||||||
ret->fetch = fetch_refs_via_pack;
|
ret->fetch = fetch_refs_via_pack;
|
||||||
ret->push_refs = git_transport_push;
|
ret->push_refs = git_transport_push;
|
||||||
ret->disconnect = disconnect_git;
|
ret->disconnect = disconnect_git;
|
||||||
|
ret->smart_options = &(data->options);
|
||||||
|
|
||||||
data->thin = 1;
|
|
||||||
data->conn = NULL;
|
data->conn = NULL;
|
||||||
data->uploadpack = "git-upload-pack";
|
|
||||||
if (remote->uploadpack)
|
|
||||||
data->uploadpack = remote->uploadpack;
|
|
||||||
data->receivepack = "git-receive-pack";
|
|
||||||
if (remote->receivepack)
|
|
||||||
data->receivepack = remote->receivepack;
|
|
||||||
} else if (!prefixcmp(url, "http://")
|
} else if (!prefixcmp(url, "http://")
|
||||||
|| !prefixcmp(url, "https://")
|
|| !prefixcmp(url, "https://")
|
||||||
|| !prefixcmp(url, "ftp://")) {
|
|| !prefixcmp(url, "ftp://")) {
|
||||||
@ -893,14 +884,39 @@ struct transport *transport_get(struct remote *remote, const char *url)
|
|||||||
transport_helper_init(ret, handler);
|
transport_helper_init(ret, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret->smart_options) {
|
||||||
|
ret->smart_options->thin = 1;
|
||||||
|
ret->smart_options->uploadpack = "git-upload-pack";
|
||||||
|
if (remote->uploadpack)
|
||||||
|
ret->smart_options->uploadpack = remote->uploadpack;
|
||||||
|
ret->smart_options->receivepack = "git-receive-pack";
|
||||||
|
if (remote->receivepack)
|
||||||
|
ret->smart_options->receivepack = remote->receivepack;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int transport_set_option(struct transport *transport,
|
int transport_set_option(struct transport *transport,
|
||||||
const char *name, const char *value)
|
const char *name, const char *value)
|
||||||
{
|
{
|
||||||
|
int git_reports = 1, protocol_reports = 1;
|
||||||
|
|
||||||
|
if (transport->smart_options)
|
||||||
|
git_reports = set_git_option(transport->smart_options,
|
||||||
|
name, value);
|
||||||
|
|
||||||
if (transport->set_option)
|
if (transport->set_option)
|
||||||
return transport->set_option(transport, name, value);
|
protocol_reports = transport->set_option(transport, name,
|
||||||
|
value);
|
||||||
|
|
||||||
|
/* If either report is 0, report 0 (success). */
|
||||||
|
if (!git_reports || !protocol_reports)
|
||||||
|
return 0;
|
||||||
|
/* If either reports -1 (invalid value), report -1. */
|
||||||
|
if ((git_reports == -1) || (protocol_reports == -1))
|
||||||
|
return -1;
|
||||||
|
/* Otherwise if both report unknown, report unknown. */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
transport.h
15
transport.h
@ -4,6 +4,15 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
|
|
||||||
|
struct git_transport_options {
|
||||||
|
unsigned thin : 1;
|
||||||
|
unsigned keep : 1;
|
||||||
|
unsigned followtags : 1;
|
||||||
|
int depth;
|
||||||
|
const char *uploadpack;
|
||||||
|
const char *receivepack;
|
||||||
|
};
|
||||||
|
|
||||||
struct transport {
|
struct transport {
|
||||||
struct remote *remote;
|
struct remote *remote;
|
||||||
const char *url;
|
const char *url;
|
||||||
@ -65,6 +74,12 @@ struct transport {
|
|||||||
signed verbose : 3;
|
signed verbose : 3;
|
||||||
/* Force progress even if the output is not a tty */
|
/* Force progress even if the output is not a tty */
|
||||||
unsigned progress : 1;
|
unsigned progress : 1;
|
||||||
|
/*
|
||||||
|
* If transport is at least potentially smart, this points to
|
||||||
|
* git_transport_options structure to use in case transport
|
||||||
|
* actually turns out to be smart.
|
||||||
|
*/
|
||||||
|
struct git_transport_options *smart_options;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TRANSPORT_PUSH_ALL 1
|
#define TRANSPORT_PUSH_ALL 1
|
||||||
|
Loading…
Reference in New Issue
Block a user