summaryrefslogtreecommitdiff
path: root/builtin/clone.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/clone.c')
-rw-r--r--builtin/clone.c67
1 files changed, 57 insertions, 10 deletions
diff --git a/builtin/clone.c b/builtin/clone.c
index b4c929b..afab299 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -39,7 +39,8 @@ 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_local = -1, option_no_hardlinks, option_shared;
+static int option_no_tags;
static int option_shallow_submodules;
static int deepen;
static char *option_template, *option_depth, *option_since;
@@ -56,6 +57,21 @@ static struct string_list option_required_reference = STRING_LIST_INIT_NODUP;
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 int recurse_submodules_cb(const struct option *opt,
+ const char *arg, int unset)
+{
+ if (unset)
+ string_list_clear((struct string_list *)opt->value, 0);
+ else if (arg)
+ string_list_append((struct string_list *)opt->value, arg);
+ else
+ string_list_append((struct string_list *)opt->value,
+ (const char *)opt->defval);
+
+ return 0;
+}
static struct option builtin_clone_options[] = {
OPT__VERBOSITY(&option_verbosity),
@@ -74,10 +90,13 @@ 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_BOOL(0, "recursive", &option_recursive,
- N_("initialize submodules in the clone")),
- OPT_BOOL(0, "recurse-submodules", &option_recursive,
- N_("initialize submodules in the clone")),
+ { OPTION_CALLBACK, 0, "recursive", &option_recurse_submodules,
+ N_("pathspec"), N_("initialize submodules in the clone"),
+ PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN, recurse_submodules_cb,
+ (intptr_t)"." },
+ { 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_INTEGER('j', "jobs", &max_jobs,
N_("number of submodules cloned in parallel")),
OPT_STRING(0, "template", &option_template, N_("template-directory"),
@@ -102,6 +121,8 @@ static struct option builtin_clone_options[] = {
N_("deepen history of shallow clone, excluding rev")),
OPT_BOOL(0, "single-branch", &option_single_branch,
N_("clone only one branch, HEAD or --branch")),
+ OPT_BOOL(0, "no-tags", &option_no_tags,
+ N_("don't clone any tags, and make later fetches not to follow them")),
OPT_BOOL(0, "shallow-submodules", &option_shallow_submodules,
N_("any cloned submodules will be shallow")),
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
@@ -545,7 +566,7 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
} else
get_fetch_map(refs, refspec, &tail, 0);
- if (!option_mirror && !option_single_branch)
+ if (!option_mirror && !option_single_branch && !option_no_tags)
get_fetch_map(refs, tag_refspec, &tail, 0);
return local_refs;
@@ -634,7 +655,7 @@ static void update_remote_refs(const struct ref *refs,
if (refs) {
write_remote_refs(mapped_refs);
- if (option_single_branch)
+ if (option_single_branch && !option_no_tags)
write_followtags(refs, msg);
}
@@ -733,7 +754,7 @@ static int checkout(int submodule_progress)
err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1),
oid_to_hex(&oid), "1", NULL);
- if (!err && option_recursive) {
+ if (!err && (option_recurse_submodules.nr > 0)) {
struct argv_array args = ARGV_ARRAY_INIT;
argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL);
@@ -755,7 +776,9 @@ static int checkout(int submodule_progress)
static int write_one_config(const char *key, const char *value, void *data)
{
- return git_config_set_multivar_gently(key, value ? value : "true", "^$", 0);
+ return git_config_set_multivar_gently(key,
+ value ? value : "true",
+ CONFIG_REGEX_NONE, 0);
}
static void write_config(struct string_list *config)
@@ -957,7 +980,25 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
fprintf(stderr, _("Cloning into '%s'...\n"), dir);
}
- if (option_recursive) {
+ if (option_recurse_submodules.nr > 0) {
+ struct string_list_item *item;
+ struct strbuf sb = STRBUF_INIT;
+
+ /* remove duplicates */
+ string_list_sort(&option_recurse_submodules);
+ string_list_remove_duplicates(&option_recurse_submodules, 0);
+
+ /*
+ * NEEDSWORK: In a multi-working-tree world, this needs to be
+ * set in the per-worktree config.
+ */
+ for_each_string_list_item(item, &option_recurse_submodules) {
+ strbuf_addf(&sb, "submodule.active=%s",
+ item->string);
+ string_list_append(&option_config,
+ strbuf_detach(&sb, NULL));
+ }
+
if (option_required_reference.nr &&
option_optional_reference.nr)
die(_("clone --recursive is not compatible with "
@@ -999,6 +1040,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
git_config_set(key.buf, repo);
strbuf_reset(&key);
+ if (option_no_tags) {
+ strbuf_addf(&key, "remote.%s.tagOpt", option_origin);
+ git_config_set(key.buf, "--no-tags");
+ strbuf_reset(&key);
+ }
+
if (option_required_reference.nr || option_optional_reference.nr)
setup_reference();