From: Ævar Arnfjörð Bjarmason Date: Wed, 19 Apr 2017 14:38:31 GMT Subject: [PATCH v2] clone: add a --no-tags option to clone without tags Message-ID: <20170419143831.6868-1-avarab@gmail.com> In-Reply-To: Add a --no-tags option to "git clone" to clone without tags. Currently there's no easy way to clone a repository and end up with just a "master" branch via --single-branch, or track all branches and no tags. Now --no-tags can be added to "git clone" with or without --single-branch to clone a repository without tags. Before this the only way of doing this was either by manually tweaking the config in a fresh repository: git init git && cat >git/.git/config < --- On Wed, Apr 19, 2017 at 3:38 AM, Junio C Hamano wrote: > Ævar Arnfjörð Bjarmason writes: > >> Add a --no-tags option to "git clone" to clone without tags. Currently >> there's no easy way to clone a repository and end up with just a >> "master" branch via --single-branch, or track all branches and no >> tags. Now --no-tags can be added to "git clone" with or without >> --single-branch to clone a repository without tags. > > Makes sense. > >> +--no-tags:: >> + Don't clone any tags, and set `remote.origin.tagOpt=--no-tags` >> + in the config, ensuring that future `git pull` and `git fetch` >> + operations won't fetch any tags. > > OK. Not just we ignore tags during the initial cloning, we set > things up so that we do not _follow_ tags in subsequent fetches. > > s/won't fetch/won't follow/ is probably needed, as we still allow > users to fetch tags by explicitly naming them on the command line. > The only thing we are doing is to refrain from auto-following. > > As an end-user facing help, exact configuration name and value is > much less helpful than telling them the effect of the setting in the > words they understand, i.e. "make later fetches not to follow tags" > or something. I reworded all of this to hopefully be more helpful. > Hardcoded 'origin' in `remote.origin.tagOpt` is not correct anyway, > so I'd suggest redoing this part of the doc. Changed, FWIW various parts of the existing clone docs do the same thing, so a follow-up change to that would make sense... >> @@ -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_NONEG(0, "no-tags", &option_no_tags, >> + N_("don't clone any tags, and set remote..tagOpt=--no-tags")), > > Likewise. As an end-user facing help, exact configuration name and > value is much less helpful than telling them the effect of the > setting in the words they understand, i.e. "make later fetches not > to follow tags" or something. *Nod* changed. >> + if (option_no_tags) { >> + strbuf_addf(&key, "remote.%s.tagOpt", option_origin); > > Good to use option_origin. > >> + git_config_set(key.buf, "--no-tags"); >> + strbuf_reset(&key); >> + } >> + > > Thanks. Documentation/git-clone.txt | 14 ++++++++- builtin/clone.c | 13 ++++++-- t/t5612-clone-refspec.sh | 73 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 95 insertions(+), 5 deletions(-) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 30052cce49..57b3f478ed 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 ] [-b ] [-u ] [--reference ] [--dissociate] [--separate-git-dir ] - [--depth ] [--[no-]single-branch] + [--depth ] [--[no-]single-branch] [--no-tags] [--recurse-submodules] [--[no-]shallow-submodules] [--jobs ] [--] [] @@ -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..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 & 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[=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 && @@ -75,7 +85,17 @@ 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' ' @@ -87,7 +107,46 @@ 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' ' @@ -123,6 +182,16 @@ 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 && git fetch && -- 2.11.0