summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-clone.txt14
-rw-r--r--builtin/clone.c13
-rw-r--r--contrib/completion/git-completion.bash1
-rwxr-xr-xt/t5612-clone-refspec.sh76
4 files changed, 99 insertions, 5 deletions
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 30052cc..83c8e9b 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -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
diff --git a/builtin/clone.c b/builtin/clone.c
index de85b85..05f52d6 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -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();
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 1150164..6da997c 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1309,6 +1309,7 @@ _git_clone ()
--template=
--depth
--single-branch
+ --no-tags
--branch
--recurse-submodules
--no-single-branch
diff --git a/t/t5612-clone-refspec.sh b/t/t5612-clone-refspec.sh
index 97c847f..fac5a73 100755
--- a/t/t5612-clone-refspec.sh
+++ b/t/t5612-clone-refspec.sh
@@ -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 &&
@@ -77,7 +87,18 @@ test_expect_success 'by default no tags will be kept updated' '
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' '
@@ -90,7 +111,47 @@ test_expect_success '--single-branch while HEAD pointing at master' '
) &&
# 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' '
@@ -129,6 +190,17 @@ test_expect_success '--single-branch with explicit --branch with tag fetches upd
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 &&