Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clone a git repository with all branches?

Tags:

git

I have a server containing a git repository with several branches. I checked on the server git with "git branch -r" and it displays:
origin/HEAD
origin/develop
origin/neatUI
origin/iOS
... and some more

If I clone this repository with: "git clone [path_to_server]/ATS ATS" I receive a repository just containing "develop". "git branch -a" shows:
* develop
remotes/origin/HEAD -> origin/develop
remotes/origin/develop

All other branches are missing.

If I clone the repository with the --mirror option all branches are present but I cannot work with them. "git branch -a" shows:
remotes/origin/HEAD
remotes/origin/develop
remotes/origin/neatUI
remotes/origin/iOS
... and the rest

If I try to checkout a branch git tells me "fatal: This operation must be run in a work tree"

I also tried "SourceTree" to clone the repoistory but also SourceTree creates only the "develop" branch.

Anyone with an idea?

like image 284
Uwe Andersen Avatar asked Jun 13 '17 07:06

Uwe Andersen


People also ask

How do I clone a git repository with all branches?

The idea is to use the git-clone to clone the repository. This will automatically fetch all the branches and tags in the cloned repository. To check out the specific branch, you can use the git-checkout command to create a local tracking branch.

Does git clone get all remote branches?

git clone downloads all remote branches but still considers them "remote", even though the files are located in your new repository. There's one exception to this, which is that the cloning process creates a local branch called "master" from the remote branch called "master".

How do I get all branches in a repository?

1 Answer. git fetch --all and git pull -all will only track the remote branches and track local branches that track remote branches respectively. Run this command only if there are remote branches on the server which are untracked by your local branches.


1 Answers

There are a few separate, but intertwined, key concepts here.

The first is that while Git has branch names, that's not all that Git has (and for that matter, the term branch is ambiguous: see also What exactly do we mean by "branch"?). Git also has tags and what Git calls remote-tracking branch names, and these all fall into a general category called references.

  • A branch name like master is simply a reference whose full name starts with refs/heads/.

  • A remote-tracking branch name like origin/iOS is a reference whose full name starts with refs/remotes/, followed by the name of the remote itself (origin) and another slash. The last part, iOS, is something your Git normally copies from another Git.

    (The remote part of this is an almost-arbitrary string. You can invent your own remote names. However, the fact that the name of the remote gets a slash added afterward is tied to the reason you should be careful about using slashes in your remote names.)

  • To complete this particular list, a tag name like v1.0 is simply a reference whose full name starts with refs/tags/. There are yet more forms of references (refs/notes/ is for Git's git notes, and GitHub uses refs/pull/ for instance) but branch, tag, and remote-tracking branches are all built in, and standard, and most importantly, highly visible—so you should know about them.

When you run git branch, Git finds all your refs/heads/ reference names and shows them with refs/heads/ stripped off. When you run git branch -r, Git finds all your refs/remotes/ references and shows them with refs/remotes/ stripped off. When you run git branch -a, Git finds both, and shows the first with refs/heads/ stripped but shows the second with just refs/ stripped. (Why? Who knows! It's Git being gitty. :-) )

This explains why you see what you see, but not what happens with git clone --mirror, nor why you can git checkout iOS and suddenly have a new refs/heads/iOS; and for that we need two more items, about refspecs (as used with git fetch and git push), and about what Git calls DWIM, or Do What I Mean, in git checkout.

To keep this short: a refspec is just a pair of references, separated by a colon, and sometimes with one part replaced with *. For instance, refs/heads/*:refs/remotes/origin/* is a refspec. You can prefix a refspec with a leading plus sign as well; this sets the --force flag. Both git fetch and git push work with refspecs (and both have a --force flag of their own, which effectively adds a + to any refspecs you give on the command line). The reference before the colon is the source and the reference after the colon is the destination, and this matters because there are two Gits involved in git fetch and git push: yours, and some other Git.

When you git fetch, the source references are the other Git's references and the destination ones are yours. When you git push, the source references are yours and the destination ones are theirs.

Using git clone --mirror tells your Git to set up a bare repository (which I'll leave undefined here) and to set up +refs/*:refs/* as the refspec for git fetch. This copies all the references from the other Git at origin, but it means you cannot have your own branches: your Git is now an exact copy of theirs, and every time you run git fetch you replace everything you have with ... an exact copy of theirs, again.

The main point of most git clone operations is to get an inexact copy of "their Git". The fundamental idea here is that you want all of their branch names to become your remote-tracking branch names. Their master becomes your origin/master; their iOS becomes your origin/iOS.

This leaves no room for their origin/*, because your inexact-copy has its own origin/*. If you want to get their remote-tracking branches, you can—but you need to name them something else!

Once you do have your (non-mirror) clone, and their whatever becomes your origin/whatever, you can git checkout whatever and the DWIM action I mentioned (and linked) above comes into play, creating a new local whatever using your own origin/whatever—which you copied from their whatever!

like image 84
torek Avatar answered Sep 18 '22 05:09

torek