6

I have some problems with Git using cloned repositories and branches and it's somehow not possible for me to find an answer to this. Let me describe: we have a bare master Git repository here we all pull from and push to, located on a local linux machine and reachable with ssh. I made a clone of this to my usb thumb drive like this:

git clone ssh://adahl@gollum//net/repos/netcube/patches.git

This gives me of course a local clone with a working copy on my thumb drive. I cd to this and see some branches in this clone then:

cd patches
git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/stable

So far so good, however if I clone the repository on my thumb drive another time to my notebook the stable branch is lost. See:

cd ..
git clone patches patches2

cd patches2

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

I tried several options when cloning or a git fetch after cloning, nothing brings the stable branch to the patches2 repository. I assume I have a lack of understandig git here and simply use it the wrong way. Could someone please point me to my error in usage and/or understanding?

LeSpocky
  • 422
  • 1
  • 5
  • 13
  • 1
    Thanks to the comments I get an idea what my misconception was. What I wanted was »transfer repositories« with _all_ the content from the master repository but Git does some kind of selective cloning based on what your tracking branches are. With `git clone --mirror` I get an intermediate repository I can use the way I expected. – LeSpocky Apr 07 '11 at 06:11
  • To put it more simply, `git clone` (without special options) won't copy remote-tracking branches from a source repo, only the local branches on the source (the ones under `.git/refs/heads/` on the source, not the ones under `.git/refs/remotes//`. –  Jun 25 '14 at 04:50

4 Answers4

12

In addition to @ThiefMaster:

I like to

git clone --mirror

or

git push --mirror 

to update all (local & remote) branch refs and tags

Additional info As noted, --mirror will really replicate the repo as is, thus overwritany changes in the destination. Branches that do not exist in the source will get pruned unconditionally.

Essentially, it is like working with a remote and doing 'git remote update --prune', the difference being that the branches affected can be local branches as well as 'remote' refs[1]

@LeSpocky (and others?)

Now if changes disappear, they will never generate merge problems, so that's easy.

--mirror is named after the real-life concept, so it was designed to pave over any differences in the target. If the target is non-bare, and you had local changes committed, you can always get them back via the reflog of the target's local branch (git log -g, git reflog).

As a general safety measure you could have a hook to 'git stash save' in the target.

Keep in mind though, that --mirror was designed to, well, mirror and this question was in fact on how to replicate all branches to a bare remote. :)

[1] (the refs are there, but the remote definitions don't get copied; if you want that, do a manual copy from .git/config to .git/config on the push destination)

Community
  • 1
  • 1
sehe
  • 328,274
  • 43
  • 416
  • 565
  • If I use the `--mirror` option to create my transfer repository _patches_ the subsequent clone to _patches2_ has the stable branch. Seems like this is the option I need for the thing I want to achieve. – LeSpocky Apr 06 '11 at 08:57
  • 1
    Note that `--mirror` can have side effects if someone else changes the repository you're mirroring in between when you clone from it and then push to it - `--mirror` sets up pushes such that they always overwrite the remote, regardless of any newer changes. – Amber Apr 07 '11 at 08:25
  • @Amber: Updated answer for additional info – sehe Apr 07 '11 at 08:29
  • @Amber Did I understand correctly, that pushing back changes from my clone to the mirror repository and then from the mirror repository to the master repository make newer changes in the master somehow disappear and I maybe get problems merging them? – LeSpocky Apr 08 '11 at 05:43
  • @LeSpocky: added answers in post – sehe Apr 08 '11 at 06:43
3

See How to clone all remote branches in Git?

You need to create a local branch based on the remote branch if you actually want it to be included in a clone. However, since you don't work in remote branches anyway you'll create local branches as soon as you start working on a branch. And before that you don't really need it in your clone since you can simply fetch it from remote at any point.

However, if the notebook has no network connectivity, you'll have to create local branches for all remote branches you want so they are cloned when cloning your local repo.

If you do have network connectivity however, use git remote add origin2 ssh://adahl@gollum//net/repos/netcube/patches.git and then git fetch origin2 - feel free to replace origin2 with a more meaningful name.

Community
  • 1
  • 1
ThiefMaster
  • 285,213
  • 77
  • 557
  • 610
  • If I had network connectivity from the notebook to the master repository, I wouldn't need the transfer repository (patches) anyway. What confuses me is, that the first clone to the transfer repository seems to be a »exact« clone with _all_ changesets of the master repository but the second clone drops some changesets, just because there's no »local branch« label on it. – LeSpocky Apr 06 '11 at 08:48
  • No, the first clone just adds the source as a remote (*origin*) and thus fetches the its branches. However, remotes are not cloned so the repo on your stick won't have this remote or its branches. – ThiefMaster Apr 06 '11 at 09:25
  • This is what I did now: Create tracking branches in my transfer repository, so these can also be cloned in subsequent clones. This requires a little more manual work, but it seems the proper solution. – LeSpocky Apr 12 '11 at 09:15
2

"origin" is the default name given to the place you cloned the repo from, which is automatically added as a remote (note: remote just means "a repo not the current one" - remotes can be on the same machine).

In patches, "origin" refers to the original repo on gollum.

In patches2, "origin" refers to patches.

Remote tracking refs (the ones that begin with remotes/) are not actually local branches - they're just pointers to where branches were last known to be on the remote. Thus, in patches, you have remote tracking refs for the original repo, but on patches2, you only have a remote tracking ref for the local master branch in patches, because that's where patches2's origin points to.

You can use git remote add to add the original repo as another remote in patches2 after cloning it - or you could just clone again from the original repo instead of from patches.

Amber
  • 446,318
  • 77
  • 595
  • 531
  • I can not clone to _patches2_ from the original repo, because I can't connect to the original repo. The repository _patches_ is just a »transfer repository« where I wouldn't work anyway. – LeSpocky Apr 06 '11 at 08:52
  • @LeSpocky: I think the point you're missing is that the branches listed as "remote" in `patches2` are all the ones that are "local" in `patches` (since that's what `origin` refers to, like @Amber said). If you haven't checked out (locally) the `stable` branch in `patches`, then it won't be in the list of remotes for `patches2`. – nickgrim Apr 06 '11 at 09:12
  • The problem is: if I use TortoiseGit to show _all_ the changesets of _all_ branches in _patches2_ it seems the changesets belonging to the _stable_ branch in _patches_ are not cloned to _patches2_, so even if I would know which changesets I need, I wouldn't get them in the second repo (patches2), because they are not cloned from the first repo (patches). However I assumed the whole repository with _all_ changesets is cloned and not only a part of it. – LeSpocky Apr 06 '11 at 10:22
  • When you clone a repo, you only get the changesets that are in branches your repo clones. Remote tracking refs are not cloned. Thus, you do not get the changesets in remote tracking refs. – Amber Apr 07 '11 at 02:15
  • So that was my basic misconception (and I think this is because mercurial handles this different). Git does some kind of selective cloning instead of always cloning the whole repository. – LeSpocky Apr 07 '11 at 06:08
  • If you want to clone the whole repository, you usually use `git clone --mirror`. The default behavior in Git is to only make a local branch pointing to what the remote's `HEAD` was pointing to, and keep the other branches as remote tracking refs. – Amber Apr 07 '11 at 08:24
0
$ git remote update
$ git pull --all
Edson Medina
  • 8,352
  • 3
  • 37
  • 48