6

情况如下:开发人员 Foo 从我们的 svn 存储库创建了一个 hg 存储库。Foo 的 hg repo 只是 svn 中树干的浅层克隆(没有 svn 分支、标签等,历史不完整 [大约 100 个变更集])。Developer Bar 做了同样的事情,但是克隆了整个 svn 存储库,包括整个历史、分支、标签等。Foo 和 Bar 都在他们的存储库上进行了分支开发。

两个存储库都有一个共同的 SVN 祖先,但每个 hg 存储库都有不同的版本号。我想将 Foo 从共同祖先的更改重新添加到 Bar 的存储库中。这是我正在寻找的图表:

Foo 的回购:

C'-D'-E-F---G
       \   /
        H-I

酒吧的回购:

...A-B-C-D-J-K---L
            \   /
             M-N

C,C' 和 D,D' 内容相同,但版本号和注释不同。

目标:

...A-B-C-D--E-F---G
          \  \   /
           \  H-I
            \
             J-K---L
              \   /
               M-N

我已经没有关于如何实现这一点的想法了。我试过 convert --splicemap splice.map [splice.map file contains ED] (没有做任何事情)。Clone -f 设法将所有内容都放入一个存储库中,但它们似乎是独立的树。在 clone -f 之后,我尝试了 rebase --source E --dest D --detach,但它只是崩溃了:(

想法?

我知道更改历史将使任何人的存储库克隆无效,在这种情况下这不是问题。所有用户都将从这项工作的结果中重新克隆。

4

3 回答 3

2

解决了!

我最初没有注意到的一件事是,我假定的共同祖先毕竟并不完全相同。在 Foo 的 repo 的 svn->hg 转换过程中,$ID$ 字符串被扩展,但不在 Bar 的 repo 的创建中。下面的第 1 步是创建一个真正的共同祖先的简单修复。

以下步骤使我能够实现我的目标:

1-确保假定的共同祖先(D 和 D')实际上是相同的。如果没有,请在 Bar 的仓库中为它们 (S) 创建一个新的拼接点。在我的示例中,S 应该与 D' 的内容完全匹配。

    ...ABCD--JK---L
              \ \ /
               小号锰

2-修剪 Foo 的 repo 的历史记录以删除重复的历史记录,包括 D',使用

    hg convert --splicemap TrimSplicemap Foo FooTrimmed

TrimSplicemap 内容:(其中 E 是 E 的完整哈希)

    E 00000000000000000000000000000000000000000

3-使用 hg strip 删除断开连接的冗余历史记录

    cd FooTrimmed
    汞带 C'

4-再次使用 hg convert 将 Foo 的剥离 repo 拼接到 Bar 的 repo 上,在 commit 'S'

    cd ../酒吧
    hg 转换 --splicemap FooBarSplicemap ../FooTrimmed 。

FooBarSplicemap 内容:(其中 E' 是 FooTrimmed 中 E 的 NEW 哈希,S 是 S 的哈希)

    埃斯

应该这样做!:D

于 2011-05-06T17:19:09.083 回答
1

可以使用Mercurial Queues来完成此操作。

  1. 将每个变更集从 repoFoo导入补丁队列。
  2. Bar回购。
  3. 更新Bar作为共同祖先的变更集。
  4. 将补丁队列导入Bar.
  5. 应用补丁队列。

这将更改所有Foo补丁的提交 ID,但仍允许您保留整个历史并将它们的开发存储库合并在一起。

于 2011-05-05T20:18:06.787 回答
1

我们今天在 IRC 讨论了这个问题,我的建议是把两者都放到同一个 repo 中,让它有两个根。头部将完全按照您的意愿进行,其余的并不重要。

如果您无法忍受(您想象人们比实际使用历史/指责更多),那么我认为您的拼接图应该具有:

E D

因为你试图让 E 的父母成为 D(不是 D')

于 2011-05-06T02:51:51.640 回答