19

I have a repository on Github with 2 branches: master and develop.

When I clone the repository and run $ git branch it shows only the master branch.
If I run $ git branch -a I can see all the remote branches.

Now, if I do a $ git checkout develop, I get the message:

Branch develop set up to track remote branch develop from origin.
Switched to a new branch 'develop'

What actually happened? Were the commits from the remote develop branch fetched when I ran $ git clone remote-url, or when I ran: $ git checkout develop, or neither?

Have I to do a $ git pull origin develop after checking out develop, or it's already done?

Please help me understand how clone works when there are multiple branches on remote.

Tamás Pap
  • 17,777
  • 15
  • 70
  • 102

5 Answers5

22

To put it simply, git clone repository-url does the following things, in order:

  1. Creates a new empty repository.

    git init
    
  2. Creates a remote called "origin" and sets it to the given url.

    git remote add origin repository-url
    
  3. Fetches all commits and remote branches from the remote called "origin".

    git fetch --all
    
  4. Creates a local branch "master" to track the remote branch "origin/master".

    git checkout --track origin/master
    

An interesting point is that a fork (in GitHub or Bitbucket) is just a server side clone.

Michael
  • 8,362
  • 6
  • 61
  • 88
rouble
  • 16,364
  • 16
  • 107
  • 102
13

git clone fetches all remote branches, but only creates one local branch, master, for you. So when you run git branch -a, you'll see something like this:

$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/develop
  remotes/origin/master

which means that you have one local branch master and several remote branches. When you ran git checkout develop, git creates another local branch develop to track remote branch origin/develop. git tries to synchronize tracking branches, so you don't have to do another pull after check out.

If the local and remote branches terminologies sound confusing to you, you can browse through this document. It has some nice figures to help you understand them, and how local and remote branches move when you do further commits.

You may find this answer helpful: How to clone all remote branches in Git?, the first answer.

Community
  • 1
  • 1
Yang
  • 7,712
  • 9
  • 48
  • 65
  • Thank you guys, each of you. Now I got it. Because it has the most complete explanation, I accept this answer. – Tamás Pap May 07 '13 at 20:35
  • Thanks, this is useful. One minor issue, you say "git tries to synchronize tracking branches, so you don't have to do another pull after check out" which seems to be suggesting that a checkout will synchronise remote tracked branches as part of the process. This is not the case and only a `git fetch` will retrieve updates from a remote (or `git pull` which uses fetch as the first part of the process). Checkout simply uses the existing local copy of the remote branch. Remote tracking only links local branches to remotes to simplify the command when pulling, it doesn't add any synchronisation. –  Dec 26 '16 at 01:19
10

git clone first creates a new empty repository. (like git init)

It then sets the given repository as a remote called "origin". (git remote add)

The main work is then done by git fetch, which is the only command talking to other repositories. It transfers all commits of the remote repository to the current repository and creates inside your local repository branches starting with "remote/origin/" corresponding with the branches on the remote repository.

If you have a default non-bare repository, it will also call git checkout to checkout usually the master branch.

If you call git branch -r it will show you the "remote" branches, i.e. those branches in your repository, which will get updated by git fetch. (You never work on these directly.)

Whenever you want to work on a branch you use git checkout which will create a copy of that branch, without the "remote/origin/" prefix. Those are the "local" branches on which you work. (git branch will show those.)

Almost everything you do will involve only your local repository. The only exception is git push, which is the only command to update remote repositories, and git fetch which is the only command to query other repositories.

git pull is just the combination of git fetch and git merge. The first fetches changes and updates remote/origin/* and the second merges those changes into your local branch.

michas
  • 25,361
  • 15
  • 76
  • 121
1

git clone fetches all branches of the repository by default. If you want to check out all branches, you need to clone a bare copy of the repository, unset the bare flag and reset it. Let me know if you have further issues.

Community
  • 1
  • 1
hd1
  • 33,938
  • 5
  • 80
  • 91
1

When you clone a repository you will get all branches and all commits that can be reached from any of those branches.

You will however not get a local branch of any other branch than master. The other ones are there as remote branches (remotes/origin/development) and you can check out any of those whenever you want. git will then set up tracking between the remote branch and the local one that you created when you did the check out.

Andreas Wederbrand
  • 38,065
  • 11
  • 68
  • 78