ChatGPT解决这个技术问题 Extra ChatGPT

如何从多个远程位置拉/推?

git

简而言之:有没有办法让 git repo 推送到远程仓库列表(而不是单个“来源”)并从中拉取?

长篇:当我在多台计算机上开发应用程序时,我经常遇到这样一种情况,它们具有不同的连接性——比如在途中使用一台笔记本电脑,一台计算机“A”当我在某个位置时,另一台计算机“B”而在另一个。此外,笔记本电脑可能仅与“A”或“B”连接,有时两者都连接。

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

截至 2016 年的新访问者请注意:当前正确的执行此操作的方法(由一流的 git 功能认可)包含在 malvineousanswer below 中。接受的答案不正确。
我发现答案 provided here 非常详细和总结

G
Gangula

不再需要手动执行此操作,使用现代版本的 git!请参阅 Malvineous 的解决方案,below

在此转载:

git remote set-url origin --push --add <a remote>
git remote set-url origin --push --add <another remote>

原答案:

这是我已经使用了很长一段时间而没有产生不良后果的东西,Linus Torvalds 在 git mailing list 上提出了建议。

araqnid 的解决方案是将代码引入您的存储库的正确解决方案……但是当您像我一样拥有多个等效的权威上游(我将一些更重要的项目克隆到私有上游、GitHub 和 Codaset)时,它可以是每天对每个人都进行更改是一种痛苦。

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

[remote "GitHub"]
    url = git@github.com:elliottcable/Paws.o.git
    fetch = +refs/heads/*:refs/remotes/GitHub/*
[branch "Master"]
    remote = GitHub
    merge = refs/heads/Master
[remote "Codaset"]
    url = git@codaset.com:elliottcable/paws-o.git
    fetch = +refs/heads/*:refs/remotes/Codaset/*
[remote "Paws"]
    url = git@github.com:Paws/Paws.o.git
    fetch = +refs/heads/*:refs/remotes/Paws/*

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

[remote "Origin"]
    url = git@github.com:Paws/Paws.o.git
    url = git@codaset.com:elliottcable/paws-o.git

完成此操作后,当我 git push Origin Master 时,它将依次推送到 Paws/MasterCodaset/Master,让生活更轻松一些。


git config -e 在您的首选编辑器中打开 .git/config 文件。
以防万一。确认有一个带有 2 个 url 的遥控器仍然可以在 1.7.12.4 上完成这项工作。谢谢。
我将“origin”远程命名为“all”以使其语义更清晰
@JamesWomack 请参阅下面的@Malvineous 的回答。现在它“更正确”了,因为 git 的命令行使用 git remote set-url ... --add 本机支持这一点。
[branch "Master"] 下设置 remote = Origingit pull 将使用两个遥控器。
A
Arsen Khachaturyan

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

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

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

git remote update

如果它当前未连接到其中一个遥控器,则会超时或抛出错误,然后继续下一个。您必须从获取的存储库或 cherry-pick 手动合并,具体取决于您希望如何组织收集更改。

要从 alt 中获取 master 分支并将其拉入当前的 head,请执行以下操作:

git pull alt master

所以实际上 git pull 几乎是 git pull origin HEAD 的简写(实际上它在配置文件中查看以确定这一点,但你明白了)。

要推送更新,您必须手动对每个 repo 执行此操作。我认为,推送的设计考虑了中央存储库工作流程。


所以你说的是“git remote add foo ssh://foo.bar/baz”创建了一个速记形式,但我仍然需要用“git pull”循环它们,或者用“git”循环它们合并”(这里的语法是什么,在“git remove update”之后?)这个简写名称是否也适用于“git push”?即我不能“git push foo”等(循环)吗?谢谢
“git pull”基本上是“git fetch”,然后是“git merge”。 “git remote update”只是为你做了一堆“git fetch”调用。所以剩下的就是做“git merge”位。您可以说“git merge origin/master”,它会将原始版本的 master 合并到您当前的 HEAD 中。 “git pull origin master” 做同样的事情,虽然它会先做一次提取(如果你已经完成了 git remote update,那将没有更多的东西要提取,所以它是多余的)。是的,你可以说“git push foo”,它会将所有匹配的分支推送到名为“foo”的远程。
显然,您也可以一次推送多个存储库,请查看此答案以获取更多详细信息stackoverflow.com/questions/14290113/…
D
Drew Noakes

自 git 1.8(2012 年 10 月)以来,您可以从命令行执行此操作:

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。


我强烈建议不要使用此解决方案。我们已经在我们的公司中使用过它,并且遇到了严重的问题,钩子在一个存储库中失败,但在另一个存储库中却没有。变更集只存在于一个存储库中。
@MichaelSchmeißer:大概您可以在推送时看到错误消息,解决问题,然后再次推送以使所有内容恢复到干净状态?
问题是修复被拒绝的推送涉及更改已经推送到另一个仓库的提交。因此,如果有人在这些提交被修复时已经基于这些提交工作,那么事情就会变得非常糟糕,我们办公室就是这种情况。
啊,是的,这可能会变得很棘手。但是在我看来,这些钩子似乎需要重新设计。失败的推送不会正常破坏 git,因此引入新的故障点(这也会阻止您使用漂亮的 git 功能)可能不是最好的解决方案。当然,我在不知道您的要求是什么的情况下这么说...
不。自从写了我的问题以来,我已经阅读了其他网络帖子,然后测试了这个东西。通过阅读其他帖子,我怀疑只使用了第一行。我刚刚对此进行了测试:确实,git fetch 只检查了第一行中的 URL。 (鉴于此,我不明白没有 --pushgit remote set-url --add 的目的是什么。)
N
Nona Urbiz

我将这些别名添加到我的 ~/.bashrc 中:

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

这太棒了!我最终得到了一个 Git 别名:git config alias.pushall '!for i in git remote; do git push $i; done;'
我想我更喜欢别名解决方案来创建一个新的遥控器。另请参阅stackoverflow.com/questions/41372919/…
建议的小调整:alias pushall='for i in `git remote`; do echo "Pushing to " $i; git push $i; done;'
F
FelipeC

您可以添加遥控器:

git remote add a urla
git remote add b urlb

然后更新所有回购做:

git remote update

t
troex

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

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

A
Asclepius

此答案与之前的答案不同,因为它避免了在 git remoteset-url 命令中不必要和不对称地使用 --push 选项。这样,两个 URL 在其配置中是对称的。对于怀疑论者,cat ./.git/config 所示的 git 配置看起来与 withwithout 不同。

从第一个 URL 克隆:

git clone git@github.com:myuser/myrepo.git

查看当前遥控器:

$ git remote -v
origin  git@github.com:myuser/myrepo.git (fetch)
origin  git@github.com:myuser/myrepo.git (push)

添加第二个遥控器:

git remote set-url --add origin git@gitlab.com:myuser/myrepo.git

确认两个遥控器都列出了推送:

$ git remote -v
origin  git@github.com:myuser/myrepo.git (fetch)
origin  git@github.com:myuser/myrepo.git (push)
origin  git@gitlab.com:myuser/myrepo.git (push)

$ git config --local --get-regexp ^remote\..+\.url$
remote.origin.url git@github.com:myuser/myrepo.git
remote.origin.url git@gitlab.com:myuser/myrepo.git

依次推送到所有 URL:

git push

要删除遥控器:

git remote set-url --delete origin git@gitlab.com:myuser/myrepo.git

d
dstineback

我将两个单独的 pushurl 添加到 .git configfig 文件中的远程“原点”。当我运行 git push origin "branchName" 然后它将运行并推送到每个 url。不确定是否有更简单的方法来完成此操作,但这对我自己来说可以推送到 Github 源代码并同时推送到 My.visualStudio 源代码。

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

I
InteXX

我想在 VSO/TFS 中工作,然后在准备好后公开推送到 GitHub。在私有 VSO 中创建的初始存储库。当需要添加到 GitHub 时,我做了:

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

像冠军一样工作......

要进行完整性检查,请发出“git remote -v”以列出与项目关联的存储库。

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)

简单的方法,为我工作......希望这对某人有所帮助。


无缘无故运行 git push -f,例如 git push 失败或确切地知道自己在做什么,这是一个坏主意,可能有害。这也没有回答问题,而是如何添加第二个遥控器。
C
Community

我冒昧地从 nona-urbiz 扩展了 answer;只需将其添加到您的 ~/.bashrc 中:

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

用法:

git-pullall master

git-pushall master ## or
git-pushall

如果您没有为 git-pullall 提供任何分支参数,那么从非默认遥控器的拉取将失败;保留此行为,因为它类似于 git。


S
S. Hesam

好吧,如果您正在寻找一种同时推送多个遥控器的方法,那么您可能对 git 有足够的了解。我们在 git 中将远程仓库称为远程仓库。将更改推送到遥控器通常是开发周期的一部分。

有时,您可能需要将更改推送到多个遥控器,例如 GitHub、bitbucket 等。为此,您可以按照给定的说明进行操作。

列出您现有的遥控器

您可以使用以下命令列出所有可用的遥控器。

git remote -v

假设您还没有配置任何(其他)远程。您可以使用 git 遥控器来执行此操作。

git remote add  remote_name  remote_url

例子:

git remote add github https//github.com/path/to/repo

通常,我们通过默认来源(例如 git push origin)寻址远程名称来推送更改。您可以配置组多个遥控器并为其命名。因此,您通过引用该名称来推送所有这些遥控器。

您可以使用 git remote 或 git config 命令或编辑配置文件来添加多个遥控器。

由于 git 可以对多个遥控器进行分组,您可以按照以下任意一种方式来配置多个遥控器同时推送(无需全部)。

使用 git remote 添加遥控器

您可以使用 git remote 将多个远程 URL 设置为单个远程。

如果您还没有名为“all”的遥控器,请使用 git remote add 创建它,然后使用 git remote set-url –add 将新 URL 添加到现有遥控器。

git remote add all <remote URL>

然后

git remote set-url  -–add  all  <another remote URL>

您可以使用 git remote -v 交叉检查添加的新遥控器。

(或者)

使用 git config 对多个遥控器进行分组

git config 命令用于配置 git 参数。它将编辑 .git/config 文件作为给定的输入。

git config –add remote.all.url  https//domain.com/repo.git
git config –add remote.all.url  ssh://user@host/repos/repo.git

注意不带–add 选项的命令将替换现有的远程URL。您可以在 .git/config 验证更新的配置。

(或者)

如果您知道配置格式,请编辑文件 .git/config 以添加远程和多个远程 URL。

现在您可以通过引用分配了多个远程 URL 的远程名称来同时推送多个远程。

git push all master

您始终可以推送到多个远程存储库,而无需使用正式的 bash 语法对它们进行分组。

git push server master && git push github master

J
Jeff Ferland

您需要一个脚本来循环它们。 Git 不提供“全部推送”。理论上,您可以在多个线程中进行推送,但本机方法不可用。

Fetch 更加复杂,我建议线性进行。

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


问题是,正如我所描述的,没有中央始终可用的盒子。如果我必须编写一个循环的 bash 脚本,那就这样吧,但是分布式 VC 在这里对我没有更多帮助,这感觉很有趣……
作为分布式,它假设不是每个人都可用,或者想要被推送到。它还涉及处于不同状态的不同存储库,以及其他人同时处理它们的假设。您从一组存储库中推送和拉取的顺序会影响不同存储库的状态,并且您必须进行多次传递才能真正同步它们。这就是为什么没有“拉/推所有”的原因。然后是冲突... ;)
C
Community

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

莱纳斯的声明

可悲的是,甚至没有任何方法可以用 git 别名来伪造它。

elliottcable's answer 中的 Git mailing list 的引用条目中不再为真。

git fetch 在过去某处学习了 --all 参数,允许一次性获取所有遥控器。

如果不是全部请求,可以使用 --multiple 开关来指定多个遥控器或一个组。


d
dhirajforyou

使用以下命令为全局 gitconfig(/home/user/.gitconfig) 添加别名。

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

一旦你提交代码,我们说

git 推送

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

git pushall

并且代码将更新到所有遥控器,包括原始遥控器。


F
Francisco Maria Calisto

添加 all 遥控器有点乏味,因为您必须在您使用的每台机器上进行设置。

此外,提供的 bashgit 别名 都假定您将推送到 all 遥控器。 (例如:我在 GitHub 和 GitLab 上维护了一个 sshag 的分支。我添加了 upstream 远程,但我没有向它推送的权限。)

这是一个 git 别名,它仅通过包含 @ 的推送 URL 推送到遥控器。

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

D
Dadaso Zanzane

添加新的遥控器

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

git remote -vv

从多个位置获取

git fetch --all

推送到位置

git push -u upstream/dev