Signed-off-by: Christian Couder <[email protected]>
---
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