Merge branch 'ab/clone-no-tags'
authorJunio C Hamano <gitster@pobox.com>
Tue, 16 May 2017 02:51:54 +0000 (11:51 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 16 May 2017 02:51:54 +0000 (11:51 +0900)
"git clone" learned the "--no-tags" option not to fetch all tags
initially, and also set up the tagopt not to follow any tags in
subsequent fetches.

* ab/clone-no-tags:
tests: rename a test having to do with shallow submodules
clone: add a --no-tags option to clone without tags
tests: change "cd ... && git fetch" to "cd &&\n\tgit fetch"

Documentation/git-clone.txt
builtin/clone.c
contrib/completion/git-completion.bash
t/t5612-clone-refspec.sh
t/t5614-clone-submodules-shallow.sh [new file with mode: 0755]
t/t5614-clone-submodules.sh [deleted file]
index 30052cce49947914f71b16aa0474bfaa36d13b09..83c8e9b394a3a83639852210e2f6e237a0077ed2 100644 (file)
@@ -13,7 +13,7 @@ SYNOPSIS
          [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
          [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
          [--dissociate] [--separate-git-dir <git dir>]
-         [--depth <depth>] [--[no-]single-branch]
+         [--depth <depth>] [--[no-]single-branch] [--no-tags]
          [--recurse-submodules] [--[no-]shallow-submodules]
          [--jobs <n>] [--] <repository> [<directory>]
 
@@ -215,6 +215,18 @@ objects from the source repository into a pack in the cloned repository.
        branch when `--single-branch` clone was made, no remote-tracking
        branch is created.
 
+--no-tags::
+       Don't clone any tags, and set
+       `remote.<remote>.tagOpt=--no-tags` in the config, ensuring
+       that future `git pull` and `git fetch` operations won't follow
+       any tags. Subsequent explicit tag fetches will still work,
+       (see linkgit:git-fetch[1]).
++
+Can be used in conjunction with `--single-branch` to clone and
+maintain a branch with no references other than a single cloned
+branch. This is useful e.g. to maintain minimal clones of the default
+branch of some repository for search indexing.
+
 --recurse-submodules[=<pathspec]::
        After the clone is created, initialize and clone submodules
        within based on the provided pathspec.  If no pathspec is
index de85b85254e49ba0211ea6476179fc6d4c774ca9..05f52d6f2bd1205a399b380b7b68a0960ce6ef5d 100644 (file)
@@ -40,6 +40,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 +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"),
@@ -563,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;
@@ -652,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);
        }
 
@@ -1035,6 +1038,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();
 
index e77498dd9c51603b86e65efe11dba97fac3cd400..1ed0a09feef51ae606dbc2d7aa1944a49c6c28ee 100644 (file)
@@ -1319,6 +1319,7 @@ _git_clone ()
                        --template=
                        --depth
                        --single-branch
+                       --no-tags
                        --branch
                        --recurse-submodules
                        --no-single-branch
index 7ace2535c80e988e353ae09ecbf3bb24d6106ecc..fac5a738519fe4aec0c3b2328c410db693c11f63 100755 (executable)
@@ -17,13 +17,20 @@ test_expect_success 'setup' '
        echo four >file &&
        git commit -a -m four &&
        git checkout master &&
+       git tag five &&
 
        # default clone
        git clone . dir_all &&
 
+       # default clone --no-tags
+       git clone --no-tags . dir_all_no_tags &&
+
        # default --single that follows HEAD=master
        git clone --single-branch . dir_master &&
 
+       # default --single that follows HEAD=master with no tags
+       git clone --single-branch --no-tags . dir_master_no_tags &&
+
        # default --single that follows HEAD=side
        git checkout side &&
        git clone --single-branch . dir_side &&
@@ -45,6 +52,9 @@ test_expect_success 'setup' '
        # explicit --single with tag
        git clone --single-branch --branch two . dir_tag &&
 
+       # explicit --single with tag and --no-tags
+       git clone --single-branch --no-tags --branch two . dir_tag_no_tags &&
+
        # advance both "master" and "side" branches
        git checkout side &&
        echo five >file &&
@@ -59,7 +69,8 @@ test_expect_success 'setup' '
 
 test_expect_success 'by default all branches will be kept updated' '
        (
-               cd dir_all && git fetch &&
+               cd dir_all &&
+               git fetch &&
                git for-each-ref refs/remotes/origin |
                sed -e "/HEAD$/d" \
                    -e "s|/remotes/origin/|/heads/|" >../actual
@@ -71,28 +82,82 @@ test_expect_success 'by default all branches will be kept updated' '
 
 test_expect_success 'by default no tags will be kept updated' '
        (
-               cd dir_all && git fetch &&
+               cd dir_all &&
+               git fetch &&
                git for-each-ref refs/tags >../actual
        ) &&
        git for-each-ref refs/tags >expect &&
-       test_must_fail test_cmp expect actual
+       test_must_fail test_cmp expect actual &&
+       test_line_count = 2 actual
+'
+
+test_expect_success 'clone with --no-tags' '
+       (
+               cd dir_all_no_tags &&
+               git fetch &&
+               git for-each-ref refs/tags >../actual
+       ) &&
+       >expect &&
+       test_cmp expect actual
 '
 
 test_expect_success '--single-branch while HEAD pointing at master' '
        (
-               cd dir_master && git fetch &&
+               cd dir_master &&
+               git fetch &&
                git for-each-ref refs/remotes/origin |
                sed -e "/HEAD$/d" \
                    -e "s|/remotes/origin/|/heads/|" >../actual
        ) &&
        # only follow master
        git for-each-ref refs/heads/master >expect &&
-       test_cmp expect actual
+       # get & check latest tags
+       test_cmp expect actual &&
+       (
+               cd dir_master &&
+               git fetch --tags &&
+               git for-each-ref refs/tags >../actual
+       ) &&
+       git for-each-ref refs/tags >expect &&
+       test_cmp expect actual &&
+       test_line_count = 2 actual
+'
+
+test_expect_success '--single-branch while HEAD pointing at master and --no-tags' '
+       (
+               cd dir_master_no_tags &&
+               git fetch &&
+               git for-each-ref refs/remotes/origin |
+               sed -e "/HEAD$/d" \
+                   -e "s|/remotes/origin/|/heads/|" >../actual
+       ) &&
+       # only follow master
+       git for-each-ref refs/heads/master >expect &&
+       test_cmp expect actual &&
+       # get tags (noop)
+       (
+               cd dir_master_no_tags &&
+               git fetch &&
+               git for-each-ref refs/tags >../actual
+       ) &&
+       >expect &&
+       test_cmp expect actual &&
+       test_line_count = 0 actual &&
+       # get tags with --tags overrides tagOpt
+       (
+               cd dir_master_no_tags &&
+               git fetch --tags &&
+               git for-each-ref refs/tags >../actual
+       ) &&
+       git for-each-ref refs/tags >expect &&
+       test_cmp expect actual &&
+       test_line_count = 2 actual
 '
 
 test_expect_success '--single-branch while HEAD pointing at side' '
        (
-               cd dir_side && git fetch &&
+               cd dir_side &&
+               git fetch &&
                git for-each-ref refs/remotes/origin |
                sed -e "/HEAD$/d" \
                    -e "s|/remotes/origin/|/heads/|" >../actual
@@ -104,7 +169,8 @@ test_expect_success '--single-branch while HEAD pointing at side' '
 
 test_expect_success '--single-branch with explicit --branch side' '
        (
-               cd dir_side2 && git fetch &&
+               cd dir_side2 &&
+               git fetch &&
                git for-each-ref refs/remotes/origin |
                sed -e "/HEAD$/d" \
                    -e "s|/remotes/origin/|/heads/|" >../actual
@@ -116,16 +182,29 @@ test_expect_success '--single-branch with explicit --branch side' '
 
 test_expect_success '--single-branch with explicit --branch with tag fetches updated tag' '
        (
-               cd dir_tag && git fetch &&
+               cd dir_tag &&
+               git fetch &&
                git for-each-ref refs/tags >../actual
        ) &&
        git for-each-ref refs/tags >expect &&
        test_cmp expect actual
 '
 
+test_expect_success '--single-branch with explicit --branch with tag fetches updated tag despite --no-tags' '
+       (
+               cd dir_tag_no_tags &&
+               git fetch &&
+               git for-each-ref refs/tags >../actual
+       ) &&
+       git for-each-ref refs/tags/two >expect &&
+       test_cmp expect actual &&
+       test_line_count = 1 actual
+'
+
 test_expect_success '--single-branch with --mirror' '
        (
-               cd dir_mirror && git fetch &&
+               cd dir_mirror &&
+               git fetch &&
                git for-each-ref refs > ../actual
        ) &&
        git for-each-ref refs >expect &&
@@ -134,7 +213,8 @@ test_expect_success '--single-branch with --mirror' '
 
 test_expect_success '--single-branch with explicit --branch and --mirror' '
        (
-               cd dir_mirror_side && git fetch &&
+               cd dir_mirror_side &&
+               git fetch &&
                git for-each-ref refs > ../actual
        ) &&
        git for-each-ref refs >expect &&
@@ -143,7 +223,8 @@ test_expect_success '--single-branch with explicit --branch and --mirror' '
 
 test_expect_success '--single-branch with detached' '
        (
-               cd dir_detached && git fetch &&
+               cd dir_detached &&
+               git fetch &&
                git for-each-ref refs/remotes/origin |
                sed -e "/HEAD$/d" \
                    -e "s|/remotes/origin/|/heads/|" >../actual
diff --git a/t/t5614-clone-submodules-shallow.sh b/t/t5614-clone-submodules-shallow.sh
new file mode 100755 (executable)
index 0000000..a87d329
--- /dev/null
@@ -0,0 +1,122 @@
+#!/bin/sh
+
+test_description='Test shallow cloning of repos with submodules'
+
+. ./test-lib.sh
+
+pwd=$(pwd)
+
+test_expect_success 'setup' '
+       git checkout -b master &&
+       test_commit commit1 &&
+       test_commit commit2 &&
+       mkdir sub &&
+       (
+               cd sub &&
+               git init &&
+               test_commit subcommit1 &&
+               test_commit subcommit2 &&
+               test_commit subcommit3
+       ) &&
+       git submodule add "file://$pwd/sub" sub &&
+       git commit -m "add submodule"
+'
+
+test_expect_success 'nonshallow clone implies nonshallow submodule' '
+       test_when_finished "rm -rf super_clone" &&
+       git clone --recurse-submodules "file://$pwd/." super_clone &&
+       git -C super_clone log --oneline >lines &&
+       test_line_count = 3 lines &&
+       git -C super_clone/sub log --oneline >lines &&
+       test_line_count = 3 lines
+'
+
+test_expect_success 'shallow clone with shallow submodule' '
+       test_when_finished "rm -rf super_clone" &&
+       git clone --recurse-submodules --depth 2 --shallow-submodules "file://$pwd/." super_clone &&
+       git -C super_clone log --oneline >lines &&
+       test_line_count = 2 lines &&
+       git -C super_clone/sub log --oneline >lines &&
+       test_line_count = 1 lines
+'
+
+test_expect_success 'shallow clone does not imply shallow submodule' '
+       test_when_finished "rm -rf super_clone" &&
+       git clone --recurse-submodules --depth 2 "file://$pwd/." super_clone &&
+       git -C super_clone log --oneline >lines &&
+       test_line_count = 2 lines &&
+       git -C super_clone/sub log --oneline >lines &&
+       test_line_count = 3 lines
+'
+
+test_expect_success 'shallow clone with non shallow submodule' '
+       test_when_finished "rm -rf super_clone" &&
+       git clone --recurse-submodules --depth 2 --no-shallow-submodules "file://$pwd/." super_clone &&
+       git -C super_clone log --oneline >lines &&
+       test_line_count = 2 lines &&
+       git -C super_clone/sub log --oneline >lines &&
+       test_line_count = 3 lines
+'
+
+test_expect_success 'non shallow clone with shallow submodule' '
+       test_when_finished "rm -rf super_clone" &&
+       git clone --recurse-submodules --no-local --shallow-submodules "file://$pwd/." super_clone &&
+       git -C super_clone log --oneline >lines &&
+       test_line_count = 3 lines &&
+       git -C super_clone/sub log --oneline >lines &&
+       test_line_count = 1 lines
+'
+
+test_expect_success 'clone follows shallow recommendation' '
+       test_when_finished "rm -rf super_clone" &&
+       git config -f .gitmodules submodule.sub.shallow true &&
+       git add .gitmodules &&
+       git commit -m "recommed shallow for sub" &&
+       git clone --recurse-submodules --no-local "file://$pwd/." super_clone &&
+       (
+               cd super_clone &&
+               git log --oneline >lines &&
+               test_line_count = 4 lines
+       ) &&
+       (
+               cd super_clone/sub &&
+               git log --oneline >lines &&
+               test_line_count = 1 lines
+       )
+'
+
+test_expect_success 'get unshallow recommended shallow submodule' '
+       test_when_finished "rm -rf super_clone" &&
+       git clone --no-local "file://$pwd/." super_clone &&
+       (
+               cd super_clone &&
+               git submodule update --init --no-recommend-shallow &&
+               git log --oneline >lines &&
+               test_line_count = 4 lines
+       ) &&
+       (
+               cd super_clone/sub &&
+               git log --oneline >lines &&
+               test_line_count = 3 lines
+       )
+'
+
+test_expect_success 'clone follows non shallow recommendation' '
+       test_when_finished "rm -rf super_clone" &&
+       git config -f .gitmodules submodule.sub.shallow false &&
+       git add .gitmodules &&
+       git commit -m "recommed non shallow for sub" &&
+       git clone --recurse-submodules --no-local "file://$pwd/." super_clone &&
+       (
+               cd super_clone &&
+               git log --oneline >lines &&
+               test_line_count = 5 lines
+       ) &&
+       (
+               cd super_clone/sub &&
+               git log --oneline >lines &&
+               test_line_count = 3 lines
+       )
+'
+
+test_done
diff --git a/t/t5614-clone-submodules.sh b/t/t5614-clone-submodules.sh
deleted file mode 100755 (executable)
index a87d329..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/bin/sh
-
-test_description='Test shallow cloning of repos with submodules'
-
-. ./test-lib.sh
-
-pwd=$(pwd)
-
-test_expect_success 'setup' '
-       git checkout -b master &&
-       test_commit commit1 &&
-       test_commit commit2 &&
-       mkdir sub &&
-       (
-               cd sub &&
-               git init &&
-               test_commit subcommit1 &&
-               test_commit subcommit2 &&
-               test_commit subcommit3
-       ) &&
-       git submodule add "file://$pwd/sub" sub &&
-       git commit -m "add submodule"
-'
-
-test_expect_success 'nonshallow clone implies nonshallow submodule' '
-       test_when_finished "rm -rf super_clone" &&
-       git clone --recurse-submodules "file://$pwd/." super_clone &&
-       git -C super_clone log --oneline >lines &&
-       test_line_count = 3 lines &&
-       git -C super_clone/sub log --oneline >lines &&
-       test_line_count = 3 lines
-'
-
-test_expect_success 'shallow clone with shallow submodule' '
-       test_when_finished "rm -rf super_clone" &&
-       git clone --recurse-submodules --depth 2 --shallow-submodules "file://$pwd/." super_clone &&
-       git -C super_clone log --oneline >lines &&
-       test_line_count = 2 lines &&
-       git -C super_clone/sub log --oneline >lines &&
-       test_line_count = 1 lines
-'
-
-test_expect_success 'shallow clone does not imply shallow submodule' '
-       test_when_finished "rm -rf super_clone" &&
-       git clone --recurse-submodules --depth 2 "file://$pwd/." super_clone &&
-       git -C super_clone log --oneline >lines &&
-       test_line_count = 2 lines &&
-       git -C super_clone/sub log --oneline >lines &&
-       test_line_count = 3 lines
-'
-
-test_expect_success 'shallow clone with non shallow submodule' '
-       test_when_finished "rm -rf super_clone" &&
-       git clone --recurse-submodules --depth 2 --no-shallow-submodules "file://$pwd/." super_clone &&
-       git -C super_clone log --oneline >lines &&
-       test_line_count = 2 lines &&
-       git -C super_clone/sub log --oneline >lines &&
-       test_line_count = 3 lines
-'
-
-test_expect_success 'non shallow clone with shallow submodule' '
-       test_when_finished "rm -rf super_clone" &&
-       git clone --recurse-submodules --no-local --shallow-submodules "file://$pwd/." super_clone &&
-       git -C super_clone log --oneline >lines &&
-       test_line_count = 3 lines &&
-       git -C super_clone/sub log --oneline >lines &&
-       test_line_count = 1 lines
-'
-
-test_expect_success 'clone follows shallow recommendation' '
-       test_when_finished "rm -rf super_clone" &&
-       git config -f .gitmodules submodule.sub.shallow true &&
-       git add .gitmodules &&
-       git commit -m "recommed shallow for sub" &&
-       git clone --recurse-submodules --no-local "file://$pwd/." super_clone &&
-       (
-               cd super_clone &&
-               git log --oneline >lines &&
-               test_line_count = 4 lines
-       ) &&
-       (
-               cd super_clone/sub &&
-               git log --oneline >lines &&
-               test_line_count = 1 lines
-       )
-'
-
-test_expect_success 'get unshallow recommended shallow submodule' '
-       test_when_finished "rm -rf super_clone" &&
-       git clone --no-local "file://$pwd/." super_clone &&
-       (
-               cd super_clone &&
-               git submodule update --init --no-recommend-shallow &&
-               git log --oneline >lines &&
-               test_line_count = 4 lines
-       ) &&
-       (
-               cd super_clone/sub &&
-               git log --oneline >lines &&
-               test_line_count = 3 lines
-       )
-'
-
-test_expect_success 'clone follows non shallow recommendation' '
-       test_when_finished "rm -rf super_clone" &&
-       git config -f .gitmodules submodule.sub.shallow false &&
-       git add .gitmodules &&
-       git commit -m "recommed non shallow for sub" &&
-       git clone --recurse-submodules --no-local "file://$pwd/." super_clone &&
-       (
-               cd super_clone &&
-               git log --oneline >lines &&
-               test_line_count = 5 lines
-       ) &&
-       (
-               cd super_clone/sub &&
-               git log --oneline >lines &&
-               test_line_count = 3 lines
-       )
-'
-
-test_done