Signed-off-by: Christian Couder <chrisc...@tuxfamily.org>
---
 builtin/clone.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/builtin/clone.c b/builtin/clone.c
index bd690576e6..dda0ad360b 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -55,6 +55,7 @@ static enum transport_family family;
 static struct string_list option_config = STRING_LIST_INIT_NODUP;
 static struct string_list option_required_reference = STRING_LIST_INIT_NODUP;
 static struct string_list option_optional_reference = STRING_LIST_INIT_NODUP;
+static struct string_list option_initial_refspec = STRING_LIST_INIT_NODUP;
 static int option_dissociate;
 static int max_jobs = -1;
 static struct string_list option_recurse_submodules = STRING_LIST_INIT_NODUP;
@@ -105,6 +106,8 @@ static struct option builtin_clone_options[] = {
                        N_("reference repository")),
        OPT_STRING_LIST(0, "reference-if-able", &option_optional_reference,
                        N_("repo"), N_("reference repository")),
+       OPT_STRING_LIST(0, "initial-refspec", &option_initial_refspec,
+                       N_("refspec"), N_("fetch this refspec first")),
        OPT_BOOL(0, "dissociate", &option_dissociate,
                 N_("use --reference only while cloning")),
        OPT_STRING('o', "origin", &option_origin, N_("name"),
@@ -864,6 +867,47 @@ static void dissociate_from_references(void)
        free(alternates);
 }
 
+static struct refspec *parse_initial_refspecs(void)
+{
+       const char **refspecs;
+       struct refspec *initial_refspecs;
+       struct string_list_item *rs;
+       int i = 0;
+
+       if (!option_initial_refspec.nr)
+               return NULL;
+
+       refspecs = xcalloc(option_initial_refspec.nr, sizeof(const char *));
+
+       for_each_string_list_item(rs, &option_initial_refspec)
+               refspecs[i++] = rs->string;
+
+       initial_refspecs = parse_fetch_refspec(option_initial_refspec.nr, 
refspecs);
+
+       free(refspecs);
+
+       return initial_refspecs;
+}
+
+static void fetch_initial_refs(struct transport *transport,
+                              const struct ref *refs,
+                              struct refspec *initial_refspecs,
+                              const char *branch_top,
+                              const char *reflog_msg,
+                              int is_local)
+{
+       int i;
+
+       for (i = 0; i < option_initial_refspec.nr; i++) {
+               struct ref *init_refs = NULL;
+               struct ref **tail = &init_refs;
+               get_fetch_map(refs, &initial_refspecs[i], &tail, 0);
+               transport_fetch_refs(transport, init_refs);
+               update_remote_refs(refs, init_refs, NULL, branch_top, 
reflog_msg,
+                                  transport, !is_local, 1);
+       }
+}
+
 int cmd_clone(int argc, const char **argv, const char *prefix)
 {
        int is_bundle = 0, is_local;
@@ -887,6 +931,9 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
        struct refspec *refspec;
        const char *fetch_pattern;
 
+       struct refspec *initial_refspecs;
+       int is_initial;
+
        packet_trace_identity("clone");
        argc = parse_options(argc, argv, prefix, builtin_clone_options,
                             builtin_clone_usage, 0);
@@ -1054,6 +1101,8 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
        if (option_required_reference.nr || option_optional_reference.nr)
                setup_reference();
 
+       initial_refspecs = parse_initial_refspecs();
+
        fetch_pattern = xstrfmt("+%s*:%s*", src_ref_prefix, branch_top.buf);
        refspec = parse_fetch_refspec(1, &fetch_pattern);
        free((char *)fetch_pattern);
@@ -1109,6 +1158,9 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
        refs = transport_get_remote_refs(transport);
 
        if (refs) {
+               fetch_initial_refs(transport, refs, initial_refspecs,
+                                  branch_top.buf, reflog_msg.buf, is_local);
+
                mapped_refs = wanted_peer_refs(refs, refspec);
                /*
                 * transport_get_remote_refs() may return refs with null sha-1
@@ -1168,9 +1220,10 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
        else if (refs && complete_refs_before_fetch)
                transport_fetch_refs(transport, mapped_refs);
 
+       is_initial = !refs || option_initial_refspec.nr == 0;
        update_remote_refs(refs, mapped_refs, remote_head_points_at,
                           branch_top.buf, reflog_msg.buf, transport,
-                          !is_local, 0);
+                          !is_local, is_initial);
 
        update_head(our_head_points_at, remote_head, reflog_msg.buf);
 
-- 
2.13.1.565.gbfcd7a9048

Reply via email to