git使多个远程服务器与所有分支同步

时间:2018-04-29 10:22:10

标签: git

我有两台电脑,我存放了我的回购。他们通过任何类型的网络连接!让我们在两个不同的电脑repo1和repo2上命名回购。

我有一个本地"克隆"我可以从一个移动到另一个PC。让我们将这个克隆的存储库命名为" clone"。

如果我现在从原点(这里是repo1)获取我的克隆,一切都很好。但如果我需要使用repo2,我就无法运行它!

只需命令

git fetch --all repo2

给我:fetch --all不接受存储库参数

此时我不知道如何继续。

我发现了许多类似的内容:How to clone all remote branches in Git?

但是没有一个处理多个回购的答案!

这根本不可控制吗?

2 个答案:

答案 0 :(得分:3)

首先,我建议您通过git remote -v检查您的回购网站的网址。对于续集,我假设你有两个名为originrepo2的遥控器。

关于你提到的SO问题 - How to clone all remote branches in Git? - 应该注意,检查所有分支以检索它们是不需要,因为git fetch repo2足以在本地获取远程repo2的整个历史。

根据doc of git fetch,您还可以执行git fetch --all(无其他参数)而不是git fetch origin ; git fetch repo2

我记得为了列出与名为repo2的遥控器相对应的远程分支,您可以git branch -r执行以下操作:

origin/HEAD -> origin/master
origin/master
origin/name-of-an-origin-branch
...
repo2/HEAD -> repo2/master
repo2/master
repo2/name-of-a-repo2-branch
...

即,所有远程分支都以远程标识符作为前缀。

为了浏览这些远程分支的内容(不需要某些互联网连接),您可以gitk --all显示所有分支的历史记录的只读摘要,或git checkout name-of-a-repo2-branch创建与跟踪分支name-of-a-repo2-branch关联的本地分支(请参阅doc of git checkout)。

或者您可以执行通常的git操作,例如merge(例如git merge origin/master),rebase(例如,git rebase repo2/master),包括跟踪远程回购中的分支。< / p>

同步两个回购的工作流程的提议

关于您的主要用例(同步两个未通过网络直接连接的repos,使用&#34;本地可移动克隆&#34;),我认为最简单的配置是有一个&#34;裸露&#34;可移动的中间存储库(即,没有工作目录的存储库,请参阅corresponding doc)在给定的本地URL,例如&#34; file:///path/to/bare-repo.git"。

要设置一个这样的回购,您可以这样做:

git init --bare /path/to/bare-repo.git

然后在repo1中你可以进行以下设置:

git remote add sync file:///path/to/bare-repo.git
git config alias.pull-ff-sync '!f(){ git fetch sync && git for-each-ref --format "%(refname:strip=3)" refs/remotes/sync/ | grep -v -e '\''^HEAD$'\'' | xargs -n1 bash -c '\''git checkout -q "$1" && git pull --ff-only -v sync "$1"'\'' bash; }; f'
git config alias.pull-ff-sync  # to check the alias has been properly setup
# and in particular that the «'\''» have been replaced with single «'»

git config push.default matching

for b in master develop ... ; do git push sync ${b}; done
# push all the branches you want to sync

当然,repo2中的类似设置:

git remote add sync file:///path/that/can/be/different/to/bare-repo.git
git config alias.pull-ff-sync '!f(){ git fetch sync && git for-each-ref --format "%(refname:strip=3)" refs/remotes/sync/ | grep -v -e '\''^HEAD$'\'' | xargs -n1 bash -c '\''git checkout -q "$1" && git pull --ff-only -v sync "$1"'\'' bash; }; f'
git config push.default matching

现在,在repo1(在repo2中),您可以通过以下方式进行同步:

  • 获取您选择的所有分支,并在操作为fast-forward时合并它们(因此该命令比git fetch sync更强大,因为如果有手册,所有本地分支都会更新不需要合并提交):

    git pull-ff-sync
    
  • 推送您选择的所有分支(取决于push.default configurationmatching设置):

    git push -v sync
    

备注以避免一个配置步骤

请注意,如果您不想更改两个repos的push.default配置(例如,如果您还想使用git push仅将一个分支从repo1推送到另一个远程...),你可以改为:

  • 替换

    git config push.default matching
    

    git config push.default upstream
    

    或只是

    git config push.default simple  # the default config in Git >= 2.0
    
  • 运行稍长的命令,将repo1(resp.repo2)中所有匹配的分支一次性发送到同步远程:

    git push -v sync :
    

答案 1 :(得分:0)

ErikMD的两个原因是正确的答案。

但是,如果您不关心强制推送回购,即您已经运行(git pull --allgit fetch -all)并确保其他PC在您使用期间不会提交任何内容正在这样做,然后:

git push --mirror

来自文档:

  

- 镜

     

不是将每个引用命名为push,而是指定将refs /(包括但不限于refs / heads /,refs / remotes /和refs / tags /)下的所有引用镜像到远程存储库。新创建的本地引用将被推送到远程端,本地更新的引​​用将在remoate端强制更新,并且已删除的引用将从远程端删除。如果设置了配置选项remote..mirror,则这是缺省值。

修复all选项的另一种方法是尝试this answer