Imported Upstream version 2.28.0
[platform/upstream/git.git] / builtin / clone.c
index 1ad26f4..bef7074 100644 (file)
@@ -102,10 +102,10 @@ static struct option builtin_clone_options[] = {
                    N_("don't use local hardlinks, always copy")),
        OPT_BOOL('s', "shared", &option_shared,
                    N_("setup as shared repository")),
-       OPT_ALIAS(0, "recursive", "recurse-submodules"),
        { OPTION_CALLBACK, 0, "recurse-submodules", &option_recurse_submodules,
          N_("pathspec"), N_("initialize submodules in the clone"),
          PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)"." },
+       OPT_ALIAS(0, "recursive", "recurse-submodules"),
        OPT_INTEGER('j', "jobs", &max_jobs,
                    N_("number of submodules cloned in parallel")),
        OPT_STRING(0, "template", &option_template, N_("template-directory"),
@@ -420,6 +420,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
        struct dir_iterator *iter;
        int iter_status;
        unsigned int flags;
+       struct strbuf realpath = STRBUF_INIT;
 
        mkdir_if_missing(dest->buf, 0777);
 
@@ -454,7 +455,8 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
                if (unlink(dest->buf) && errno != ENOENT)
                        die_errno(_("failed to unlink '%s'"), dest->buf);
                if (!option_no_hardlinks) {
-                       if (!link(real_path(src->buf), dest->buf))
+                       strbuf_realpath(&realpath, src->buf, 1);
+                       if (!link(realpath.buf, dest->buf))
                                continue;
                        if (option_local > 0)
                                die_errno(_("failed to create link '%s'"), dest->buf);
@@ -468,6 +470,8 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
                strbuf_setlen(src, src_len);
                die(_("failed to iterate over '%s'"), src->buf);
        }
+
+       strbuf_release(&realpath);
 }
 
 static void clone_local(const char *src_repo, const char *dest_repo)
@@ -639,7 +643,9 @@ static void write_followtags(const struct ref *refs, const char *msg)
                        continue;
                if (ends_with(ref->name, "^{}"))
                        continue;
-               if (!has_object_file(&ref->old_oid))
+               if (!has_object_file_with_flags(&ref->old_oid,
+                                               OBJECT_INFO_QUICK |
+                                               OBJECT_INFO_SKIP_FETCH_OBJECT))
                        continue;
                update_ref(msg, ref->name, &ref->old_oid, NULL, 0,
                           UPDATE_REFS_DIE_ON_ERR);
@@ -672,8 +678,7 @@ static void update_remote_refs(const struct ref *refs,
                               const char *branch_top,
                               const char *msg,
                               struct transport *transport,
-                              int check_connectivity,
-                              int check_refs_are_promisor_objects_only)
+                              int check_connectivity)
 {
        const struct ref *rm = mapped_refs;
 
@@ -682,8 +687,6 @@ static void update_remote_refs(const struct ref *refs,
 
                opt.transport = transport;
                opt.progress = transport->progress;
-               opt.check_refs_are_promisor_objects_only =
-                       !!check_refs_are_promisor_objects_only;
 
                if (check_connected(iterate_ref_map, &rm, &opt))
                        die(_("remote did not send all necessary objects"));
@@ -780,11 +783,11 @@ static int checkout(int submodule_progress)
        if (!strcmp(head, "HEAD")) {
                if (advice_detached_head)
                        detach_advice(oid_to_hex(&oid));
+               FREE_AND_NULL(head);
        } else {
                if (!starts_with(head, "refs/heads/"))
                        die(_("HEAD not found below refs/heads!"));
        }
-       free(head);
 
        /* We need to be in the new work tree for the checkout */
        setup_work_tree();
@@ -799,6 +802,7 @@ static int checkout(int submodule_progress)
        opts.verbose_update = (option_verbosity >= 0);
        opts.src_index = &the_index;
        opts.dst_index = &the_index;
+       init_checkout_metadata(&opts.meta, head, &oid, NULL);
 
        tree = parse_tree_indirect(&oid);
        parse_tree(tree);
@@ -806,6 +810,8 @@ static int checkout(int submodule_progress)
        if (unpack_trees(1, &t, &opts) < 0)
                die(_("unable to checkout working tree"));
 
+       free(head);
+
        if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
                die(_("unable to write new index file"));
 
@@ -939,7 +945,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 {
        int is_bundle = 0, is_local;
        const char *repo_name, *repo, *work_tree, *git_dir;
-       char *path, *dir;
+       char *path, *dir, *display_repo = NULL;
        int dest_exists;
        const struct ref *refs, *remote_head;
        const struct ref *remote_head_points_at;
@@ -994,10 +1000,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        path = get_repo_path(repo_name, &is_bundle);
        if (path)
                repo = absolute_pathdup(repo_name);
-       else if (!strchr(repo_name, ':'))
-               die(_("repository '%s' does not exist"), repo_name);
-       else
+       else if (strchr(repo_name, ':')) {
                repo = repo_name;
+               display_repo = transport_anonymize_url(repo);
+       } else
+               die(_("repository '%s' does not exist"), repo_name);
 
        /* no need to be strict, transport_set_option() will validate it again */
        if (option_depth && atoi(option_depth) < 1)
@@ -1014,7 +1021,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                die(_("destination path '%s' already exists and is not "
                        "an empty directory."), dir);
 
-       strbuf_addf(&reflog_msg, "clone: from %s", repo);
+       strbuf_addf(&reflog_msg, "clone: from %s",
+                   display_repo ? display_repo : repo);
+       free(display_repo);
 
        if (option_bare)
                work_tree = NULL;
@@ -1102,7 +1111,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                }
        }
 
-       init_db(git_dir, real_git_dir, option_template, INIT_DB_QUIET);
+       init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
+               INIT_DB_QUIET);
 
        if (real_git_dir)
                git_dir = real_git_dir;
@@ -1211,6 +1221,15 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        refs = transport_get_remote_refs(transport, &ref_prefixes);
 
        if (refs) {
+               int hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));
+
+               /*
+                * Now that we know what algorithm the remote side is using,
+                * let's set ours to the same thing.
+                */
+               initialize_repository_version(hash_algo);
+               repo_set_hash_algo(the_repository, hash_algo);
+
                mapped_refs = wanted_peer_refs(refs, &remote->fetch);
                /*
                 * transport_get_remote_refs() may return refs with null sha-1
@@ -1257,9 +1276,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                remote_head_points_at = NULL;
                remote_head = NULL;
                option_no_checkout = 1;
-               if (!option_bare)
-                       install_branch_config(0, "master", option_origin,
-                                             "refs/heads/master");
+               if (!option_bare) {
+                       const char *branch = git_default_branch_name();
+                       char *ref = xstrfmt("refs/heads/%s", branch);
+
+                       install_branch_config(0, branch, option_origin, ref);
+                       free(ref);
+               }
        }
 
        write_refspec_config(src_ref_prefix, our_head_points_at,
@@ -1275,7 +1298,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
        update_remote_refs(refs, mapped_refs, remote_head_points_at,
                           branch_top.buf, reflog_msg.buf, transport,
-                          !is_local, filter_options.choice);
+                          !is_local);
 
        update_head(our_head_points_at, remote_head, reflog_msg.buf);