Merge branch 'sb/submodule-clone-retry'
[gitweb.git] / builtin / clone.c
index ecdf3080a50103adba0dd1dfcff48bb6efe9f32b..f044a8c27f542c94c0b7f2458de1590e0d02fae2 100644 (file)
@@ -40,7 +40,7 @@ static const char * const builtin_clone_usage[] = {
 
 static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1;
 static int option_local = -1, option_no_hardlinks, option_shared, option_recursive;
-static int option_shallow_submodules = -1;
+static int option_shallow_submodules;
 static char *option_template, *option_depth;
 static char *option_origin = NULL;
 static char *option_branch = NULL;
@@ -48,8 +48,9 @@ static const char *real_git_dir;
 static char *option_upload_pack = "git-upload-pack";
 static int option_verbosity;
 static int option_progress = -1;
-static struct string_list option_config;
-static struct string_list option_reference;
+static enum transport_family family;
+static struct string_list option_config = STRING_LIST_INIT_NODUP;
+static struct string_list option_reference = STRING_LIST_INIT_NODUP;
 static int option_dissociate;
 static int max_jobs = -1;
 
@@ -98,6 +99,10 @@ static struct option builtin_clone_options[] = {
                   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()
 };
 
@@ -233,8 +238,8 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
        strip_suffix_mem(start, &len, is_bundle ? ".bundle" : ".git");
 
        if (!len || (len == 1 && *start == '/'))
-           die("No directory name could be guessed.\n"
-               "Please specify a directory on the command line");
+               die(_("No directory name could be guessed.\n"
+                     "Please specify a directory on the command line"));
 
        if (is_bare)
                dir = xstrfmt("%.*s.git", (int)len, start);
@@ -341,7 +346,7 @@ static void copy_alternates(struct strbuf *src, struct strbuf *dst,
        FILE *in = fopen(src->buf, "r");
        struct strbuf line = STRBUF_INIT;
 
-       while (strbuf_getline(&line, in, '\n') != EOF) {
+       while (strbuf_getline(&line, in) != EOF) {
                char *abs_path;
                if (!line.len || line.buf[0] == '#')
                        continue;
@@ -619,13 +624,13 @@ static void update_remote_refs(const struct ref *refs,
        const struct ref *rm = mapped_refs;
 
        if (check_connectivity) {
-               if (transport->progress)
-                       fprintf(stderr, _("Checking connectivity... "));
-               if (check_everything_connected_with_transport(iterate_ref_map,
-                                                             0, &rm, transport))
+               struct check_connected_options opt = CHECK_CONNECTED_INIT;
+
+               opt.transport = transport;
+               opt.progress = transport->progress;
+
+               if (check_connected(iterate_ref_map, &rm, &opt))
                        die(_("remote did not send all necessary objects"));
-               if (transport->progress)
-                       fprintf(stderr, _("done.\n"));
        }
 
        if (refs) {
@@ -638,9 +643,11 @@ static void update_remote_refs(const struct ref *refs,
                struct strbuf head_ref = STRBUF_INIT;
                strbuf_addstr(&head_ref, branch_top);
                strbuf_addstr(&head_ref, "HEAD");
-               create_symref(head_ref.buf,
-                             remote_head_points_at->peer_ref->name,
-                             msg);
+               if (create_symref(head_ref.buf,
+                                 remote_head_points_at->peer_ref->name,
+                                 msg) < 0)
+                       die(_("unable to update %s"), head_ref.buf);
+               strbuf_release(&head_ref);
        }
 }
 
@@ -650,7 +657,8 @@ static void update_head(const struct ref *our, const struct ref *remote,
        const char *head;
        if (our && skip_prefix(our->name, "refs/heads/", &head)) {
                /* Local default branch link */
-               create_symref("HEAD", our->name, NULL);
+               if (create_symref("HEAD", our->name, NULL) < 0)
+                       die(_("unable to update HEAD"));
                if (!option_bare) {
                        update_ref(msg, "HEAD", our->old_oid.hash, NULL, 0,
                                   UPDATE_REFS_DIE_ON_ERR);
@@ -730,8 +738,7 @@ static int checkout(void)
                struct argv_array args = ARGV_ARRAY_INIT;
                argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL);
 
-               if (option_shallow_submodules == 1
-                   || (option_shallow_submodules == -1 && option_depth))
+               if (option_shallow_submodules == 1)
                        argv_array_push(&args, "--depth=1");
 
                if (max_jobs != -1)
@@ -746,7 +753,7 @@ static int checkout(void)
 
 static int write_one_config(const char *key, const char *value, void *data)
 {
-       return git_config_set_multivar(key, value ? value : "true", "^$", 0);
+       return git_config_set_multivar_gently(key, value ? value : "true", "^$", 0);
 }
 
 static void write_config(struct string_list *config)
@@ -756,7 +763,7 @@ static void write_config(struct string_list *config)
        for (i = 0; i < config->nr; i++) {
                if (git_config_parse_parameter(config->items[i].string,
                                               write_one_config, NULL) < 0)
-                       die("unable to write parameters to config file");
+                       die(_("unable to write parameters to config file"));
        }
 }
 
@@ -981,6 +988,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        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;