如何用不相关的历史替换远程存储库内容?
How to replace remote repository content with unrelated history?
我在 github 上托管了一个存储库,我用它来开发一些代码,我们称它为 https://github.com/foo/bar.git。
在另一个完全独立的本地存储库中,我开发了一些其他代码。现在我想把这个本地仓库的内容推送到https://github.com/foo/bar.git,完全替换旧的内容(分支、标签等)。我该如何实现?
我知道我可以简单地删除 github 上的回购并创建一个新的,但我想避免这种情况。
我在本地仓库中设置了远程 URL。我也做了 git push
,但这导致新内容与原始内容共存(例如,由于 main
与 master
分支不匹配)。有办法解决吗?
大体上是正确的,但遗漏了几个注释:
由于您现在有一个 main
而替换存储库中没有 master
,您可能希望 GitHub 设置名称 main
,而不是名字 master
。那么你可能想要 删除 旧 名称 master
完全,但在你这样做之前,你可能需要告诉 GitHub 为您的 GitHub-side 存储库更改 默认分支 的概念,因为您无法删除克隆的推荐默认分支名称。
或者,您可能希望在遥控器上继续使用名称 master
。如果是这样,您将需要决定是否重命名您自己的本地存储库中的分支。简单的事情是 git branch -m main master
然后根据需要 force-push。
做前者(将GitHub分支名称切换为main
),你可以从:
开始
git remote add origin https://github.com/foo/bar.git
git push -u origin main
这会将(如果不是全部的话)你的新提交发送到 GitHub,然后要求 GitHub-side 软件创建一个新分支名称 main
在那里。成功后,它将本地 main
的上游设置为新创建的 origin/main
.
现在那里已经有了main
,你可以使用GitHub网页或者gh
cli command设置那里的默认分支名称为main
:
gh repo edit --default-branch main
(或使用浏览器和通常的点击按钮)。
更多
您可能还想删除 GitHub 端的所有现有标签和其他分支名称,然后为任何新分支和标签名称创建新的。
你可以——但不是必须;见下文—使用 git push --delete
删除 GitHub 拥有的所有分支和标签名称,除了您刚刚创建的新 main
或您刚刚更新的 master
。要获取此类名称的列表,请考虑使用:
git ls-remote origin
这会将它们全部溢出(您可能希望将其重定向到您可以编辑的文件)。请务必过滤掉名称 HEAD
和 main
。您可以将剩余的名称提供给单个 git push origin --delete
,带或不带 refs/heads/
和 refs/tags/
前缀,例如:
git push origin --delete br1 br2 master tag1 tag2 tag3
现在,如果您要设置更多的分支 and/or 标记名称,您可以一次完成,再设置一个 git push
,例如:
git push -u origin newbr1 newbr2 newtag1 newtag2
(注意:我实际上不确定 -u
在推送标签时是否正常工作;如果它导致问题,请考虑将其拆分为两个单独的 git push
命令,一个用于分支名称 -u
和一个没有 -u
).
的标签名称
作为 short-cut,考虑:
git push --mirror origin
--mirror
选项将 删除 名称 而不是 推送,并将尝试推送(使用 --force
) 所有分支和标记名称。所以这应该涵盖“删除旧名称”和“更新新名称”。不过,我认为这不能与 -u
结合使用。您可以改为 运行 git fetch
之后,根据需要创建 origin/*
名称,然后执行一系列 git branch --set-upstream-to
命令(很容易编写脚本)。
如果您有任何受保护的分支名称,您可能需要在执行所有这些操作之前 un-protect 它们。
警告
从您的 GitHub-side 存储库中删除 分支名称 会使那里的旧 提交 un-find-able。但是,它实际上并没有删除 那些提交。 GitHub 有一个内部保留政策(由于与 GitHub 分叉有关的内部原因)永远 保留此类提交,而不是 Git典型的本地 30 或 90 天有效期。 (您可以要求支持人员清除死提交,就像您可能对包含敏感数据的提交所做的那样。不过,我不确定针对这种情况的政策是什么。)
所有这些意味着 (a) 更容易 完全 删除 您的 GitHub-side 存储库; (b) 这样做可以 GitHub 自己节省一些磁盘空间 space,尤其是在您的私有存储库没有复刻的情况下。所以我不会费心用更复杂的 repository-retaining 方式来做这件事。当然,删除和re-creating仓库也会破坏GitHub-only问题、PR等数据库,可以考虑一下。
我在 github 上托管了一个存储库,我用它来开发一些代码,我们称它为 https://github.com/foo/bar.git。
在另一个完全独立的本地存储库中,我开发了一些其他代码。现在我想把这个本地仓库的内容推送到https://github.com/foo/bar.git,完全替换旧的内容(分支、标签等)。我该如何实现?
我知道我可以简单地删除 github 上的回购并创建一个新的,但我想避免这种情况。
我在本地仓库中设置了远程 URL。我也做了 git push
,但这导致新内容与原始内容共存(例如,由于 main
与 master
分支不匹配)。有办法解决吗?
由于您现在有一个
main
而替换存储库中没有master
,您可能希望 GitHub 设置名称main
,而不是名字master
。那么你可能想要 删除 旧 名称master
完全,但在你这样做之前,你可能需要告诉 GitHub 为您的 GitHub-side 存储库更改 默认分支 的概念,因为您无法删除克隆的推荐默认分支名称。或者,您可能希望在遥控器上继续使用名称
master
。如果是这样,您将需要决定是否重命名您自己的本地存储库中的分支。简单的事情是git branch -m main master
然后根据需要 force-push。
做前者(将GitHub分支名称切换为main
),你可以从:
git remote add origin https://github.com/foo/bar.git
git push -u origin main
这会将(如果不是全部的话)你的新提交发送到 GitHub,然后要求 GitHub-side 软件创建一个新分支名称 main
在那里。成功后,它将本地 main
的上游设置为新创建的 origin/main
.
现在那里已经有了main
,你可以使用GitHub网页或者gh
cli command设置那里的默认分支名称为main
:
gh repo edit --default-branch main
(或使用浏览器和通常的点击按钮)。
更多
您可能还想删除 GitHub 端的所有现有标签和其他分支名称,然后为任何新分支和标签名称创建新的。
你可以——但不是必须;见下文—使用 git push --delete
删除 GitHub 拥有的所有分支和标签名称,除了您刚刚创建的新 main
或您刚刚更新的 master
。要获取此类名称的列表,请考虑使用:
git ls-remote origin
这会将它们全部溢出(您可能希望将其重定向到您可以编辑的文件)。请务必过滤掉名称 HEAD
和 main
。您可以将剩余的名称提供给单个 git push origin --delete
,带或不带 refs/heads/
和 refs/tags/
前缀,例如:
git push origin --delete br1 br2 master tag1 tag2 tag3
现在,如果您要设置更多的分支 and/or 标记名称,您可以一次完成,再设置一个 git push
,例如:
git push -u origin newbr1 newbr2 newtag1 newtag2
(注意:我实际上不确定 -u
在推送标签时是否正常工作;如果它导致问题,请考虑将其拆分为两个单独的 git push
命令,一个用于分支名称 -u
和一个没有 -u
).
作为 short-cut,考虑:
git push --mirror origin
--mirror
选项将 删除 名称 而不是 推送,并将尝试推送(使用 --force
) 所有分支和标记名称。所以这应该涵盖“删除旧名称”和“更新新名称”。不过,我认为这不能与 -u
结合使用。您可以改为 运行 git fetch
之后,根据需要创建 origin/*
名称,然后执行一系列 git branch --set-upstream-to
命令(很容易编写脚本)。
如果您有任何受保护的分支名称,您可能需要在执行所有这些操作之前 un-protect 它们。
警告
从您的 GitHub-side 存储库中删除 分支名称 会使那里的旧 提交 un-find-able。但是,它实际上并没有删除 那些提交。 GitHub 有一个内部保留政策(由于与 GitHub 分叉有关的内部原因)永远 保留此类提交,而不是 Git典型的本地 30 或 90 天有效期。 (您可以要求支持人员清除死提交,就像您可能对包含敏感数据的提交所做的那样。不过,我不确定针对这种情况的政策是什么。)
所有这些意味着 (a) 更容易 完全 删除 您的 GitHub-side 存储库; (b) 这样做可以 GitHub 自己节省一些磁盘空间 space,尤其是在您的私有存储库没有复刻的情况下。所以我不会费心用更复杂的 repository-retaining 方式来做这件事。当然,删除和re-creating仓库也会破坏GitHub-only问题、PR等数据库,可以考虑一下。