by default when it is attached to a terminal, unless -q
is specified. This flag forces progress status even if the
standard error stream is not directed to a terminal.
+
+-4::
+--ipv4::
+ Use IPv4 addresses only, ignoring IPv6 addresses.
+
+-6::
+--ipv6::
+ Use IPv6 addresses only, ignoring IPv4 addresses.
default is --verify, giving the hook a chance to prevent the
push. With --no-verify, the hook is bypassed completely.
+-4::
+--ipv4::
+ Use IPv4 addresses only, ignoring IPv6 addresses.
+
+-6::
+--ipv6::
+ Use IPv6 addresses only, ignoring IPv4 addresses.
include::urls-remotes.txt[]
static char *option_upload_pack = "git-upload-pack";
static int option_verbosity;
static int option_progress = -1;
+static enum transport_family family;
static struct string_list option_config;
static struct string_list option_reference;
static int option_dissociate;
N_("separate git dir from working tree")),
OPT_STRING_LIST('c', "config", &option_config, N_("key=value"),
N_("set config inside the new repository")),
+ OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
+ TRANSPORT_FAMILY_IPV4),
+ OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
+ TRANSPORT_FAMILY_IPV6),
OPT_END()
};
remote = remote_get(option_origin);
transport = transport_get(remote, remote->url[0]);
transport_set_verbosity(transport, option_verbosity, option_progress);
+ transport->family = family;
path = get_repo_path(remote->url[0], &is_bundle);
is_local = option_local != 0 && path && !is_bundle;
static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity;
static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
static int tags = TAGS_DEFAULT, unshallow, update_shallow;
+static enum transport_family family;
static const char *depth;
static const char *upload_pack;
static struct strbuf default_rla = STRBUF_INIT;
N_("accept refs that update .git/shallow")),
{ OPTION_CALLBACK, 0, "refmap", NULL, N_("refmap"),
N_("specify fetch refmap"), PARSE_OPT_NONEG, parse_refmap_arg },
+ OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
+ TRANSPORT_FAMILY_IPV4),
+ OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
+ TRANSPORT_FAMILY_IPV6),
OPT_END()
};
struct transport *transport;
transport = transport_get(remote, NULL);
transport_set_verbosity(transport, verbosity, progress);
+ transport->family = family;
if (upload_pack)
set_option(transport, TRANS_OPT_UPLOADPACK, upload_pack);
if (keep)
static int verbosity;
static int progress = -1;
static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
+static enum transport_family family;
static struct push_cas_option cas;
unsigned int reject_reasons;
transport_set_verbosity(transport, verbosity, progress);
+ transport->family = family;
if (receivepack)
transport_set_option(transport,
0, "signed", &push_cert, "yes|no|if-asked", N_("GPG sign the push"),
PARSE_OPT_OPTARG, option_parse_push_signed },
OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC),
+ OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
+ TRANSPORT_FAMILY_IPV4),
+ OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
+ TRANSPORT_FAMILY_IPV6),
OPT_END()
};
port = "<none>";
memset(&hints, 0, sizeof(hints));
+ if (flags & CONNECT_IPV4)
+ hints.ai_family = AF_INET;
+ else if (flags & CONNECT_IPV6)
+ hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
}
argv_array_push(&conn->args, ssh);
+ if (flags & CONNECT_IPV4)
+ argv_array_push(&conn->args, "-4");
+ else if (flags & CONNECT_IPV6)
+ argv_array_push(&conn->args, "-6");
if (tortoiseplink)
argv_array_push(&conn->args, "-batch");
if (port) {
#define CONNECT_VERBOSE (1u << 0)
#define CONNECT_DIAG_URL (1u << 1)
+#define CONNECT_IPV4 (1u << 2)
+#define CONNECT_IPV6 (1u << 3)
extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags);
extern int finish_connect(struct child_process *conn);
extern int git_connection_is_socket(struct child_process *conn);
#include "gettext.h"
#include "transport.h"
+#if LIBCURL_VERSION_NUM >= 0x070a08
+long int git_curl_ipresolve = CURL_IPRESOLVE_WHATEVER;
+#else
+long int git_curl_ipresolve;
+#endif
int active_requests;
int http_is_verbose;
size_t http_post_buffer = 16 * LARGE_PACKET_MAX;
curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(slot->curl, CURLOPT_RANGE, NULL);
+
+#if LIBCURL_VERSION_NUM >= 0x070a08
+ curl_easy_setopt(slot->curl, CURLOPT_IPRESOLVE, git_curl_ipresolve);
+#endif
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods);
#endif
int proactive_auth);
extern void http_cleanup(void);
+extern long int git_curl_ipresolve;
extern int active_requests;
extern int http_is_verbose;
extern size_t http_post_buffer;
else
return -1;
return 0;
+
+#if LIBCURL_VERSION_NUM >= 0x070a08
+ } else if (!strcmp(name, "family")) {
+ if (!strcmp(value, "ipv4"))
+ git_curl_ipresolve = CURL_IPRESOLVE_V4;
+ else if (!strcmp(value, "ipv6"))
+ git_curl_ipresolve = CURL_IPRESOLVE_V6;
+ else if (!strcmp(value, "all"))
+ git_curl_ipresolve = CURL_IPRESOLVE_WHATEVER;
+ else
+ return -1;
+ return 0;
+#endif /* LIBCURL_VERSION_NUM >= 0x070a08 */
} else {
return 1 /* unsupported */;
}
if (n >= sizeof(buf))
die("impossibly large verbosity value");
set_helper_option(t, "verbosity", buf);
+
+ switch (t->family) {
+ case TRANSPORT_FAMILY_ALL:
+ /*
+ * this is already the default,
+ * do not break old remote helpers by setting "all" here
+ */
+ break;
+ case TRANSPORT_FAMILY_IPV4:
+ set_helper_option(t, "family", "ipv4");
+ break;
+ case TRANSPORT_FAMILY_IPV6:
+ set_helper_option(t, "family", "ipv6");
+ break;
+ }
}
static int release_helper(struct transport *transport)
if (data->conn)
return 0;
+ switch (transport->family) {
+ case TRANSPORT_FAMILY_ALL: break;
+ case TRANSPORT_FAMILY_IPV4: flags |= CONNECT_IPV4; break;
+ case TRANSPORT_FAMILY_IPV6: flags |= CONNECT_IPV6; break;
+ }
+
data->conn = git_connect(data->fd, transport->url,
for_push ? data->options.receivepack :
data->options.uploadpack,
struct push_cas_option *cas;
};
+enum transport_family {
+ TRANSPORT_FAMILY_ALL = 0,
+ TRANSPORT_FAMILY_IPV4,
+ TRANSPORT_FAMILY_IPV6
+};
+
struct transport {
struct remote *remote;
const char *url;
* actually turns out to be smart.
*/
struct git_transport_options *smart_options;
+
+ enum transport_family family;
};
#define TRANSPORT_PUSH_ALL 1