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

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

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

如何推送所有内容,以便在遥控器上获得本地存储库的完整副本?

308076 次浏览

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

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

要推送所有的标签

git push REMOTE --tags

最后,我认为你可以在一个命令中完成这一切:

git push REMOTE --mirror

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

在像我这样的情况下,您购买了一个存储库,现在正在将远程源切换到另一个存储库,一个新的空存储库…

所以你有你的repo和里面的所有分支,但是你仍然需要为git push --all命令签出这些分支来实际推送它们。

您应该在推送之前执行此操作:

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

其次是

git push --all

这是对同样的事情的另一种看法,它更适合我所处的情况。它解决了您有多个遥控器的问题,希望将远程source中的所有分支克隆到远程destination,但无需事先检查它们。

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

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

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

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

这会将远程source中的所有分支推送到destination中的头分支,可能会进行非快进推送。你仍然需要单独推送标签。

git-push的手册值得一读。结合本网站,我在我的.git/config中写了以下内容:

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

push = :表示“推送任何'匹配'分支(即已经存在于远程存储库中并且具有本地对应物的分支)”,而push = refs/tags/*表示“推送所有标签”。

所以现在我只需要运行git push来推送所有匹配的分支和所有标签。

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

基于@陈志立答案我做了:

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

要推送分支和标签(但不是远程):

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

这相当于将git push--tags--all选项组合在一起,这似乎是git不允许的。

我发现上面的答案仍然有一些不清楚的地方,这会误导用户。首先,可以肯定的是git push new_origin --allgit 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 clone有一个git仓库,这意味着你有裸仓库和git工作区,你可以使用git remote add new_origin new_origin_url,然后git push new_origin +refs/remotes/origin/\*:refs/heads/\*,然后git push new_origin --tags

通过这种方式,你会得到一个额外的头部分支,这是没有意义的。

在我的情况下,有效的是。

git push origin --all

这是我找到的最简洁的方式,前提是目标是空的。切换到一个空文件夹,然后:

# 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等。

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

预期结果是“克隆”到另一个远程仓库(即从Github到另一个提供商):

  • 所有分支都在新的远程上创建
  • 所有分支历史记录都在新远程创建
    • (我尝试过的每个解决方案都错过了这一点)
  • 所有标签都在新的遥控器上创建
  • 源移动(给定)
  • 非破坏性的(暂停--镜像选项)

我看到的主要问题是所有远程分支都没有在新远程中重新创建。如果命令做了,新远程没有分支历史记录(即执行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

镜像存储库

创建存储库的裸克隆。

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/

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

git push origin '*:*'

注意:当您迁移版本控制时,此命令会派上用场 服务(#E YZ 0)

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

为了实现上面的目标,我接下来做了:

  • 手动签出所有分支到本地存储库(下面显示了签出所有分支的脚本),
  • 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

我最喜欢(最简单)的方式

git clone --mirror  OLD_GIT_URL
cd  NEW_CREATED_FOLDER
git remote add NEW-REMOTE NEW_GIT_URL
git push  NEW-REMOTE --mirror

每次我谷歌如何做到这一点,我最终都会读到同样的帖子,但它并没有让我到达我需要的地方,所以希望这也能帮助我未来的自己和他人。

我启动了一个新的本地项目,我想将其推送到我的存储库(BitBucket)。这是我所做的:

  1. 导航到我的本地项目根
  2. 开始:git init
  3. 添加所有文件:git add .
  4. 提交:git commit -m "Initial commit"
  5. 转到我的存储库(BitBucket)
  6. 创建新的存储库:new_project
  7. 回到我当地的项目
  8. 添加遥控器:git remote add origin git@bitbucket.org:AndrewFox/new_project.git
  9. 推送提交:git push origin master -f

-f标志是强制推送,否则它将识别两个存储库不同并失败。

我找到了最好和最简单的方法https://www.metaltoad.com/blog/git-push-all-branches-new-remote,对我来说就像一个魅力,它将把所有标签和分支从源推到新的远程:

git remote add newremote new-remote-url


git push newremote --tags refs/remotes/origin/*:refs/heads/*

我使用了'git ush--all-u newRemote',但它只将签出的分支推送到newRemote。

Git:将所有分支推送到一个新的远程

作者:Keith Dechant,软件架构师

这是你们中的一些人在使用Git时可能遇到的场景 存储库。你有一个Git存储库的工作副本,比如从一个旧的 服务器。但你只有工作副本,而来源不是 容易接近。所以你不能只是分叉。但你想把整个 存储库和所有分支历史记录到您的新远程。

如果您的工作副本包含跟踪分支,这是可能的 从旧的远程(起源/分支1、起源/分支1等)。如果您这样做, 你有整个回购和历史。

然而,在我的情况下,有几十个分支,和一些或全部 我从来没有在当地检查过。把它们都推出去似乎是一种

那么,接下来该怎么做呢?

我确定了两个选项:

选项1:检查每个分支并推送我可以这样做,我可以 甚至写一个Bash脚本来帮助。然而,这样做会改变我的 工作文件与每个签出,并将创建一个本地分支 每个远程跟踪分支。这将是缓慢的一个大 仓库。

选项2:在不更改工作副本的情况下推送 替代方案,不需要每个分支的签出,不需要 在工作副本中创建无关的分支,甚至 修改工作副本中的文件。

如果您的旧的、不再活动的遥控器称为“oldremote”并且您的 新的遥控器被称为“新遥控器”,您可以只推送遥控器 使用此命令跟踪分支:

git push newremote refs/remotes/oldremote/*:refs/heads/*

在某些 情况下,也可以只推送分支的子集。如果 分支名称以斜杠命名空间(例如, oldremote/特征/分支3,oldremote/特征/分支4等),您可以 仅推送名称以 "旧的远程/功能":

git push newremote refs/remotes/oldremote/features/*:refs/heads/features/*

无论你 推送所有分支或只是其中的一部分,Git将执行 整个操作而不创建任何新的本地分支,并且没有 对您的工作文件进行更改。每个跟踪分支 匹配您的模式将被推送到新的遥控器。

有关该主题的更多信息,请查看Stack上的此线程 溢出。

发布日期:2017年10月9日

做你想做的事情的主要方法是使用--all--tags标志。省略其中任何一个都不会推送你想要的部分。不幸的是,它们不能一起使用(不明白为什么),所以它们必须一个接一个地运行。

git push --all
git push --tags

另一个相关的选项是--prune选项,它删除远程上本地不存在的任何分支/标签。

或者,考虑--mirror选项,因为它基本上等同于--all --tags --prune

git push --mirror

这是我在将本地Git存储库推送到新远程时解决的问题,包括所有分支和标签

  • git clone--镜像旧仓

  • cd

  • git远程添加新的新建仓库

  • git ush新的--镜像

运行以下命令将现有存储库移动到具有所有分支和标签的新远程:

cd existing_repo
git remote rename origin old-origin
git remote add origin git@<repo-url.git>
for remote in `git branch -r `; do git checkout --track remotes/$remote ; done
git push -u origin --all
git push -u origin --tags