Why does "git clone" not take a refspec? Why does "git clone" not take a refspec? jenkins jenkins

Why does "git clone" not take a refspec?


git clone can take a refspec via the generic --config option:

Set a configuration variable in the newly-created repository; this takes effect immediately after the repository is initialized, but before the remote history is fetched or any files checked out. [...] This makes it safe, for example, to add additional fetch refspecs to the origin remote.

Example:

 git clone -c remote.origin.fetch=+refs/changes/*:refs/remotes/origin/changes/* https://gerrit.googlesource.com/git-repo

However, I just realized this does not work as expected for me with git version 2.12.2.windows.2 as the changes ref is not really fetched when cloning. It gets properly added to .git/config, but I need to manually fetch it after the clone via

cd git-repogit fetch

Edit: This turns out to be known bug.


Please specify what is the refname that gerrit uses, that’s missing after the clone. And would simply git clone --origin <gerrit-suitable-origin-name> solve the problem?

Now for the long version. Your question is probably two questions combined. Why is it advantageous to git init, git remote add and git fetch, and why isn’t there a way to conveniently filter for refspecs when you initially clone the repository?

refspecs - After clone initialises a repo, the remote-refspec behaviour for the command is to add a default section to the .gitconfig that outlines the fetch spec:

[remote "origin"]url = ssh://host/your.gitfetch = +refs/heads/*:refs/remotes/origin/*

These are good and sane defaults, and the supplied refspecs are intended to fetch everything from the remote. If you need to change the refspecs you can do it manually by just editing the file. For example,

[remote "origin"]url = ssh://host/your.gitfetch = +refs/heads/atari:refs/remotes/origin/atarifetch = +refs/heads/vertigo:refs/remotes/origin/vertigo

After the edit, fetching will involve only the atari and vertigo branches from the origin remote, and the commonly present master for example, along with all other branches that might exist on the remote are ignored. This is of course similar to the option of supplying the refspecs to git fetch on the command line.

Overall it just isn’t necessary, and I reckon isn’t a clean design, to be able to support multiple initial refspecs upfront on the git clone command line, for the sole purpose of placing them in .gitconfig. You can even script much the same by running git clone and then sed on the .gitconfig file. It will also be problematic to decide which is the initial branch to checkout when cloning given the many possible refspecs.

init over clone - Assuming we avoid discussing the more advanced git clone setups, such as leveraging --reference, shallow depth with --depth, or creating bare repos, the distinction between init-add-fetch and clone are quite minor for your everyday flow.

Plain clone just copies an existing repository and setups “origin” as the remote for the source of creation. This comes with some minor annoyances - the “origin” remote is forced on you, remote tracking branches are created, an initial branch is setup, and HEAD is checked out. If however you start with git init you are slightly more in control. You can start manually adding remotes and fetch specific branches without checking anything out.

Note though that many aspects of git clone behaviour can be controlled by command line switches – so maybe the developers who prefer git init just aren’t aware of them? There isn’t enough information in the question to decide. Compared to the alternatives, git clone saves you some typing, staves off the thermal death of the universe and sets up sane upstream defaults - such as having master a tracking branch. I vote for clone.