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>
Ilari Liusvaara committed
Dec 9, 2009 at 17:26 UTC
aa5af9749f53f7e44bef36c5c40918295430fb03
2 files changed
+62
-31
transport.c
+47
-31
@@ -395,41 +395,35 @@ static int close_bundle(struct transport *transport)
395
}
396
397
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;
399
struct child_process *conn;
400
int fd[2];
404
- const char *uploadpack;
405
- const char *receivepack;
401
struct extra_have_objects extra_have;
402
};
403
409
-static int set_git_option(struct transport *connection,
404
+static int set_git_option(struct git_transport_options *opts,
405
const char *name, const char *value)
406
{
412
- struct git_transport_data *data = connection->data;
407
if (!strcmp(name, TRANS_OPT_UPLOADPACK)) {
414
- data->uploadpack = value;
408
+ opts->uploadpack = value;
409
return 0;
410
} else if (!strcmp(name, TRANS_OPT_RECEIVEPACK)) {
417
- data->receivepack = value;
411
+ opts->receivepack = value;
412
return 0;
413
} else if (!strcmp(name, TRANS_OPT_THIN)) {
420
- data->thin = !!value;
414
+ opts->thin = !!value;
415
return 0;
416
} else if (!strcmp(name, TRANS_OPT_FOLLOWTAGS)) {
423
- data->followtags = !!value;
417
+ opts->followtags = !!value;
418
return 0;
419
} else if (!strcmp(name, TRANS_OPT_KEEP)) {
426
- data->keep = !!value;
420
+ opts->keep = !!value;
421
return 0;
422
} else if (!strcmp(name, TRANS_OPT_DEPTH)) {
423
if (!value)
430
- data->depth = 0;
424
+ opts->depth = 0;
425
else
432
- data->depth = atoi(value);
426
+ opts->depth = atoi(value);
427
return 0;
428
}
429
return 1;
@@ -439,7 +433,8 @@ static int connect_setup(struct transport *transport, int for_push, int verbose)
433
{
434
struct git_transport_data *data = transport->data;
435
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,
438
verbose ? CONNECT_VERBOSE : 0);
439
return 0;
440
}
@@ -469,15 +464,15 @@ static int fetch_refs_via_pack(struct transport *transport,
464
struct ref *refs_tmp = NULL;
465
466
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;
469
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;
472
args.verbose = (transport->verbose > 0);
473
args.quiet = (transport->verbose < 0);
474
args.no_progress = args.quiet || (!transport->progress && !isatty(1));
480
- args.depth = data->depth;
475
+ args.depth = data->options.depth;
476
477
for (i = 0; i < nr_heads; i++)
478
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
729
memset(&args, 0, sizeof(args));
730
args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR);
731
args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
737
- args.use_thin_pack = data->thin;
732
+ args.use_thin_pack = data->options.thin;
733
args.verbose = !!(flags & TRANSPORT_PUSH_VERBOSE);
734
args.quiet = !!(flags & TRANSPORT_PUSH_QUIET);
735
args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
@@ -847,12 +842,14 @@ struct transport *transport_get(struct remote *remote, const char *url)
842
ret->get_refs_list = get_refs_via_rsync;
843
ret->fetch = fetch_objs_via_rsync;
844
ret->push = rsync_transport_push;
845
+ ret->smart_options = NULL;
846
} else if (is_local(url) && is_file(url)) {
847
struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
848
ret->data = data;
849
ret->get_refs_list = get_refs_from_bundle;
850
ret->fetch = fetch_refs_from_bundle;
851
ret->disconnect = close_bundle;
852
+ ret->smart_options = NULL;
853
} else if (!is_url(url)
854
|| !prefixcmp(url, "file://")
855
|| !prefixcmp(url, "git://")
@@ -862,20 +859,14 @@ struct transport *transport_get(struct remote *remote, const char *url)
859
/* These are builtin smart transports. */
860
struct git_transport_data *data = xcalloc(1, sizeof(*data));
861
ret->data = data;
865
- ret->set_option = set_git_option;
862
+ ret->set_option = NULL;
863
ret->get_refs_list = get_refs_via_connect;
864
ret->fetch = fetch_refs_via_pack;
865
ret->push_refs = git_transport_push;
866
ret->disconnect = disconnect_git;
867
+ ret->smart_options = &(data->options);
868
871
- data->thin = 1;
869
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;
870
} else if (!prefixcmp(url, "http://")
871
|| !prefixcmp(url, "https://")
872
|| !prefixcmp(url, "ftp://")) {
@@ -893,14 +884,39 @@ struct transport *transport_get(struct remote *remote, const char *url)
884
transport_helper_init(ret, handler);
885
}
886
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
+
897
return ret;
898
}
899
900
int transport_set_option(struct transport *transport,
901
const char *name, const char *value)
902
{
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
+
909
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. */
920
return 1;
921
}
922
transport.h
+15
@@ -4,6 +4,15 @@
4
#include "cache.h"
5
#include "remote.h"
6
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
+
16
struct transport {
17
struct remote *remote;
18
const char *url;
@@ -65,6 +74,12 @@ struct transport {
74
signed verbose : 3;
75
/* Force progress even if the output is not a tty */
76
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;
83
};
84
85
#define TRANSPORT_PUSH_ALL 1