将本地Git存储库推送到新的远程服务器,包括所有分支和标签


551

我有一个本地Git存储库,我想将其推送到新的远程存储库(如果需要的话,可以在Beanstalk上设置全新的存储库)。
我的本地存储区有几个分支和标签,我希望保留所有历史记录。

看来我基本上只需要做一个git push,但是只上传master分支。

如何推送所有内容,以便在远程计算机上获得本地存储的完整副本?


最短和最简单的答案-stackoverflow.com/a/39992258/6648326
MasterJoe2

Answers:


898

要推送所有分支,请使用其中一个(将REMOTE替换为远程名称,例如“ origin”):

git push REMOTE '*:*'
git push REMOTE --all

推送所有标签

git push REMOTE --tags

最后,我认为您可以使用以下命令在一个命令中完成所有操作:

git push REMOTE --mirror

但是,此外--mirror,还会推动您的遥控器,因此这可能并不是您想要的。


53
--all而不是*:*看起来更友好
Idan K

56
我的天啊……..我撕毁了整个互联网,我发现`--all`开关是我需要的AAAAALLLLLLLLLLLLLLLL!
拉基布

21
只是注意到git push REMOTE --all返回No refs in common and none specified;什么都不做,而git push REMOTE "*:*实际上却将所有分支推到了远端。
Im0rtality

10
使用--dry-run检查会发生什么情况,以防您真正不想在REMOTE中进行本地更新的“ tmp”或“功能”分支
Jonno 2014年

55
如果原始遥控器仍然可用,那是个不错的主意git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-url
苏珊·杜彭(SuzanneDupéron)

156

在像我这样的情况下,您购买了一个回购协议,现在正在将远程源切换到另一个回购协议,即一个新的空仓库...

因此,您具有仓库和所有分支,但是您仍然需要检出这些分支,以使git push --all命令也能实际推送这些分支。

您应在执行以下操作之前执行此操作:

for remote in `git branch -r | grep -v master `; do git checkout --track $remote ; done

其次是

git push --all

4
这也非常有帮助,因为我必须手动检出所有分支。这对下一次很好。
2012年

10
奇怪的是,git push '*:*'推了所有分支。git push -all刚推高手。我正在将回购从github传输到bitbucket。
jerrymouse13 2013年

3
不必检查每个分支,而应该执行“ git branch --track $ remote”。在庞大的回购中,检查旧分支需要一些时间
Moataz Elmasry 2014年

2
为此,我必须进行一些小的更改:--track remotes/$remote而不是--track $remote。这是完整的命令行:for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
Adrian T

谢谢,它对我有用,上面的答案也不起作用。
本雅明·贾法里

90

这是同一件事的另一种选择,对于我当时所处的情况更有效。它解决了您拥有多个远程站点的问题,希望将所有分支克隆source到远程站点destination,而不必事先检查所有分支。

(我的Daniel解决方案存在的问题是,source如果我以前已经签出过它,它将拒绝从远程签出跟踪分支,即,在推送之前它不会更新本地分支)

git push destination +refs/remotes/source/*:refs/heads/*

注意:如果您不使用直接CLI,则必须转义星号:

git push destination +refs/remotes/source/\*:refs/heads/\*

这会将所有远程分支推source到中的head分支destination,可能会进行非快进推送。您仍然必须单独推送标签。


8
+1这对我有用,从一个克隆remote到另一个克隆。谢谢!
劳伦斯

4
我不得不躲避星号:git push destination +refs/remotes/source/\*:refs/heads/\*
mattalxndr 2014年

2
对我来说,这很容易推动一个名为HEAD的分支,在这种情况下,我认为这不是故意的。
maxwellb '16

1
这个答案对我非常有用。git-push(1)手册页中唯一提到的星号用法是该--prune选项的一个小例子。
laindir '16

4
出色的答案,与--mirror大家推荐的通常参数大不相同。非常适合于您只想使两个遥控器保持自动化或审核目的的情况。
Vinicius Xavier

15

如果目的地为空,这是我找到的最简洁的方法。切换到一个空文件夹,然后:

# Note the period for cwd >>>>>>>>>>>>>>>>>>>>>>>> v
git clone --bare https://your-source-repo/repo.git .
git push --mirror https://your-destination-repo/repo.git

替换https://...file:///your/repo等中的。


13

的联机帮助页git-push值得一读。结合这个网站,我在自己的文章中写了以下内容.git/config

[remote "origin"]
    url = …
    fetch = …
    push = :
    push = refs/tags/*

push = :手段“推动任何‘匹配’分支(即已经存在于远程仓库,并有当地合作即分行)”,而push = refs/tags/*表示“推动所有标签”。

所以现在我只需要跑步 git push即可推送所有匹配的分支和所有标签。

是的,这并不是OP想要的(要推送的所有分支必须已经存在于远程端),但是对于那些在搜索“我如何同时推送分支和标签时发现此问题”的人可能会有所帮助时间”。


13

就我而言,有效的是。

git push origin --all

4
简单容易。有用!origin是远程URL Git存储库的别名。
做Nhu Vy

8

镜像存储库

创建存储库的裸克隆。

git clone --bare https://github.com/exampleuser/old-repository.git

镜像推送到新存储库。

cd old-repository.git
git push --mirror https://github.com/exampleuser/new-repository.git

删除您在步骤1中创建的临时本地存储库。

cd ..
rm -rf old-repository.git

镜像包含Git大文件存储对象的存储库

创建存储库的裸克隆。将示例用户名替换为拥有存储库的人员或组织的名称,然后将示例存储库名称替换为要复制的存储库的名称。

git clone --bare https://github.com/exampleuser/old-repository.git

导航到刚克隆的存储库。

cd old-repository.git

引入存储库的Git大文件存储对象。

git lfs fetch --all

镜像推送到新存储库。

git push --mirror https://github.com/exampleuser/new-repository.git

将存储库的Git大文件存储对象推送到镜像。

git lfs push --all https://github.com/exampleuser/new-repository.git

删除您在步骤1中创建的临时本地存储库。

cd ..
rm -rf old-repository.git

以上说明来自Github帮助:https : //help.github.com/articles/duplicating-a-repository/


1
虽然从理论上讲这可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。有关如何编写更好的 “基于链接的”答案的说明,请参见此处。谢谢!
GhostCat

5

我发现上述答案仍有一些不清楚的地方,这会误导用户。首先,确保git push new_origin --all并且git push new_origin --mirror不能复制所有原始分支,它只是将本地现有分支复制到new_origin。

以下是我测试过的两种有用的方法:

1,通过克隆裸仓库重复。git clone --bare origin_url,然后进入文件夹git push new_origin_url --mirror。通过这种方式,您也可以同时使用和git clone --mirror origin_url--bare--mirror下载一个裸仓库,不包括工作区。请参考这个

2,如果您使用来创建git repo git clone,这意味着您有裸露的repo和git工作区,则可以使用git remote add new_origin new_origin_url,然后使用,git push new_origin +refs/remotes/origin/\*:refs/heads/\*然后git push new_origin --tags

这样,您将获得一个多余的head分支,这毫无意义。


2

推送分支和标签(但不推送):

git push origin 'refs/tags/*' 'refs/heads/*'

这等同于组合的--tags--all选项git push,而git似乎不允许这样做。


是否有其他选择可以从另一个遥控器推送?例如+refs/remotes/source/*
伊夫·马丁

2

基于@Daniel的答案,我做了:

for remote in \`git branch | grep -v master\`
do 
    git push -u origin $remote
done

2
更好的是,| grep -v master可以将其替换为| sed 's/\*//'(我假设您已被排除在外,master以避免*当前选择的分支之前出现一些讨厌的内容),它可以让您包括非当前选择的分支,master并避免出现任何问题master。同样为您的尸体发布而感到抱歉,只是今天这个答案对我有所帮助,我想分享我的修改,如果它可以帮助其他人保持我的位置……
ToVine

1

我发现这些似乎都不适合我。随意将其杀死,但由于某些原因无法使其他选项正常工作。

预期结果是回购“克隆”到另一个远程服务器(例如,从Github到另一个提供商):

  • 所有分支均在新遥控器上创建
  • 所有分支历史均在新的远程上创建
    • (在我尝试过的每个解决方案中都错过了此功能)
  • 所有标签均在新遥控器上创建
  • 源移动(给定)
  • 非破坏性(使--mirror选项暂停)

我看到的主要问题是没有在新的遥控器中重新创建所有远程分支。如果有命令,则新的远程控制器没有分支历史记录(即执行操作git checkout branch; git log不会显示预期的分支提交)。

我注意到git checkout -b branchnamegit checkout branchname(后者是我所需要的)不同。我注意到git checkout --track branchname似乎没有拉分支历史。

我的解决方案(基于Powershell):

Function Git-FetchRemoteBranches {
$originalbranch = (git symbolic-ref HEAD).split("/")[-1]

Foreach ($entry in (git branch -r)) {

If ($entry -like "*->*") {
  $branch = $entry.split("->")[2].split("/")[1]
}
  else {$branch = $entry.split("/")[1]}

Write-Host "--Trying git checkout " -NoNewline
Write-Host "$branch" -Foreground Yellow

git checkout $branch

Remove-Variable branch -Force

""}

#Switch back to original branch, if needed
If ( ((git symbolic-ref HEAD).split("/")[-1]) -ne $originalbranch) {
"Switching back to original branch"
git checkout $originalbranch
Remove-Variable originalbranch -Force
}
}

git clone http://remoterepo
cd remoterepo
Git-FetchRemoteBranches
git remote add newremote
git push newremote --all
git push newremote --tags #Not sure if neeeded, but added for good measure

1

下面的命令将推送所有分支(包括您从未检出但存在于git repo中git branch -a的分支,您可以通过查看它们

git push origin '*:*'

注意:当您迁移版本控制服务时(即从Gitlab迁移到GitHub),此命令非常方便。


1
在版本控制服务之间迁移,这正是我正在寻找的东西,加油!
LukaŠpoljarić,

1

我正在从一种版本控制服务切换到另一种版本控制服务的过程中,需要克隆所有存储库,包括所有分支,标签和历史记录。

为了达到上述目的,我接下来要做的是:

  • 手动检出所有分支到本地存储库(检出所有脚本的脚本如下所示),
  • git push origin '*:*'

.sh脚本,用于签出本地存储库的所有分支:

for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
   git branch --track ${branch#remotes/origin/} $branch
done
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.