简述: 是否有一种方法可以让 git 仓库推送和拉取多个远程仓库的列表(而不是单个的“origin”)?
详述: 我经常遇到这样的情况:在多台电脑上开发应用程序,网络连接方式也不同——比如在运输中使用笔记本电脑,在某个位置使用计算机“A”,在另一个位置使用计算机“B”。此外,笔记本电脑可能只与“A”或“B”之一连接,并且有时两者都连接。
我想做的是让 git 总是从它当前可以连接到的所有电脑上 “pull” 并 “push”,这样更容易从一台机器跳转到另一台机器并继续无缝工作。
简述: 是否有一种方法可以让 git 仓库推送和拉取多个远程仓库的列表(而不是单个的“origin”)?
详述: 我经常遇到这样的情况:在多台电脑上开发应用程序,网络连接方式也不同——比如在运输中使用笔记本电脑,在某个位置使用计算机“A”,在另一个位置使用计算机“B”。此外,笔记本电脑可能只与“A”或“B”之一连接,并且有时两者都连接。
我想做的是让 git 总是从它当前可以连接到的所有电脑上 “pull” 并 “push”,这样更容易从一台机器跳转到另一台机器并继续无缝工作。
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
更新远程仓库(即pull
的情况)变得更加容易了。
Linus在引用条目中说:
不幸的是,甚至没有任何方法可以通过git别名来伪造它。
这段话在Git邮件列表中的引用已经不再适用,详情请参考elliottcable的回答。
git fetch
在过去学会了--all
参数,允许一次性获取所有远程仓库。
如果不需要全部请求,则可以使用--multiple
开关来指定多个远程仓库或一个组。
您需要编写一个脚本来循环处理它们。Git没有提供“全部推送”的功能。理论上,您可以在多个线程中进行推送,但没有本地方法可用。
Fetch更加复杂,我建议按顺序执行。
我认为最好的答案是有一台机器,每个人都可以推送/拉取,如果可能的话。
在Git的最新版本中,您可以为给定的远程添加多个pushurl。使用以下命令将两个pushurl添加到您的origin:
git remote set-url --add --push origin git://original/repo.git
git remote set-url --add --push origin git://another/repo.git
$ git clone git://original/repo.git
$ git remote -v
origin git://original/repo.git (fetch)
origin git://original/repo.git (push)
$ git config -l | grep '^remote\.'
remote.origin.url=git://original/repo.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
$ git remote add all git://original/repo.git
$ git remote -v
all git://original/repo.git (fetch) <-- ADDED
all git://original/repo.git (push) <-- ADDED
origin git://original/repo.git (fetch)
origin git://original/repo.git (push)
$ git config -l | grep '^remote\.all'
remote.all.url=git://original/repo.git <-- ADDED
remote.all.fetch=+refs/heads/*:refs/remotes/all/* <-- ADDED
然后,我们可以向所有远程仓库添加一个 pushurl ,指向另一个代码库:
$ git remote set-url --add --push all git://another/repo.git
$ git remote -v
all git://original/repo.git (fetch)
all git://another/repo.git (push) <-- CHANGED
origin git://original/repo.git (fetch)
origin git://original/repo.git (push)
$ git config -l | grep '^remote\.all'
remote.all.url=git://original/repo.git
remote.all.fetch=+refs/heads/*:refs/remotes/all/*
remote.all.pushurl=git://another/repo.git <-- ADDED
这里git remote -v显示了新的pushurl用于推送,所以如果您执行git push all master,则只会将主分支推送到git://another/repo.git。这展示了pushurl如何覆盖默认的url(remote.all.url)。
现在让我们添加另一个指向原始仓库的pushurl:
$ git remote set-url --add --push all git://original/repo.git
$ git remote -v
all git://original/repo.git (fetch)
all git://another/repo.git (push)
all git://original/repo.git (push) <-- ADDED
origin git://original/repo.git (fetch)
origin git://original/repo.git (push)
$ git config -l | grep '^remote\.all'
remote.all.url=git://original/repo.git
remote.all.fetch=+refs/heads/*:refs/remotes/all/*
remote.all.pushurl=git://another/repo.git
remote.all.pushurl=git://original/repo.git <-- ADDED
我们添加的两个pushurls都被保留。现在,使用单个git push all master命令,就可以将主分支推送到git://another/repo.git和git://original/repo.git。
重要提示:如果你的远程库有不同的规则(钩子)来接受或拒绝推送,则其中一个远程库可能会接受它,而另一个则不会。因此,如果您希望它们具有完全相同的历史记录,您需要在本地修复提交,使它们可被两个远程库接受并再次推送,否则您可能会面临只能通过重写历史记录(使用push-f)来修复它的情况,并且这可能会对已经从库中拉取了您之前的更改的人造成问题。
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
来更新所有的远程仓库,包括主仓库。
all
远程有点繁琐。此外,提供的bash
和git
aliases都假设您将推送到all remotes。(例如:我在GitHub和GitLab上维护一个sshag
的fork,我添加了upstream远程,但我没有权限推送到它。)这里是一个git
alias,只会推送URL包含@
的远程。psall = "!f() { \
for R in $(git remote -v | awk '/@.*push/ { print $1 }'); do \
git push $R $1; \
done \
}; f"
git remote add upstream https://github.com/example-org/example-repo.git
git remote -vv
git fetch --all
git push -u upstream/dev
git
功能,包含在malvineous的下面的答案中,被认可的答案是不正确的。 - ELLIOTTCABLE