git shallow clone (clone --depth) misses remote branches

GitBranchShallow Clone

Git Problem Overview


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.

Git Solutions


Solution 1 - Git

After doing a shallow clone, to be able to checkout other branches from remote,

  1. Run (thanks @jthill):

     git remote set-branches origin '*'
    
  2. After that, do a git fetch -v

  3. 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 - Git

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 - Git

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's HEAD 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionminghuaView Question on Stackoverflow
Solution 1 - GitmarloView Answer on Stackoverflow
Solution 2 - GitalejandrodnmView Answer on Stackoverflow
Solution 3 - GitFlorian NeumannView Answer on Stackoverflow