能否用一个命令将代码推送到所有的git远程仓库?

260

不要这样做:

git push origin --all && git push nodester --all && git push duostack --all
有没有一种只需一个命令就可以完成的方法?谢谢 :)

1
参见:https://dev59.com/4W035IYBdhLWcg3wGMHa - Mark Longair
要创建一个“all”远程以将其推送到所有远程,请参见:https://dev59.com/f2855IYBdhLWcg3wlVca#18637593 - Édouard Lopez
7个回答

353

创建一个包含多个仓库URL的all远程:

git remote add all origin-host:path/proj.git
git remote set-url --add all nodester-host:path/proj.git
git remote set-url --add all duostack-host:path/proj.git

然后只需执行git push all --all命令。


这是在.git/config文件中的样子:

  [remote "all"]
  url = origin-host:path/proj.git
  url = nodester-host:path/proj.git
  url = duostack-host:path/proj.git

12
超酷的技巧!唯一的缺点是它不会移动远程分支。在执行此操作后,您需要立即运行 git fetch --all 命令。 - madhead
16
Torvalds先生(Git的创始人)提到他使用这种方法,但他表示仅仅是为了方便,没有技术优势。最终,即使是“git push all”也会对每个存储库进行一次连接,因此它实际上只是多次执行“git push”的速记方式。没有真正的技术优势,只是一种方便。 - Matt
26
这种方法的问题在于,随着新的URL变得可用,你需要将其添加到“all”远程中,而git remote | xargs -L1 git push --all将自动获取任何新的远程。 - khatchad
4
提示:如果您在提交时不想每次都输入 "all",只需使用 "origin" 代替 "all" 即可:git remote set-url --add origin nodester-host:path/proj.git - macabeus
1
这个答案的优点在于它是关于Git本身的。 - Samie Bencherif
显示剩余5条评论

341

推送所有分支到所有远程仓库:

git remote | xargs -L1 git push --all

或者如果你想将特定分支推送到所有远程端:

用你想要推送的分支替换master

git remote | xargs -L1 -I R git push R master

(奖励)创建一个用于该命令的 Git 别名:

git config --global alias.pushall '!git remote | xargs -L1 git push --all'

运行 git pushall 现在将会把所有分支推送到所有远程仓库。


2
非常好的且简单的解决方案。顺便说一下,你可以使用 xargs -l 代替 -L 1 ,-l 选项等同于 -L 1 。另外,有时我会在 git push 中加上 --all 。git remote | xargs -l git push --all - Tony
3
在OSX上我收到了xargs: illegal option -- l的错误提示。后来发现需要使用git remote | xargs -L1 git push命令。 - balupton
6
Git允许你调用自定义命令,只需将其放入一个文件中:1)这个文件在你的路径上;2)你有执行权限;3)命名为“git-[自定义名称]”(例如git-foo,git-push-all)。然后你就可以简单地输入“git [自定义名称]”(例如git foo,git push-all)来使用它。 - vowel-house-might
4
在Ubuntu系统上,执行man xargs命令可以看到,选项-l已经被弃用,因为它不符合POSIX规范。 - wjandrea
7
在Git别名语法中,“!”表示以下内容不是Git内部命令,而是外部shell命令。 - weakish
显示剩余5条评论

137
如果你想要一直将代码推送到repo1、repo2和repo3,但只从repo1拉取代码,请将远程版本库"origin"设置为:
[remote "origin"]
    url = https://exampleuser@example.com/path/to/repo1
    pushurl = https://exampleuser@example.com/path/to/repo1
    pushurl = https://exampleuser@example.com/path/to/repo2
    pushurl = https://exampleuser@example.com/path/to/repo3
    fetch = +refs/heads/*:refs/remotes/origin/*

在命令行配置:

$ git remote add origin https://exampleuser@example.com/path/to/repo1
$ git remote set-url --push --add origin https://exampleuser@example.com/path/to/repo1
$ git remote set-url --push --add origin https://exampleuser@example.com/path/to/repo2
$ git remote set-url --push --add origin https://exampleuser@example.com/path/to/repo3

如果您只想从repo1拉取,但对于特定分支specialBranch要推送到repo1repo2

[remote "origin"]
    url = ssh://git@aaa.xxx.com:7999/yyy/repo1.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    ...
[remote "specialRemote"]
    url = ssh://git@aaa.xxx.com:7999/yyy/repo1.git
    pushurl = ssh://git@aaa.xxx.com:7999/yyy/repo1.git
    pushurl = ssh://git@aaa.xxx.com:7999/yyy/repo2.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    ...
[branch "specialBranch"]
    remote = origin
    pushRemote = specialRemote
    ...

请参见https://git-scm.com/docs/git-config#git-config-branchltnamegtremote


6
我不确定为什么这个没有得到更多的投票。实际上,这非常方便,因为它允许您只需执行 git push 而无需任何参数。 - Husky
3
请投票给我! - Meng Lu
2
这对我来说似乎是更合适的方式。应该得到最高票数。 - Ahmad
1
非常有用。是否可以将pushurl限制为仅适用于主分支? - fbucek
1
我在原文章中已添加了回答,@fbucek。 - Meng Lu
对于那些使用后没有推送到repo1(主要的获取仓库)的人,请不要忘记也要使用git remote set-url --push --add origin命令来设置repo1。无论如何,使用git remote -v命令检查您的远程仓库。 - Muhammad Yasirroni

20
作为编辑.git/config文件的命令行界面替代方案,您可以使用以下命令:
# git remote add all origin-host:path/proj.git
# git remote set-url --add all nodester-host:path/proj.git
# git remote set-url --add all duostack-host:path/proj.git

同样的git push all --all命令也可以在这里使用。

你已经完成了与答案#1相同的操作。只不过你是通过命令行完成而非直接编辑配置文件。


2
我编写了一个简短的bash函数,可以一次性向多个远程仓库推送代码。你可以通过参数指定单个远程仓库、空格分隔的多个远程仓库或者不指定任何参数来将代码推送到所有远程仓库。这个函数可以添加到你的.bashrc或.bash_profile中。
function GitPush {
  REMOTES=$@

  # If no remotes were passed in, push to all remotes.
  if [[ -z "$REMOTES" ]]; then
    REM=`git remote`

    # Break the remotes into an array
    REMOTES=$(echo $REM | tr " " "\n")
  fi

  # Iterate through the array, pushing to each remote
  for R in $REMOTES; do
    echo "Pushing to $R..."
    git push $R
  done
}

例子:假设您的仓库有三个远程仓库:rem1、rem2和rem3。

# Pushes to rem1
GitPush rem1

# Pushes to rem1 and rem2
GitPush rem1 rem2

# Pushes to rem1, rem2 and rem3
GitPush

1
你可以使用 git hooks,特别是 pre-push:将非源推送添加到.git/hooks/pre-push中。

-1

如果您已经有一个现有的存储库,并且将origin作为默认远程,想要通过仅调用git push(或使用IDE /文本编辑器的git同步按钮)推送到多个远程存储库,请首先将当前的origin URL(用于所有操作,例如pushpullfetch)添加为特定于推送的远程源URL:

git remote set-url --push --add origin "$(git remote get-url --push origin)"

...然后将每个远程仓库添加到特定于push的URL中,如下所示:

git remote set-url --push --add origin "git@github.com:username/repo-name.git"

现在所有的获取和拉取操作只会从您的原始远程仓库中获取。

但是通过简单的git push,Git会将您最新的更改推送到您当前添加的所有远程仓库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接