有什么方法可以将拉取请求从bitbucket hg存储库迁移到github git存储库吗?

时间:2019-12-22 22:25:19

标签: git github mercurial bitbucket pull-request

我在bitbucket hg存储库中有一个旧的请求请求,我想尝试将其集成,但是与此同时,我已将存储库迁移到github并将其转换为git。有什么办法可以迁移此拉取请求?如果没有,那么进行集成的最痛苦的方法是什么?

1 个答案:

答案 0 :(得分:0)

我在a comment中提到了基本过程。本质上,您需要原始的Mercurial存储库,并将其更改集发送给原始的Bitbucket服务器以进行PR。

(注意:我实际上并没有做过。这只是理论上的。理论很简单。同样的技术也可以用于从CVS或SVN或Perforce进行的转换。关键是建立一个临时的带有正确提交的Git存储库会导致(然后包括)一组要复制的PR提交。然后,我们仅将PR提交复制到链接到GitHub存储库的Git存储库中。)


执行此操作的最佳(或最短或最简单)方法可能会有所不同,具体取决于一些细节。但是,大概您已经或者至少可以克隆整个原始Mercurial存储库及其从bitbucket的拉取请求。这将为您提供一个完整的,自包含的Hg存储库,其中包含一堆变更集,包括最初转换为Git的所有变更集以及此后属于PR的变更集。

现在,您可以通过任何方式将整个内容转换为 new Git存储库。每个原始Mercurial变更集都会对该Git存储库进行一次提交,或多或少。 (“或多或少”发生在您有意不转换某些hg提交和/或您有hg标签的情况下,这会导致新的提交,这些新的提交又转换为不使用提交的Git标签。一些详细信息是可能取决于您的转换软件。)

这个新的Git存储库可能与GitHub上的存储库完全无关,从原始转换到Git的提交哈希值不同。或者,如果转换很简单,那么当您构建这个新的Git存储库时,它实际上会使用原始的哈希ID,因此紧密相关!

如果确实如此紧密相关,那么问题实际上就消失了。只需为此Git存储库(即GitHub存储库(或其分支))设置一个远程站点,然后git push在此处进行其他提交,然后照常进行GitHub PR。

如果紧密相关,那么您最有可能应该使用git cherry-pick,这似乎是最简单的方法。这里涉及很多存储库,因此让我们使用一些简单的单字母名称来命名每个字母:

  • G main 是要在其上创建新PR的GitHub存储库(或其分支)。

  • G local 是您在自己的计算机上 G main 的克隆。 (即使您实际上并未使用笔记本电脑,我也会简称为“您的笔记本电脑”,以将其与各种服务器上的Git存储库区分开来。)

  • R 0 是您的Mercurial存储库,其中包含您已经拥有或从Bitbucket上的PR重新克隆的额外提交。

  • R g 是转换为Git后的存储库。该存储库可以直接在笔记本电脑上使用。请注意,它已经在某个分支上有了新的提交,几乎可以准备git push了,但在这种情况下还不够。问题在于这些提交所处的历史与 G main 中的历史无关。

在笔记本电脑上的 G local 中,您现在将使用git remote add R g

git remote add recoverer <url>

the只是笔记本电脑上 R g 的路径。 (您可以根据需要将file:///放在其前面,尽管您不愿意,如果您直接使用 R g 的完整路径,如果您出于某些原因 R g 位于某台服务器上,请使用一个允许您的Git到达该服务器的URL,这样,您的Git就不会使用多余的磁盘空间。您的Git将需要分配新的本地磁盘空间,以便一段时间内在所有提交中进行复制。)

现在运行:

git fetch recoverer

这将用 R g 中的提交(整个历史记录)填充您的 G local ,并创建远程跟踪格式为recoverer/originrecoverer/develop等的名称。现在,您想要的提交(除了错误的历史链接之外)都位于远程跟踪名称上。具体来说,我将其称为recoverer/pr123,但实际名称取决于您在转换软件中创建的 R 0 中使用的分支或书签名称。当它生成 R g 时。

请注意,在分支recoverer/pr123上的这些提交之前,还存在recoverer/pr123上的的许多(数十,数百,数千,任意)提交。 Git奇怪的是,提交在分支上意味着什么,它经常在多个分支上进行提交。 包含的分支集会动态变化随着时间的推移!这与Mercurial截然不同,Mercurial礼貌地保留在其原始分支中。因此,您现在的目标是复制recoverer/pr123上仅 的提交,而不是复制recoverer/master上的上的提交,或者他们出现在其他任何分支上。

您可以一次通过哈希ID查找这些提交,也可以找出哪些名称可以排除它们。例如,如果git log recoverer/master..recoverer/pr123恰好显示了正确的提交集,则名称recoverer/master用于排除不需要的提交。您将以一种或另一种方式运行git log recoverer/pr123,也许像这样在前面加上一些排除名称,以验证您是否获得了要复制的正确提交集。


已经找到要复制给您PR的提交-无论是通过单个哈希ID还是通过这种名称,您现在都可以运行:

git checkout <branch>

(其中 branch 是要将这些提交复制到的位置,如果愿意,可以将其复制为新分支),然后:

git cherry-pick <hashes-or-string>

例如git cherry-pick recoverer/master..recoverer/pr123。 Git现在将尝试复制-或以Mercurial术语 graft -这些将提交到当前分支。新的提交将进行与原始提交相同的更改,但是将是您在git checkout branch步骤中签出的提交的基础上,又有了新的历史记录-一组新的提交。

一切顺利之后,您就可以照常git push origin并照常发出GitHub Pull请求。您还可以git remote remove recoverer G local 中删除所有recoverer/*名称,并从 G local 中删除链接> 更改为 R g ,您可以删除 R g 本身。 (选择完樱桃之后,您可以随时执行所有这些操作。)如果Git与 R g共享 G local 中的内容 ,删除 R g 后,将释放磁盘空间。如果不是这样,由于它与 R g 的链接已消失,Git最终将“垃圾回收”额外的磁盘空间。