在新 Git 回购中有新的主要版本,但保留旧回购并具有完整的历史记录

Have new major version in new Git repo but keep old repo and have full history

我要将 Visual Studio 现在在回购 A 中的解决方案复制到新的解决方案 B 并在 github 上为其创建新的回购。

A完全不会开发。但是我需要整个 A 历史记录在 B 中可见。

我该怎么做?

我可以在 VS 中不安装 git 吗?


Visual Studio 2022 专业版 / Windows 11


编辑: 快速总结(@torek 解决方案的实用步骤):

一个 Git 存储库的核心由两个数据库组成:

  • 一个数据库——通常更大——包含Git的提交对象和其他对象。每个对象都有一个哈希 ID(OID对象 ID ),这就是 Git 检索对象的方式。任何给定的提交都包含与该特定提交一起使用的所有文件的完整快照,并在该提交的 中一直冻结。 (Git 通过制作 sub-objects 并通过 de-duplication 从字面上共享文件的相同副本来做到这一点,并且还压缩文件,有时非常成功,所以每次提交都保存完整快照的事实每个 文件不会使存储库膨胀——有些存储库实际上比它们保存的文件

    每个提交对象都包含先前(parent )提交的哈希 ID 列表。这个列表通常只有一个条目长,尽管至少有一个提交(第一个)有一个 empty 列表,因为那时没有以前的提交,并且 merge 提交在此列表中有两个(或可能更多)父项。

    存储在每个提交中的父列表将提交形成 Directed Acyclic Graph 或 DAG。存储在这个大数据库中的DAG,就是的历史。如果你有提交,你就有历史。如果你没有提交,你就没有历史。所以那部分很简单:只需获取所有提交,您就会拥有所有历史记录。

  • 一个单独的数据库包含 human-readable 名称:b运行ch 名称、标签名称、remote-tracking 名称和其他名称。 Git 需要提供它以供 人类 使用,因为数据库对象的哈希 ID (OID) — Git 需要 数据库中检索 那些对象——是random-looking 并且人类无法处理。通过在 names 下存储特别重要的哈希 ID,Git 使您可以轻松地询问 Git 以获取“版本 v2.1”或“ b运行ch main 的最新提交”。 Git 通过在该名称中查找存储的哈希 ID 来提供哈希 ID。每个名称只存储一个哈希 ID,由于有 DAG,这就足够了。

所以:

I am going to copy Visual Studio solution that is now in repo A to new solution B and create new repo on github for it.

请注意,VS“解决方案”不仅仅是一个Git存储库,而是只要整个解决方案都包含在 一个(单个)Git 存储库,克隆存储库就足够了。

要克隆原始(repo A)存储库,请使用 git clone。这个:

  • 将整个提交数据库复制到使用相同哈希 ID 的新数据库(所有 Git 哈希 ID 都是通用的:所有 Git 软件都同意使用 相同 相同对象的OID,这就是Git).

    中真正的魔法
  • 读取并t运行sforms 名称数据库中的名称,以构建新的名称数据库。 new 数据库保持 tag 名称不变,但将原始存储库的 b运行ch names into remote-tracking names in the new clone.

  • 最后,执行最后的 git switchgit checkout 步骤以从一个特定的 b运行ch 中提取一个特定的提交。由于新克隆有 no b运行ch 名称(请记住,Git 不需要这些类型的 b 运行ches:它只需要对象;人类需要名字),这通常会失败,但是Git 将 创建 b运行ch from 自动 remote-tracking 名称。

Git 创建的 b运行ch 名称,在最后一步中,是您在 运行 git clone 时告诉它使用的名称。如果你不告诉它一些特定的,你的 Git 软件会询问另一个 Git 软件(在这种情况下可能在 GitHub 上,无论如何存储 repo A 的任何地方)哪个名称 他们推荐。你的 Git 然后使用你的 Git 从 他们的 [=190 创建的 remote-tracking 名称中存储的散列 ID =] b运行ch 名称。 (哇!)

举个例子就清楚多了。如果他们有名为 maindevelop 的 b运行ches 并且您克隆了他们的存储库,您将得到一个 origin/main 和一个 origin/developremote-tracking 名字 记住他们的 b运行ch 名字。如果他们随后建议您的 Git 应该创建 main,那么您的 Git 将使用您的 origin/main——您的 Git 从他们的 main 中创建——来创建你的 b运行ch 名称 main,选择 origin/main 相同的提交 ,这会选择与他们的 main 相同的提交。所以你现在有 one b运行ch.

克隆中的历史 是 cl 中的提交集ne,由所有名称找到:标记名称、remote-tracking 名称和一个新的 b运行ch 名称。如果愿意,您可以创建额外的 b运行ch 名称来记住特定的提交;例如,您可以为每个 remote-tracking 名称创建一个 b运行ch 名称。但通常你可能只想要 mainmaster:例如,任何当前只有 find-able 到 origin/develop 的提交都是不相关的,不需要保留.

现在你有了一个克隆,你可以推送到 GitHub

上的一个新的空仓库 B

现在是时候在 GitHub 上创建 一个存储库:repo B。

您可以使用 gh command-line 界面(参见 )从 shell 中执行此操作,例如 bash 或 zsh 或 PowerShell,或者您可以使用 GitHub 提供的 Web 界面执行此操作。无论哪种方式,您都应该将其作为 empty 存储库。一个空的存储库有一对空的数据库:没有提交或其他对象,也没有名称。但它仍然存在,即使它是空的。

现在回购 B 存在 在 GitHub 上,您将再次使用命令行界面(通过 bash 或 zsh 或 PowerShell 或其他任何方式) 告诉您的 Git 软件替换 origin URL。当您 运行 git clone 时,您的 Git 软件将存储库 A 的 URL 保存在名称 origin 下。但是您不再想与访问 repo A 的软件对话。您现在想与访问 repo B 的 GitHub 软件对话。所以:

git remote set-url origin <url>

用回购 B 的实际 URL 替换 <url> 部分,无论是 https://github.com/... 还是 ssh://git@github.com/...(都可以:细节涉及 Git集线器设置你必须单独做的事情)。然后使用 git remote -v 确保您已正确设置所有内容。

一旦远程 origin 是您的存储库 B,运行 git push --all origin 将两个数据库填充到 GitHub 副本中。这将为您创建的所有 b运行ches 填充所有 reachable 对象,并设置它们的所有 b运行通道名称。然后 运行 git push --tags origin 使用您的所有标签更新他们的姓名数据库。

请注意,您在本地的提交只能通过 remote-tracking 名称(例如,origin/develop)找到,不会被发送到存储库 B这里。如果你想让它们被发送,创建一个 b运行ch name:

git switch develop

例如会注意到您没有 develop,但是您有 origin/develop,并且会使用您的 origin/develop 名称和保存的提交哈希 ID使用相同的哈希 ID 创建一个新的 develop。然后,您可以 git push origin develop(或再次 git push --all origin)在 GitHub 上创建名称 develop 并填写那些缺失的对象他们的对象数据库。

如果您在 git push --all origin 步骤之前创建所有您想要的 b运行ch 名称,您将获得所有对象和 b运行ch 名称 t运行sferred,因为 --all 意味着 发送所有 b运行ch names.

可选:在 GitHub 上保存 space 并启用拉取请求

完成上述所有操作后,您会在 GitHub 上获得一个 independent 存储库 B。也就是说,这个新的存储库 B 与任何其他 GitHub 存储库没有连接。您不能在 GitHub 上从 回购 B 发出拉取请求 。如果那是你想要的,那很好。

如果回购 A GitHub 之前创建回购 B,不过,GitHub 为您提供了一种方法来制作 [= =121=]repo A 的完整副本,只需单击一个 web-page 按钮。使用此按钮将复制两个数据库,即,您将获得所有对象(完整历史记录)所有b运行ch 和标签名称。 (Git集线器不使用 remote-tracking 名称,因此此处没有可复制的内容。Remote-tracking 名称用于您的笔记本电脑 Git 存储库。)

使用这个按钮——一个大的绿色 FORK 按钮——通过在 他们的 系统,如果您想创建拉取请求,可以帮助 。你说:

The A will not be developed at all.

这表明您从未打算创建任何拉取请求 回购 A。但是如果您改变主意,您可能希望您使用了“fork the repo" 按钮并保存 space 在 GitHub 上。不过,这完全取决于您。

最后几项

Can I do it in VS without installing git?

可能不会,但我不使用 Visual Studio。

I am going to copy Visual Studio solution ...

据我了解,“解决方案”包括一个 .sln 文件。该文件确实在存储库中,因此复制提交将为您提供原始解决方案文件。由于历史记录(任何 Git 存储库中的现有提交)一直 完全冻结 ,此解决方案可能包含错误的 名称 .你无法解决这个问题,除非用一个新的不同的提交(包含不同的文件)替换每个历史提交。这可能不值得做,但我实际上并没有使用 VS