将一个远程仓库的所有分支推送到另一个远程仓库

86

我有两个远程库:upstream和origin。upstream是我无法推送到的,而origin则是我的自己的存储库。如何从upstream获取所有分支,然后将它们推送到origin? 我尝试过:

git fetch upstream
git push --all origin

但它不起作用。


使用“git remote show”验证远程URL。 - Gregg
1
这个能帮到你吗? - Christophe
8个回答

100

我只需要将一个Bitbucket仓库复制到GitHub上,以下是步骤,假设您的远程仓库名为origin,所有分支和标签都将被复制:

git remote add neworigin url-to-new-remote
git push neworigin --tags "refs/remotes/origin/*:refs/heads/*"

好的一点是,这样您工作副本中的文件不会被修改。


2
需要使用 --force 吗?或者加上 --tags 来包含它们? - David Tchepak
1
@DavidTchepak 是的,你说得对。--force 不是必需的,在我的情况下是因为目标仓库中有冲突的代码。而且,--tags 会复制标签。我已经更新了我的答案。谢谢。 - jose.arias
12
我喜欢这个回答适用于已经检出的存储库。我唯一看到的不足是它将“HEAD”推送为一个分支到远程仓库,除了本地分支和远程分支。 - Nejuf
4
最终,有一个可行的答案,它不需要在本地创建所有远程分支,也不需要特殊的“bare(裸)”克隆或“mirror(镜像)”克隆。 - Ed Randall
5
在没有引用符的情况下,出现错误zsh: no matches found: refs/remotes/origin/*:refs/heads/*,直到我将refspec放在引用符中,例如""refs/remotes/origin/*:refs/heads/*" - Stefano
显示剩余6条评论

85

你可以尝试使用--mirror选项克隆上游代码库,然后再使用--mirror选项将其推送到新的远程代码库中。

你将拥有以下流程:

git clone <upstream-repo-url/repo.git> --mirror
cd <repo>
git remote add <your-remote-name> <your-remote-url/repo.git>
git push <your-remote-name> --mirror

请注意,push --mirror 命令会删除在你的 <your-remote-name> 上的分支,请谨慎操作。


14
请注意使用 push --mirror 命令,它会删除在你的<your-remote-name>上的分支。 - Pavel Rogovoy
如果您不想创建克隆,只想从当前的存储库中工作,您该怎么做? - David Ammouial
第二行给了我一个错误 fatal: not a git repository (or any parent up to mount point /) - Toby 1 Kenobi
1
看起来我需要先进入克隆的代码库,使用 cd 命令。 - Toby 1 Kenobi
@DavidAmmouial,如果您已经克隆了上游存储库,只需执行最后两个步骤即可。但是我猜如果您想从本地存储库工作,那么只需要按照标准的git工作流程,在本地执行它们并将它们推送到远程,与初始问题无关,或者我错过了什么? - Nicko Glayre
你是对的@NickoGlayre,原问题确实提到了本地克隆。 - David Ammouial

14

将一个(裸的)仓库完全克隆到另一个(裸的)仓库,包括所有分支,而不仅仅是已检出的分支的完整答案是通过克隆本地裸仓库作为中间件来实现。然后,在克隆的过程中,所有分支都会被拉取,并且使用 git push --all 命令可以将它们全部推送。以下示例在 Windows 上从 github 到 gitlab 执行:

  1. git clone --bare git@github.com:robe070/cookbooks.git
  2. cd cookbooks.git
  3. git remote add gitlab git@gitlab.com:robe071/cookbookstest2.git
  4. git push --force --all gitlab
  5. git push --force --tags gitlab

结果:25 个分支被推送到 gitlab。

注意,对于所有分支来说,都不需要 git checkout 命令,因为它对于裸仓库也没有意义。


1
我们的需求是将一个内部托管的git仓库移动到GitLab上。由于我们的仓库在防火墙外不可见,因此我们无法使用GitLab.com上的导入或拉取镜像选项。我们还有一个选择可以使用GitLab社区版,其中我们可以使用导入功能,但最大仓库会超过3小时限制。而且GitLab CE中没有可用的拉取镜像功能。因此,上述选项始终有效,因为它仅依赖于git功能。 - RobG
我建议不要使用--force,除非你绝对确定需要它。否则这正是我在寻找的! - Lars Nyström

9

当你执行git push <REMOTE> --all或者git push <REMOTE> --tags时,所有的分支和标签都将从你的本地历史推送到远程仓库。如果你想要把一个远程仓库(比如origin)中的所有分支和标签(不仅仅是你的本地历史)推送到另一个远程仓库(比如upstream),请按照以下步骤进行操作:

  1. Recieve all branches and tags from the origin and remove unmatched branches in your local history with the origin remote:
    • git fetch --prune
      
    • git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
      
    • git fetch --all
      
  2. Add new remote url:
    • git remote add upstream <the-url-path-of-a-remote.git>
      
  3. Now, your local is synchronized. Next, you can push all of the branches and tags to the new remote:
    • git push --all upstream
      git push --tags upstream
      

简洁概括

git fetch --prune
git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
git fetch --all
git remote add upstream <the-url-path-of-a-remote.git>
git push --all upstream
git push --tags upstream

2
您可以将以下命令作为bash脚本运行,第一个输入为您现有的源代码库,第二个输入为您的目标代码库。
mkdir migrate
git clone $1 migrate
cd migrate
git fetch origin
git remote add new-origin $2
git push -u new-origin --all
git push new-origin --tags
git remote set-head origin -d
git push new-origin refs/remotes/origin/*:refs/heads/*

这里假设您已经创建了目标仓库。

1

UI方法:
您也可以通过Github.com的用户界面进行此操作-私有和公共存储库都可以。

  1. 在github.com的组织中创建一个新的存储库 - 单击绿色的“创建存储库”按钮Create new Repo Screen

  2. 在下一个屏幕上,列出的最后一个选项可让您将旧的存储库克隆到Github。 (请参见蓝色突出显示部分)Select Repository Source

  3. 接下来,请按如下方式输入您的旧的bitbucket repo url。
    (是的,私人repo也可以 - 继续阅读 - 下一步是授权:p)Old repo url in bitbucket

  4. 最后,它会要求您输入登录凭据,输入它们并去冲杯咖啡。 老实说,这不会花费很长时间。Who might you be sir?

BAM - 完成了。个人而言,我只使用CLI + Mirror,这是在这里具有讽刺意味的被接受的答案,但我的团队中的一位开发人员最近问我这个问题,所以我认为提供另一种选择会很有帮助。


0
如果在存储库中已将“upstream”添加为远程仓库,则无需显式检出所有分支即可执行以下操作:
git fetch -pPt upstream
git push origin --tags "refs/remotes/upstream/*:refs/heads/*"

如果你不想推送标签,那么请移除--tags选项。

-5
希望这可以帮到你:
git remote add your-new-origin url-to-repo/repo.git
git push --all your-new-origin //pushes all branches
git push --tags your-new-origin //pushes all tags

7
这将仅推送已在本地检出的分支,它不会拉取任何分支。 - RobG

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