git保持多个远程服务器与所有分支同步 [英] git keeping multiple remote servers in sync with all branches

查看:339
本文介绍了git保持多个远程服务器与所有分支同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两台存储我的仓库的PC.它们不是通过任何类型的网络连接!让我们在两个不同的PC的repo1和repo2上命名存储库.

我有一个本地克隆",可以将它从一台转移到另一台PC.让我们将此克隆的存储库简称为克隆".

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

只需命令

git fetch --all repo2

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

目前我还不知道如何继续.

我发现了许多问题,例如:如何克隆所有远程在Git中分支?

但是没有一个答案涉及多个存储库!

那是根本无法管理的吗?

解决方案

首先,我建议您通过执行git remote -v来检查您处于风险中的仓库的URL.对于续集,我假设您有两个名为originrepo2的遥控器.

关于您提到的SO问题-如何克隆所有远程分支-应该指出,不需要检出所有分支来检索它们,因为git fetch repo2足以在本地获取远程repo2的全部历史记录. /p>

根据 doc 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关联的分支(请参见 git checkout的文档).

或者您可以执行常见的git操作,例如合并(例如),重新设置(例如,git rebase repo2/master),涉及从远程存储库中跟踪分支

建议同步两个仓库的工作流程

关于您的主要用例(使用本地可移动克隆"同步两个未通过网络直接连接的存储库),我认为最简单的配置是使用裸露的"可移动的中间存储库(即没有工作目录的存储库,请参见

要设置一个这样的存储库,您可以执行以下操作:

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中为resp.)中,您可以通过以下方式进行同步:

  • 以获取您选择的所有分支,如果操作为

    If I now fetch my clone from the origin ( which is here repo1), everything is fine. But if I need to use the repo2, I can't get it to run!

    Simply the command

    git fetch --all repo2
    

    gives me: fetch --all does not take a repository argument

    At this point I have no idea how to continue.

    I found a lot of worarounds like: How to clone all remote branches in Git?

    But none of the answers dealing with multiple repos!

    Is that simply not manageable?

    解决方案

    First, I'd suggest to check the URL of your repos at stake by doing git remote -v. For the sequel, I assume that you have two remotes named origin and repo2.

    Regarding the SO question you mention - How to clone all remote branches in Git? - it should be noted that it is unneeded to checkout all branches to retrieve them, because git fetch repo2 is enough to get locally the whole history of remote repo2.

    According to the doc of git fetch, you can also do git fetch --all (with no additional argument) instead of git fetch origin ; git fetch repo2.

    I recall that in order to list the remote branches corresponding to the remote called repo2, you can just do git branch -r which will show something like:

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

    that is, all remote branches are prefixed with the identifier of the remote.

    In order to browse the content of these remote branches (without requiring some internet connection), you can either do gitk --all to display a read-only summary of the history of all branches, or git checkout name-of-a-repo2-branch to create a local branch associated to the tracking branch name-of-a-repo2-branch (see the doc of git checkout).

    Or you can do the usual git manipulations such as merge (e.g. git merge origin/master), rebase (e.g., git rebase repo2/master) involving tracking branches from your remote repos.

    Proposition of workflow to sync your two repos

    Regarding your main use case (synchronize two repos that are not directly connected by a network, using a "local moveable clone"), I think the simplest configuration would be to have a "bare" moveable intermediate repo (i.e., a repo with no working directory, see the corresponding doc) at a given local URL, say "file:///path/to/bare-repo.git".

    To setup one such repo, you could just do:

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

    Then in repo1 you could do the following setup:

    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
    

    And of course, a similar setup in 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
    

    Now, in repo1 (resp. in repo2), you can sync in the following way:

    • to fetch all the branches you have selected and merge them if the operation is fast-forward (so this command is more powerful than just git fetch sync because all local branches will be updated if a manual merge commit is not required):

        git pull-ff-sync
      

    • to push all the branches you have selected (which relies on the matching setting of the push.default configuration):

        git push -v sync
      

    Remark to avoid one configuration step

    Note that if you don't want to change the push.default config of your two repos (e.g., if you also want to use git push to only push one branch from repo1 to another remote...), you can instead:

    • replace

        git config push.default matching
      

      with

        git config push.default upstream  # recommended
      

      or just with

        git config push.default simple  # the default config in Git >= 2.0
      

    • run the slightly longer command below to send all matching branches from repo1 (resp. repo2) to the sync remote in one go:

        git push -v sync :
      

    这篇关于git保持多个远程服务器与所有分支同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆