]> git.ipfire.org Git - thirdparty/git.git/blobdiff - builtin/clone.c
Merge branch 'jk/clone-allow-bare-and-o-together' into maint-2.38
[thirdparty/git.git] / builtin / clone.c
index f5f902cce194ee01b889a1cb57fd03fd19ebebf1..547d6464b3c04b83cb1376d325eeefb79aca079c 100644 (file)
@@ -34,6 +34,7 @@
 #include "list-objects-filter-options.h"
 #include "hook.h"
 #include "bundle.h"
+#include "bundle-uri.h"
 
 /*
  * Overall FIXMEs:
@@ -72,11 +73,12 @@ static struct string_list option_optional_reference = STRING_LIST_INIT_NODUP;
 static int option_dissociate;
 static int max_jobs = -1;
 static struct string_list option_recurse_submodules = STRING_LIST_INIT_NODUP;
-static struct list_objects_filter_options filter_options;
+static struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT;
 static int option_filter_submodules = -1;    /* unspecified */
 static int config_filter_submodules = -1;    /* unspecified */
 static struct string_list server_options = STRING_LIST_INIT_NODUP;
 static int option_remote_submodules;
+static const char *bundle_uri;
 
 static int recurse_submodules_cb(const struct option *opt,
                                 const char *arg, int unset)
@@ -160,6 +162,8 @@ static struct option builtin_clone_options[] = {
                    N_("any cloned submodules will use their remote-tracking branch")),
        OPT_BOOL(0, "sparse", &option_sparse_checkout,
                    N_("initialize sparse-checkout file to include only files at root")),
+       OPT_STRING(0, "bundle-uri", &bundle_uri,
+                  N_("uri"), N_("a URI for downloading bundles before fetching from origin remote")),
        OPT_END()
 };
 
@@ -316,13 +320,11 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
        int src_len, dest_len;
        struct dir_iterator *iter;
        int iter_status;
-       unsigned int flags;
        struct strbuf realpath = STRBUF_INIT;
 
        mkdir_if_missing(dest->buf, 0777);
 
-       flags = DIR_ITERATOR_PEDANTIC | DIR_ITERATOR_FOLLOW_SYMLINKS;
-       iter = dir_iterator_begin(src->buf, flags);
+       iter = dir_iterator_begin(src->buf, DIR_ITERATOR_PEDANTIC);
 
        if (!iter)
                die_errno(_("failed to start iterator over '%s'"), src->buf);
@@ -338,6 +340,10 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
                strbuf_setlen(dest, dest_len);
                strbuf_addstr(dest, iter->relative_path);
 
+               if (S_ISLNK(iter->st.st_mode))
+                       die(_("symlink '%s' exists, refusing to clone with --local"),
+                           iter->relative_path);
+
                if (S_ISDIR(iter->st.st_mode)) {
                        mkdir_if_missing(dest->buf, 0777);
                        continue;
@@ -494,6 +500,7 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
                        /* if --branch=tag, pull the requested tag explicitly */
                        get_fetch_map(remote_head, tag_refspec, &tail, 0);
                }
+               free_refs(remote_head);
        } else {
                int i;
                for (i = 0; i < refspec->nr; i++)
@@ -929,6 +936,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                option_no_checkout = 1;
        }
 
+       if (bundle_uri && deepen)
+               die(_("--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-exclude"));
+
        repo_name = argv[0];
 
        path = get_repo_path(repo_name, &is_bundle);
@@ -1228,6 +1238,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        if (transport->smart_options && !deepen && !filter_options.choice)
                transport->smart_options->check_self_contained_and_connected = 1;
 
+       /*
+        * Before fetching from the remote, download and install bundle
+        * data from the --bundle-uri option.
+        */
+       if (bundle_uri) {
+               /* At this point, we need the_repository to match the cloned repo. */
+               if (repo_init(the_repository, git_dir, work_tree))
+                       warning(_("failed to initialize the repo, skipping bundle URI"));
+               else if (fetch_bundle_uri(the_repository, bundle_uri))
+                       warning(_("failed to fetch objects from bundle URI '%s'"),
+                               bundle_uri);
+       }
 
        strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD");
        refspec_ref_prefixes(&remote->fetch,