5

I have a bare repository, whose origin is on a remote machine.

I would like to download its branches into the local bare repo. I.e. I want to see them with a git branch -vva command in the branch list, like so:

* master                0bc84f0 [origin/master] something...
  remotes/origin/HEAD   -> origin/master
  remotes/origin/master 0bc84f0 something...

In the case of non-bare repos, a git pull --all synchronized also the branches (it made the remote branches visible in the local repository), but in the case of a bare repo, pull is impossible.

How can I sync the remote branches in this scenario?


Note: git --fetch doesn't work, the remote branches are still invisible after it:

$ git remote -v
origin  git://host/project.git (fetch)
origin  git://host/project.git (push)
$ git branch -vva
* master 4085a31 ...something
$ git fetch
From git://host/project.git
 * branch            HEAD       -> FETCH_HEAD
$ git branch -vva
* master 4085a31 ...something

Additional info: my config is the following:

[core]
        repositoryformatversion = 0
        filemode = false
        bare = true
        symlinks = false
        ignorecase = true
[remote "origin"]
        url = git://host/project.git

My config in a newly cloned (also bare) repo:

[core]
        repositoryformatversion = 0
        filemode = true
        bare = true
[remote "origin"]
        url = git://host/project.git
peterh
  • 11,875
  • 18
  • 85
  • 108

5 Answers5

10

Solution #1:

You need to convert your repo to a mirror repo:

git remote add --mirror=fetch origin <url>
git fetch

A mirror repo will keep to local references in sync with the origin references after a fetch. It has the disadvantage, that a mirror should be an exact copy of the remote repo, what may be not your goal.


Solution #2:

(Extension from @peterh using the comments):

In the git config (simply repo/config in the case of a bare repo), a

[remote "origin"]
  fetch = +refs/heads/*:refs/remotes/origin/*

should exist. If it doesn't, it may be a non-trivial git feature, or a git bug. You can fix it by hand. After that, git fetch will work.

peterh
  • 11,875
  • 18
  • 85
  • 108
yaba
  • 829
  • 7
  • 11
  • I didn't know this was a thing. Pretty neat! – alexbclay Sep 15 '16 at 17:40
  • Thanks for your answer! But, currently I won't convert my repo to a mirror repo. – peterh Sep 15 '16 at 17:53
  • 1
    The problem with this: mirror-repo is an exact duplicate of the remote side, what is not my intention. I only want to see the remote branches. – peterh Sep 19 '16 at 15:27
  • Does your config file have the following entry: `[remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/*`? This states to fetch all branches and write them to refs/remotes/origin – yaba Sep 19 '16 at 16:52
  • @yaba No, below `[remote "origin"]` is there only an `url = git://host/project.git`. What I find quite surprising, how could it happen. The config still doesn't contain it in the case of a new clone. – peterh Sep 20 '16 at 06:49
  • @yaba After inserting this into the config, `git fetch` works, but I suspect now a git bug. – peterh Sep 20 '16 at 06:58
  • glad to hear you found a solution. You can still try `git config --global -l` to see if maybe there is something wrong in your global config, which causes the `remote.origin.fetch` to have non-default values. – yaba Sep 20 '16 at 07:22
5

A git fetch should have been enough.

Just for testing, simply try and clone again your bare repo into a new local repo. See then if the remote tracking branches are there.

git clone git://host/project.git newproject
cd newproject
git branch -avv

I've did a new clone, and I still can't see any remote branches, despite that the origin points to the correct url.
The situation is still the same, as you can see at the end of my question (correct origin URL, but still no remote branches)

That means those remote branches are not in the remote repo in the first place.
The default fetch refspecfor a clone is

fetch = +refs/heads/*:refs/remotes/origin/*

If the remote repo had any other branches, they would have been cloned as well.

If the config does not show any fetch key (as seen with git config -l), try and add one:

git config remote.origin.fetch +refs/heads/*:refs/remotes/origin/*

Check that with:

git config --get remote.origin.fetch

See more at "git fetch doesn't fetch all branches".


The true question then becomes: what in the OP's config makes a git clone clones only master and include no fetch refspec?

Maybe a Git environment variable is set?
For instance, GIT_TEMPLATE_DIR (which would include a default config)

Simply adding the fetch refspec does not solve the actual issue.
For solving the actual issue, more information is needed (Git version, OS version, ...)

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • As you can see at the end of the question, git fetch doesn't work. I've copied the commands and their outputs into the question. Both repos are bare. – peterh Sep 20 '16 at 06:44
  • @peterh Yes, hence my suggestion to `git clone` (for testing), not `git fetch`. – VonC Sep 20 '16 at 06:45
  • Ok, right! I've did a new clone, and I still can't see any remote branches, despite that the `origin` points to the correct url. The situation is still the same, as you can see at the end of my question (correct `origin` URL, but still no remote branches). – peterh Sep 20 '16 at 06:50
  • @peterh That means those remote branches are *not* in the remote repo in the first place. The default refspec (https://git-scm.com/book/en/v2/Git-Internals-The-Refspec) for a clone is `fetch = +refs/heads/*:refs/remotes/origin/*`: if the remote repo has any other branches, they would have been cloned as well. – VonC Sep 20 '16 at 06:52
  • @peterh I have edited the answer: can you try and add a `fetch` entry to your `remote.origin` key? – VonC Sep 20 '16 at 07:07
  • @peterh just to be clear, I suggested adding the git fetch refspec after seing your config -l: I have added the command to add the fetch section – VonC Sep 20 '16 at 07:30
2

add to your config in the bare repo the following line :

fetch = +refs/*:refs/*

your config would then look like:

[core]
    repositoryformatversion = 0
    filemode = false
    bare = true
    symlinks = false
    ignorecase = true
[remote "origin"]
    url = git://host/project.git
    fetch = +refs/*:refs/*

and then in your repo do

git --bare  fetch

and new branches will be downloaded

Danny
  • 1,603
  • 1
  • 15
  • 25
1

git pull is shorthand for running git fetch to synchronize the branch, then git merge to merge the local copy with the remote version.

From your bare repo, all you need to do is git fetch to sychronize your local branch refs.

See here for more info: https://git-scm.com/docs/git-fetch

alexbclay
  • 1,389
  • 14
  • 19
  • `git --fetch` doesn't work. I updated the question. As I understand the doc (thank you very much for the link), it loads only a given remote branch, but not the list of the remote branches. – peterh Sep 15 '16 at 17:52
  • When I set up a bare repo, then point it at a full repo and do `git fetch`, it updates my bare repo's remote branch list and looks like this: `* [new branch] adfsl -> origin/adfsl` or `38b8475..9bd1033 adff -> origin/adff`. Can you post what you're seeing before and after you fetch? – alexbclay Sep 15 '16 at 19:58
  • Yes, I copy-pasted the whole scenario into my question. – peterh Sep 16 '16 at 07:12
1

One would have to start with:

git clone --mirror git@host/project.git

this creates a bare repo and is ready to receive updates then cd into your project.git and to update your local bare repo:

git --bare  fetch

Just tested it and works like a charm

Danny
  • 1,603
  • 1
  • 15
  • 25