Skip to content

Commit aa5af97

Browse files
Ilari Liusvaaragitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 25d5cc4 commit aa5af97

File tree

2 files changed

+62
-31
lines changed

2 files changed

+62
-31
lines changed

transport.c

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -395,41 +395,35 @@ static int close_bundle(struct transport *transport)
395395
}
396396

397397
struct git_transport_data {
398-
unsigned thin : 1;
399-
unsigned keep : 1;
400-
unsigned followtags : 1;
401-
int depth;
398+
struct git_transport_options options;
402399
struct child_process *conn;
403400
int fd[2];
404-
const char *uploadpack;
405-
const char *receivepack;
406401
struct extra_have_objects extra_have;
407402
};
408403

409-
static int set_git_option(struct transport *connection,
404+
static int set_git_option(struct git_transport_options *opts,
410405
const char *name, const char *value)
411406
{
412-
struct git_transport_data *data = connection->data;
413407
if (!strcmp(name, TRANS_OPT_UPLOADPACK)) {
414-
data->uploadpack = value;
408+
opts->uploadpack = value;
415409
return 0;
416410
} else if (!strcmp(name, TRANS_OPT_RECEIVEPACK)) {
417-
data->receivepack = value;
411+
opts->receivepack = value;
418412
return 0;
419413
} else if (!strcmp(name, TRANS_OPT_THIN)) {
420-
data->thin = !!value;
414+
opts->thin = !!value;
421415
return 0;
422416
} else if (!strcmp(name, TRANS_OPT_FOLLOWTAGS)) {
423-
data->followtags = !!value;
417+
opts->followtags = !!value;
424418
return 0;
425419
} else if (!strcmp(name, TRANS_OPT_KEEP)) {
426-
data->keep = !!value;
420+
opts->keep = !!value;
427421
return 0;
428422
} else if (!strcmp(name, TRANS_OPT_DEPTH)) {
429423
if (!value)
430-
data->depth = 0;
424+
opts->depth = 0;
431425
else
432-
data->depth = atoi(value);
426+
opts->depth = atoi(value);
433427
return 0;
434428
}
435429
return 1;
@@ -439,7 +433,8 @@ static int connect_setup(struct transport *transport, int for_push, int verbose)
439433
{
440434
struct git_transport_data *data = transport->data;
441435
data->conn = git_connect(data->fd, transport->url,
442-
for_push ? data->receivepack : data->uploadpack,
436+
for_push ? data->options.receivepack :
437+
data->options.uploadpack,
443438
verbose ? CONNECT_VERBOSE : 0);
444439
return 0;
445440
}
@@ -469,15 +464,15 @@ static int fetch_refs_via_pack(struct transport *transport,
469464
struct ref *refs_tmp = NULL;
470465

471466
memset(&args, 0, sizeof(args));
472-
args.uploadpack = data->uploadpack;
473-
args.keep_pack = data->keep;
467+
args.uploadpack = data->options.uploadpack;
468+
args.keep_pack = data->options.keep;
474469
args.lock_pack = 1;
475-
args.use_thin_pack = data->thin;
476-
args.include_tag = data->followtags;
470+
args.use_thin_pack = data->options.thin;
471+
args.include_tag = data->options.followtags;
477472
args.verbose = (transport->verbose > 0);
478473
args.quiet = (transport->verbose < 0);
479474
args.no_progress = args.quiet || (!transport->progress && !isatty(1));
480-
args.depth = data->depth;
475+
args.depth = data->options.depth;
481476

482477
for (i = 0; i < nr_heads; i++)
483478
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
734729
memset(&args, 0, sizeof(args));
735730
args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR);
736731
args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
737-
args.use_thin_pack = data->thin;
732+
args.use_thin_pack = data->options.thin;
738733
args.verbose = !!(flags & TRANSPORT_PUSH_VERBOSE);
739734
args.quiet = !!(flags & TRANSPORT_PUSH_QUIET);
740735
args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
@@ -847,12 +842,14 @@ struct transport *transport_get(struct remote *remote, const char *url)
847842
ret->get_refs_list = get_refs_via_rsync;
848843
ret->fetch = fetch_objs_via_rsync;
849844
ret->push = rsync_transport_push;
845+
ret->smart_options = NULL;
850846
} else if (is_local(url) && is_file(url)) {
851847
struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
852848
ret->data = data;
853849
ret->get_refs_list = get_refs_from_bundle;
854850
ret->fetch = fetch_refs_from_bundle;
855851
ret->disconnect = close_bundle;
852+
ret->smart_options = NULL;
856853
} else if (!is_url(url)
857854
|| !prefixcmp(url, "file://")
858855
|| !prefixcmp(url, "git://")
@@ -862,20 +859,14 @@ struct transport *transport_get(struct remote *remote, const char *url)
862859
/* These are builtin smart transports. */
863860
struct git_transport_data *data = xcalloc(1, sizeof(*data));
864861
ret->data = data;
865-
ret->set_option = set_git_option;
862+
ret->set_option = NULL;
866863
ret->get_refs_list = get_refs_via_connect;
867864
ret->fetch = fetch_refs_via_pack;
868865
ret->push_refs = git_transport_push;
869866
ret->disconnect = disconnect_git;
867+
ret->smart_options = &(data->options);
870868

871-
data->thin = 1;
872869
data->conn = NULL;
873-
data->uploadpack = "git-upload-pack";
874-
if (remote->uploadpack)
875-
data->uploadpack = remote->uploadpack;
876-
data->receivepack = "git-receive-pack";
877-
if (remote->receivepack)
878-
data->receivepack = remote->receivepack;
879870
} else if (!prefixcmp(url, "http://")
880871
|| !prefixcmp(url, "https://")
881872
|| !prefixcmp(url, "ftp://")) {
@@ -893,14 +884,39 @@ struct transport *transport_get(struct remote *remote, const char *url)
893884
transport_helper_init(ret, handler);
894885
}
895886

887+
if (ret->smart_options) {
888+
ret->smart_options->thin = 1;
889+
ret->smart_options->uploadpack = "git-upload-pack";
890+
if (remote->uploadpack)
891+
ret->smart_options->uploadpack = remote->uploadpack;
892+
ret->smart_options->receivepack = "git-receive-pack";
893+
if (remote->receivepack)
894+
ret->smart_options->receivepack = remote->receivepack;
895+
}
896+
896897
return ret;
897898
}
898899

899900
int transport_set_option(struct transport *transport,
900901
const char *name, const char *value)
901902
{
903+
int git_reports = 1, protocol_reports = 1;
904+
905+
if (transport->smart_options)
906+
git_reports = set_git_option(transport->smart_options,
907+
name, value);
908+
902909
if (transport->set_option)
903-
return transport->set_option(transport, name, value);
910+
protocol_reports = transport->set_option(transport, name,
911+
value);
912+
913+
/* If either report is 0, report 0 (success). */
914+
if (!git_reports || !protocol_reports)
915+
return 0;
916+
/* If either reports -1 (invalid value), report -1. */
917+
if ((git_reports == -1) || (protocol_reports == -1))
918+
return -1;
919+
/* Otherwise if both report unknown, report unknown. */
904920
return 1;
905921
}
906922

transport.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
#include "cache.h"
55
#include "remote.h"
66

7+
struct git_transport_options {
8+
unsigned thin : 1;
9+
unsigned keep : 1;
10+
unsigned followtags : 1;
11+
int depth;
12+
const char *uploadpack;
13+
const char *receivepack;
14+
};
15+
716
struct transport {
817
struct remote *remote;
918
const char *url;
@@ -65,6 +74,12 @@ struct transport {
6574
signed verbose : 3;
6675
/* Force progress even if the output is not a tty */
6776
unsigned progress : 1;
77+
/*
78+
* If transport is at least potentially smart, this points to
79+
* git_transport_options structure to use in case transport
80+
* actually turns out to be smart.
81+
*/
82+
struct git_transport_options *smart_options;
6883
};
6984

7085
#define TRANSPORT_PUSH_ALL 1

0 commit comments

Comments
 (0)