0

I have a repository with a number of branches. e.g.

git --branch -a
*master
remotes/origin/HEAD -> origin/master
remotes/origin/branch1
remotes/origin/branch2
remotes/origin/master

Iconverted it to a bare repository using the method found here : How to convert a normal Git repository to a bare one?

In the bare repository, running the same command "git branch -a ", all the branches are listed.

git --branch -a
*master
remotes/origin/HEAD -> origin/master
remotes/origin/branch1
remotes/origin/branch2
remotes/origin/master

Once I clone from the bare repository, the branches are gone. Running git --branch -a shows:

git clone git-server git-local
cd git-local
git --branch -a
*master
remotes/origin/HEAD - origin/master
remotes/origin/master

Is there anything I'm missing? How do I get the branches back?

Community
  • 1
  • 1
Sunil Khiatani
  • 337
  • 4
  • 12

1 Answers1

1

They're not really "missing": they're deliberately not taken in a new clone.

Another way to put this is that your bare repository has only one branch, master. The other things you see (remotes/origin/branch1 and so on) are not branches, they are "remote branches". (These names are unfortunately similar. You can qualify the local branches with the word "local" to distinguish them from the "remote branches". So another way to put this is that clone only copies local branches.)

Remember that every clone is an independent git repository.1 The idea is that you make this clone and then modify it yourself. Your changes are purely yours, up until you decide to publish (share) them. So your clone starts out as a copy of the thing you're cloning, but then gets changed as you do your own work.

Whether or not you change your copy, at some point you might like to pick up changes that someone else has published (shared). This is where git's "remote branches" come in. Your private repository copy will have your own personal, local branches, which are up to you to create and maintain. But wherever you copied from originally—i.e., origin—is also an independent repository. The person you copied from—let's call this guy Bob, just so that he has a name—may have made some changes and then decided to allow you to share them. To pick up Bob's changes, you put, in your copy, a set of "remote branches" that keep track of where Bob's repository's branches were.

These are the remotes/origin/ branches you see, such as remotes/origin/master. Clearly you have, or at least had, access to Bob's repository, because you cloned it to make your repository. So your git repository records the URL for Bob's under the remote name origin (the origin of your clone).

Let's say someone else, Clara for example, now clones your repository. She will get, as her "remote branches", your (local) branches. She does not get Bob's branches because Clara is not copying Bob's repository. She just gets your branches, which on her repository, live under remotes/origin/. She gets your master and calls it remotes/origin/master. This has nothing to do with your remotes/origin/master, which you and your clone use to track Bob's work in Bob's master.

If you make your repository pick up all Bob's changes, and integrate all of Bob's changes into your local branches, then at this point Clara can pick up your branches, which are the same as Bob's branches, and thus catch up with Bob. But she does it through you.

Should Clara realize that Bob exists and decide to pick up his stuff directly, she may record another remote in her clone. Let's say she calls this remote bob:

$ git remote add bob ssh://whatever... # whatever URL is appropriate

Clara can now run git fetch bob to contact Bob's system and pick up his local branches. In her git repository, these will be called remotes/bob/: she will acquire a remotes/bob/master, for instance. Clara can then compare remotes/bob/master and remotes/origin/master in her repository to see whether you have been keeping your master up to date with Bob's master: her remotes/origin/master is a copy of your master as of the last time she re-synchronized with you, and her remotes/bob/master is a copy of Bob's master as of the last time she re-synchronized with Bob.

In short, a clone does not copy remotes/ branches because this makes no sense. The people making the clone have access to your repository—the one they're cloning—and generally do not care whether your repository has access to some other repository. They care only about your branches—at least, until they add more remotes.


1At least, independent-in-principle. You can make "shallow" clones that are essentially incomplete. These are still independent, they just have backward references that cannot be resolved without contacting another repository first, to "deepen" the copy. A non-shallow ("fully deep", as it were) clone has everything though, and is truly independent.

torek
  • 448,244
  • 59
  • 642
  • 775