On Wed, Apr 26, 2017 at 4:12 PM, Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> wrote: > Add a --no-tags option to clone without fetching any tags. > > Without this change there's no easy way to clone a repository without > also fetching its tags. > > When supplying --single-branch the primary remote branch will be > cloned, but in addition tags will be followed & retrieved. Now > --no-tags can be added --single-branch to clone a repository without > tags, and which only tracks a single upstream branch. > > This option works without --single-branch as well, and will do a > normal clone but not fetch any tags. > > Many git commands pay some fixed overhead as a function of the number > of references. E.g. creating ~40k tags in linux.git will cause a > command like `git log -1 >/dev/null` to run in over a second instead > of in a matter of milliseconds, in addition numerous other things will > slow down, e.g. "git log <TAB>" with the bash completion will slowly > show ~40k references instead of 1. > > The user might want to avoid all of that overhead to simply use a > repository like that to browse the "master" branch, or something like > a CI tool might want to keep that one branch up-to-date without caring > about any other references. > > Without this change the only way of accomplishing this was either by > manually tweaking the config in a fresh repository: > > git init git && > cat >git/.git/config <<EOF && > [remote "origin"] > url = git@xxxxxxxxxx:git/git.git > tagOpt = --no-tags > fetch = +refs/heads/master:refs/remotes/origin/master > [branch "master"] > remote = origin > merge = refs/heads/master > EOF > cd git && > git pull > > Which requires hardcoding the "master" name, which may not be the main > --single-branch would have retrieved, or alternatively by setting > tagOpt=--no-tags right after cloning & deleting any existing tags: > > git clone --single-branch git@xxxxxxxxxx:git/git.git && > cd git && > git config remote.origin.tagOpt --no-tags && > git tag -l | xargs git tag -d > > Which of course was also subtly buggy if --branch was pointed at a > tag, leaving the user in a detached head: > > git clone --single-branch --branch v2.12.0 git@xxxxxxxxxx:git/git.git && > cd git && > git config remote.origin.tagOpt --no-tags && > git tag -l | xargs git tag -d > > Now all this complexity becomes the much simpler: > > git clone --single-branch --no-tags git@xxxxxxxxxx:git/git.git > > Or in the case of cloning a single tag "branch": > > git clone --single-branch --branch v2.12.0 --no-tags git@xxxxxxxxxx:git/git.git > > Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> I like the option, though I dislike the implementation, specifically as you brought up e.g. "[PATCH] various: disallow --no-no-OPT for --no-opt options". Can we have an option "--tags" instead, which is on by default and then you can negate it to --no-tags, without having to worry about the no-no case. The problem with tags is that they are in a shared name-space and not part of the remote refspec. If they were, the documentation would be way easier, too going this way. > +--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. In the future we may want to have '--depth' also imply --no-tags, just as it implies --single-branch. > @@ -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) I am debating if this needs to be an || instead of &&, as you would not want to write the tags with "--no-single-branch --no-tags" ? Thanks, Stefan