关于Git:从多个远程位置拉/推


pull/push from multiple remote locations

简而言之:有没有一种方法可以让git repo推送到远程repo列表中并从中拉出(而不是单个"来源")?

长话短说:当我在多台计算机上开发一个应用程序时,我经常会遇到这样的情况:比如在运输途中的一台笔记本电脑,在某个位置时的一台计算机"A",在另一台计算机上时的另一台计算机"B"。此外,笔记本电脑可能只与"A"或"B"连接,有时两者都有。

我想让Git总是"拉"和"推"到它当前可以连接到的所有计算机,因此从一台机器跳到另一台机器并继续无缝工作更容易。


使用现代版本的git,不再需要手动执行此操作!见下面Malvineus的解决方案。

在此转载:

1
2
git remote set-url origin --push --add
git remote set-url origin --push --add

原始答案:

这是我用了很长一段时间,没有不良后果,并建议由LinusTorvalds在git邮件列表。

Araqnid的解决方案是将代码引入您的存储库的合适方案……但是,当您像我一样拥有多个等效的权威上游(我将一些更关键的项目克隆到一个私有上游、GitHub和Codaset)时,每天都要对每个项目进行更改可能会很痛苦。

长话短说,git remote add所有的遥控器都是单独的……然后git config -e添加一个合并的遥控器。假设您有这个存储库config

1
2
3
4
5
6
7
8
9
10
11
12
[remote"GitHub"]
    url = [email protected]:elliottcable/Paws.o.git
    fetch = +refs/heads/*:refs/remotes/GitHub/*
[branch"Master"]
    remote = GitHub
    merge = refs/heads/Master
[remote"Codaset"]
    url = [email protected]:elliottcable/paws-o.git
    fetch = +refs/heads/*:refs/remotes/Codaset/*
[remote"Paws"]
    url = [email protected]:Paws/Paws.o.git
    fetch = +refs/heads/*:refs/remotes/Paws/*

…要为"Paws""Codaset"创建一个合并的远程文件,我可以在所有这些文件之后添加以下内容:

1
2
3
[remote"Origin"]
    url = [email protected]:Paws/Paws.o.git
    url = [email protected]:elliottcable/paws-o.git

一旦我做到了这一点,当我做了git push Origin Master的时候,它会依次推动Paws/MasterCodaset/Master,使生活变得更加轻松。


您可以使用git remote命令配置多个远程存储库:

1
git remote add alt alt-machine:/path/to/repo

要从所有配置的远程设备中提取并更新跟踪分支,但不合并到头中,请执行以下操作:

1
git remote update

如果它当前没有连接到其中一个遥控器,它将花费一些时间或者抛出一个错误,然后继续下一个。根据您想要如何组织收集更改,您必须从提取的存储库或cherry pick手动合并。

要从alt获取主分支并将其拉入当前头部,请执行以下操作:

1
git pull alt master

所以实际上,git pull几乎是git pull origin HEAD的简写(实际上,它在配置文件中查找以确定这一点,但您得到了这个想法)。

对于推送更新,您必须手动对每个回购执行此操作。我认为,推送是在考虑到中央存储库工作流的情况下设计的。


最新版本的git(截至2012年10月)允许您从命令行执行此操作:

1
2
3
git remote set-url origin --push --add user1@repo1
git remote set-url origin --push --add user2@repo2
git remote -v

然后,git push将推到user1@repo1,然后推到user2@repo2。如果你还想从他们那里得到git pull,那么就把--push去掉。


我将这些别名添加到了我的~/。bashrc:

1
2
alias pushall='for i in `git remote`; do git push $i; done;'
alias pullall='for i in `git remote`; do git pull $i; done;'


您可以通过以下方式添加遥控器:

1
2
git remote add a urla
git remote add b urlb

然后要更新所有回购操作:

1
git remote update

下面是我在.gitconfig别名部分中使用bash脚本的示例

1
2
[alias]
        pushall ="!f(){ for i in `git remote`; do git push $i; done; };f"


我在.git-config文件中向远程"origin"添加了两个单独的pushurl。当我运行git push origin"branchName"时,它将运行并推送到每个URL。不确定是否有更简单的方法来完成此操作,但这对于我自己来说是可行的,可以同时推送到Github源代码和My.VisualStudio源代码。

1
2
3
4
5
[remote"origin"]
  url ="Main Repo URL"
  fetch = +refs/heads/*:refs/remotes/origin/*
  pushurl ="repo1 URL"
  pushurl ="reop2 URl"

为了更新遥控器(即pull案例),事情变得更容易了。

利纳斯的声明

Sadly, there's not even any way to fake this out with a git
alias.

在Git邮件列表中引用的条目中,Elliottcable的答案不再为真。

git fetch在过去的某个地方学习了--all参数,允许一次性获取所有远程设备。

如果不是全部请求,可以使用--multiple开关来指定多个远程设备或一个组。


我冒昧地扩大了诺娜·乌比兹的回答;只需在你的~/。bashrc:

1
2
3
4
5
git-pullall () { for RMT in $(git remote); do git pull -v $RMT $1; done; }    
alias git-pullall=git-pullall

git-pushall () { for RMT in $(git remote); do git push -v $RMT $1; done; }
alias git-pushall=git-pushall

用途:

1
2
3
4
git-pullall master

git-pushall master ## or
git-pushall

如果您没有为git pull提供任何分支参数,那么从非默认远程设备的pull将失败;保持这个行为不变,因为它类似于git。


您需要一个脚本来循环它们。Git不提供"push all"。理论上可以在多个线程中执行push,但本机方法不可用。

获取更为复杂,我建议您线性执行此操作。

我认为你最好的答案是有一台机器,每个人都可以推/拉,如果可能的话。


使用下面的命令向全局gitconfig(/home/user/.gitconfig)添加别名。

1
git config --global alias.pushall '!f(){ for var in $(git remote show); do echo"pushing to $var"; git push $var; done; }; f'

一旦你提交了代码,我们就说

git push

默认情况下推到原点。在上面的别名之后,我们可以说

git pushall

代码将更新到所有远程设备,包括源站远程设备。


我想在vso/tfs中工作,然后在准备好的时候公开推到github。在私有VSO中创建的初始回购。当需要添加到Github时,我做到了:

1
2
git remote add mygithubrepo https://github.com/jhealy/kinect2.git
git push -f mygithubrepo master

像冠军一样工作…

要进行健全性检查,请发出"git remote-v"以列出与项目关联的存储库。

1
2
3
4
5
C:\dev\kinect\vso-repo-k2work\FaceNSkinWPF>git remote -v
githubrepo      https://github.com/jhealy/kinect2.git (fetch)
githubrepo      https://github.com/jhealy/kinect2.git (push)
origin  https://devfish.visualstudio.com/DefaultCollection/_git/Kinect2Work (fetch)
origin  https://devfish.visualstudio.com/DefaultCollection/_git/Kinect2Work (push)

简单的方法,为我工作…希望这能帮助别人。


添加EDOCX1[1]遥控器会变得有点乏味,因为您必须在使用的每台机器上进行设置。

另外,bashgit别名都假定您将推送到所有远程。(例如:我有一把我在Github和Gitlab上维护的sshag叉子)。我已经添加了上游遥控器,但我没有权限推送它。)

这里有一个git别名,它只使用包含@的push url推送到远程。

1
2
3
4
5
psall    ="!f() { \
    for R in $(git remote -v | awk '/@.*push/ { print $1 }'); do \
    git push $R $1; \
    done \
    }; f"

Adding new remote

1
2
3
git remote add upstream https://github.com/example-org/example-repo.git

git remote -vv

Fetch form multiple locations

1
git fetch --all

Push to locations

1
git push -u upstream/dev