简体   繁体   中英

How can I synchronize git branches between bare repositories?

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

I would like to download its branches into the local bare repo. Ie 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

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.

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 refspec for 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, ...)

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM