【问题标题】:Push local Git repo to new remote including all branches and tags将本地 Git 存储库推送到新的远程,包括所有分支和标签
【发布时间】:2011-10-15 11:17:28
【问题描述】:

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

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

如何推送所有内容,以便在远程获取本地存储库的完整副本?

【问题讨论】:

    标签: git


    【解决方案1】:

    要推送all your branches,请使用以下任一方法(将 REMOTE 替换为遥控器的名称,例如“origin”):

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

    推送all your tags

    git push REMOTE --tags
    

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

    git push REMOTE --mirror
    

    但是,除了--mirror,还会推送你的遥控器,所以这可能不是你想要的。

    【讨论】:

    • --all 而不是*:* 似乎更友好
    • 我的上帝......我撕毁了整个互联网,我发现`--all`开关是我需要的AAAAALLLLLLLLLLLLLL!
    • 只是注意到git push REMOTE --all 返回了No refs in common and none specified; 什么都不做,而git push REMOTE "*:* 实际上将所有分支推到了远程。
    • 使用 --dry-run 来检查会发生什么,以防你在本地有“tmp”或“feature”分支,而你真的不想在 REMOTE 中更新
    • 如果原始遥控器仍然可用,最好使用git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-url
    【解决方案2】:

    在像我这样的情况下,您获得了一个 repo,现在正在将远程源切换到另一个 repo,一个新的空 repo...

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

    你应该在推送之前这样做:

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

    紧随其后

    git push --all
    

    【讨论】:

    • 这也很有帮助,因为我必须手动检查所有分支。这将是很好的下一次。
    • 奇怪的是,git push '*:*' 推送了所有分支。 git push -all 刚推高手。我正在将 repo 从 github 传输到 bitbucket。
    • 而不是检查每个分支,您应该只执行“git branch --track $remote”。在巨大的仓库中检查一个旧分支需要一些时间
    • 我必须做一些小改动才能让它工作:--track remotes/$remote 而不是 --track $remote。这是完整的命令行:for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
    • 谢谢,它对我有用,上面的答案也不起作用。
    【解决方案3】:

    这是对同一件事的另一种看法,它在我所处的情况下效果更好。它解决了您拥有多个遥控器的问题,希望将远程 source 中的所有分支克隆到远程 destination 但是无需事先检查所有内容。

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

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

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

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

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

    【讨论】:

    • +1 这对我有用,从一个remote 克隆到另一个。谢谢!
    • 我不得不避开星号:git push destination +refs/remotes/source/\*:refs/heads/\*
    • 对我来说,这最终推动了一个名为 HEAD 的分支,我认为在这种情况下不是故意的。
    • 优秀的答案,与大家推荐的通常--mirror 参数大不相同。非常适合您只想保持同步两个遥控器以实现自动化或审计目的的场景。
    • 谢谢,这在git push origin *:* 没有的地方有效,没有git clone --baregit clone --mirror,也没有循环来实现所有远程分支。移动存储库的最终命令:1) git clone oldurl 2) git remote set-url origin newurl 3) git push -u origin --tags 'refs/remotes/origin/*:refs/heads/*'
    【解决方案4】:

    就我而言,有效的是。

    git push origin --all
    

    【讨论】:

    • 简单易行。有用! origin 是远程 URL Git 存储库的别名。
    【解决方案5】:

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

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

    【讨论】:

    • 目前为止最简单的方法是处理所有分支和标签。谢谢!
    【解决方案6】:

    git-push 的联机帮助页值得一读。结合this website我在.git/config中写了以下内容:

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

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

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

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

    【讨论】:

      【解决方案7】:

      镜像存储库

      创建存储库的裸克隆。

      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/

      【讨论】:

      • 虽然理论上可以回答这个问题,it would be preferable 在这里包含答案的基本部分,并提供链接以供参考。有关如何编写更好“基于链接”的答案的说明,请参阅here。谢谢!
      【解决方案8】:

      我发现上面的答案还有一些不清楚的地方,会误导用户。首先,确定git push new_origin --allgit push new_origin --mirror 不能复制所有的起源分支,它只是将你本地存在的分支复制到你的new_origin。

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

      1,通过克隆bare repo复制。git clone --bare origin_url,然后进入文件夹,git push new_origin_url --mirror。这样你也可以使用git clone --mirror origin_url--bare--mirror都会下载一个bare repo ,不包括工作区。请参考this

      2,如果你有一个使用git clone的git repo,这意味着你有裸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分支,这没有任何意义。

      【讨论】:

        【解决方案9】:

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

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

        【讨论】:

          【解决方案10】:

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

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

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

          【讨论】:

            【解决方案11】:

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

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

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

            【讨论】:

            • 是否有其他选项可以从另一个遥控器推送?例如+refs/remotes/source/*
            【解决方案12】:

            基于@Daniel 回答我做了:

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

            【讨论】:

            • 更好的是,| grep -v master 可以替换为 | sed 's/\*//'(我假设您排除了 master 以避免在当前选择的分支之前出现讨厌的小 *),它允许您包括master 并在master 不是您当前选择的分支时避免任何问题。也很抱歉发布了 necroposting,只是今天这个答案对我有所帮助,如果它可以帮助我所在位置的其他人,我想分享我的修改......
            【解决方案13】:

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

            git push origin '*:*'

            注意:当您迁移版本控制时,此命令会派上用场 服务(即从 Gitlab 迁移到 GitHub

            【讨论】:

            • 在版本控制服务之间迁移,这正是我正在寻找的,干杯!
            【解决方案14】:

            我找到了最好和最简单的方法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 push --all -u newremote',但它只将签出的分支推送到 newremote。

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

            作者:软件架构师 Keith Dechant

            这是你们中的一些人在使用 Git 时可能遇到的场景 存储库。你有一个 Git 存储库的工作副本,比如来自旧的 服务器。但是您只有工作副本,而来源不是 无障碍。所以你不能只分叉它。但你想推整个 repo 和所有分支历史记录到你的新遥控器。

            如果您的工作副本包含跟踪分支,这是可能的 从旧遥控器(origin/branch1、origin/branch1 等)。如果你这样做, 你有完整的 repo 和历史记录。

            但是,在我的例子中,有几十个分支,部分或全部 他们我从来没有在本地检查过。推动他们似乎是一个 举重。那么,如何进行呢?

            我确定了两个选项:

            选项 1:检查每个分支并推送我可以这样做,我可以 甚至编写一个 Bash 脚本来提供帮助。但是,这样做会改变我的 每次结帐的工作文件,并将创建一个本地分支 每个远程跟踪分支。这会很慢 回购。

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

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

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

            在一些 在这种情况下,也可以只推送分支的一个子集。如果 分支名称用斜杠命名(例如, oldremote/features/branch3、oldremote/features/branch4 等),您可以 仅推送名称以开头的远程跟踪分支 “oldremote/功能”:

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

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

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

            发布日期:2017 年 10 月 9 日

            【讨论】:

            • 您好,但是这样做也会给您添加一个之前提交中没有的 HEAD 分支,您知道如何处理吗?
            • 是的,我也发现了,我还没有对它做任何事情。可以直接删除。
            【解决方案15】:

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

            预期结果是一个 repo “克隆”到另一个远程(即从 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
            

            【讨论】:

              【解决方案16】:

              每次我谷歌如何做到这一点时,我最终都会阅读相同的主题,但这并没有让我到达我需要的地方,所以希望这对我未来的自己和其他人也有帮助。

              我开始了一个新的本地项目,我想将它推送到我的存储库 (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标志是强制推送,否则会识别出两个repo不同而失败。

              【讨论】:

              • 这不是最初的问题所要问的。这也确实不安全。您是在告诉人们丢弃旧的提交。除非您真的知道自己在做什么,否则您实际上应该基本上永远不要使用“强制”选项。
              • @CameronTacklind 这是一个新项目,所以没有提交。
              • 最初的问题是询问如何将现有项目上传到“新远程”包括全部分支和标签。 “新遥控器”是空的,因此不需要力量。同样,除非您真的知道自己在做什么,否则您基本上不应该进行强制推动。将此建议给其他用户,尤其是在没有适当警告的情况下,尤其是在不需要它的情况下,会伤害某人。
              • 公平点。我从 BitBucket 网站获得了这些说明并决定分享。请编辑我的答案以包括您的警告和潜在问题,因为我不像您那样熟悉它。感谢您引起我的注意??
              【解决方案17】:

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

              git push --all
              git push --tags
              

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

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

              git push --mirror
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-02-15
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-01-09
                • 1970-01-01
                相关资源
                最近更新 更多