git shallow clone (clone --depth) misses remote branches
After cloning a remote repository it does not show any remote branch by -a option. What could be the problem? How to debug it? In this snippet two of the remote branches are not shown:
$ git clone --depth 1 git://git.savannah.gnu.org/pythonwebkit.git
$ cd pythonwebkit
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
$ git --version
git version 1.8.3.1
Tried the same command on another machine, it works well:
$ git clone --depth 1 git://git.savannah.gnu.org/pythonwebkit.git
Receiving objects: 100% (186886/186886), 818.91 MiB | 3.44 MiB/s, done.
$ cd pythonwebkit/
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/debian
remotes/origin/master
remotes/origin/python_codegen
$ git --version
git version 1.7.1
Tried also cloning another repo, it works well. Though I can try it on this machine again, but it would be better to know what's wrong.
Any suggestions or hints will be more than welcome.
Edit: Answer summary: Since git version 1.8.3.2 the "--depth" and "--no-single-branch" need to be used together to get the same behavior as before. This is deemed a bug fix.
Solution 1:
After doing a shallow clone, to be able to checkout other branches from remote,
-
Run (thanks @jthill):
git remote set-branches origin '*'
After that, do a
git fetch -v
Finally
git checkout the-branch-i-ve-been-looking-for
Step 1 can also be done manually by editing .git/config
.
For instance, change the folloing line from:
fetch = +refs/heads/master:refs/remotes/origin/master
to (replace master
with *
):
fetch = +refs/heads/*:refs/remotes/origin/*
Solution 2:
From reading the responses and the comment from @jthill, the thing that worked best for me was to use the set-branches
option on the git remote
command:
$ git clone --depth 1 https://github.com/dogescript/dogescript.git
$ git remote set-branches origin 'remote_branch_name'
$ git fetch --depth 1 origin remote_branch_name
$ git checkout remote_branch_name
This changes the list of branches tracked by the named remote so that we can fetch and checkout just the required branch.
Solution 3:
The behavior is correct, after the last revision the master-branch is (since this is the primary remote's HEAD) the only remote-branch in the repository:
florianb$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
The full clone offers new (all) branches:
florianb$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/debian
remotes/origin/master
remotes/origin/python_codegen
Shallow clones
Due to the shallow-description in the technical documentation, a "git-clone --depth 20 repo
[...] result[s in] commit chains with a length of at most 20." A shallow clone therefore should contain the requested depth of commits, from the tip of a branch.
As - in addition - the documentation of git clone
for the --single-branch
-option describes:
"Clone only the history leading to the tip of a single branch, either specified by the
--branch
option or the primary branch remote'sHEAD
points at. When creating a shallow clone with the--depth
option, this is the default, unless--no-single-branch
is given to fetch the histories near the tips of all branches."
Therefore a shallow clone (with the depth-option) only fetches only one single branch (at your requested depth).
Unfortunately both options (--depth
and --single-branch
) have been faulty in the past and the use of shallow clones implicits unresolved problems (as you can read in the link I posted above), which is caused by the given history-rewrite. This leads in overall to somewhat complicated behavior in special cases.