ref-filter: abstract ref format into its own struct
[gitweb.git] / builtin / clone.c
index a6ae7d6180ebee6e199b40b4e0c720d4049b68e9..08b5cc433c6fcad5eea2dfc3321aea28a599d51f 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "builtin.h"
+#include "config.h"
 #include "lockfile.h"
 #include "parse-options.h"
 #include "fetch-pack.h"
@@ -40,6 +41,7 @@ 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;
+static int option_no_tags;
 static int option_shallow_submodules;
 static int deepen;
 static char *option_template, *option_depth, *option_since;
@@ -120,6 +122,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"),
@@ -357,7 +361,7 @@ static void copy_alternates(struct strbuf *src, struct strbuf *dst,
         * to turn entries with paths relative to the original
         * absolute, so that they can be used in the new repository.
         */
-       FILE *in = fopen(src->buf, "r");
+       FILE *in = xfopen(src->buf, "r");
        struct strbuf line = STRBUF_INIT;
 
        while (strbuf_getline(&line, in) != EOF) {
@@ -563,7 +567,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;
@@ -652,7 +656,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);
        }
 
@@ -682,7 +686,7 @@ static void update_head(const struct ref *our, const struct ref *remote,
                        install_branch_config(0, head, option_origin, our->name);
                }
        } else if (our) {
-               struct commit *c = lookup_commit_reference(our->old_oid.hash);
+               struct commit *c = lookup_commit_reference(&our->old_oid);
                /* --branch specifies a non-branch (i.e. tags), detach HEAD */
                update_ref(msg, "HEAD", c->object.oid.hash,
                           NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
@@ -739,7 +743,7 @@ static int checkout(int submodule_progress)
        opts.src_index = &the_index;
        opts.dst_index = &the_index;
 
-       tree = parse_tree_indirect(oid.hash);
+       tree = parse_tree_indirect(&oid);
        parse_tree(tree);
        init_tree_desc(&t, tree->buffer, tree->size);
        if (unpack_trees(1, &t, &opts) < 0)
@@ -1037,6 +1041,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();