Mercurial到Mercurial到颠覆工作流问题

时间:2010-03-23 19:57:37

标签: svn mercurial hgsubversion

我们正在从Subversion迁移到Mercurial。为了促进迁移,我们正在创建一个中间Mercurial存储库,它是我们的Subversion存储库的一个副本。所有开发人员将开始切换到Mercurial存储库,我们将定期将更改从中间Mercurial存储库推送到现有的Subversion存储库。经过一段时间后,我们将简单地废弃Subversion存储库,中间的Mercurial存储库将成为新的记录系统。

Dev 1 Local --+--> Mercurial --+--> Subversion
Dev 2 Local --+                +
Dev 3 Local --+                +
Dev 4 -------------------------+

我一直在对此进行测试,但是当我将更改从我的本地存储库推送到中间Mercurial存储库,然后再推送到我们的Subversion存储库时,我一直遇到问题。

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/01.png

在我的本地计算机上,我有一个已提交的变更集,可以将其推送到我们的中间Mercurial存储库。在这里你可以看到它是版本#2263,哈希625 ......

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/02.png

我只将此变更集推送到远程存储库。

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/03.png

到目前为止,一切看起来都不错。变更集已被推送。

hg update
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

我现在切换到远程存储库,并更新工作目录。

hg push
pushing to svn://...
searching for changes
[r3834] bmurphy: database namespace
pulled 1 revisions
saving bundle to /srv/hg/repository/.hg/strip-backup/62539f8df3b2-temp
adding branch
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
rebase completed

接下来,我将更改推送到Subversion,效果很好。此时,更改位于Subversion存储库中,我将注意力返回给我的本地客户端。

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/04.png

我将更改提取到本地计算机。咦?我现在有两个变更集。我的原始变更集现在显示为本地分支。

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/05.png

另一个变更集的新版本号为2264,新的哈希值为10c1 ...

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/06.png

无论如何,我将本地仓库更新为新版本。

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/07.png

我现在换了。

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/08.png

所以,我最后点击“确定并标记传出的更改集”,正如您所看到的,Mercurial仍然想要推出我之前的更改集,即使它们已被推送过。

显然,我做错了什么。

我也无法合并这两个版本。如果我在本地计算机上合并两个修订版,我最终会进行“合并”提交。当我将合并提交推送到中间Mercurial存储库时,我不能再将更改推送到我们的Subversion存储库。我最终遇到了以下问题:

hg update
0 files updated, 0 files merged, 0 files removed, 0 files unresolved

hg push
pushing to svn://...
searching for changes
abort: Sorry, can't find svn parent of a merge revision.

我必须回滚合并才能恢复工作状态。

我错过了什么?

3 个答案:

答案 0 :(得分:22)

你没有做错任何事情,事实上在你的情况下,你所看到的行为是预期的(如果对新的Mercurial用户有点混淆)结果。

hgsubversion非常适合两件事:

  1. 使用Mercurial作为Subversion的客户端,无需在svn
  2. 之外交换更改
  3. 将Subversion存储库转换为Mercurial
  4. 您正在尝试将其用作更通用的网关,这是一个更难解决的问题。 Subversion对世界有着非常严格的看法,我们必须在其中工作。问题的真相是,在从Subversion中提取修订版后使用hgsubversion时,修订版哈希只能被视为最终版本。因此,如果您的开发人员直接在Mercurial存储库之间共享更改集,而不将Subversion作为中介,则会发生这种情况。

    rebase是自动的,非可选的,原因很简单:Subversion在你推送时会执行rebase。如果您在推送时进行了无法更改,Subversion会为您执行该rebase,如果成功(使用非常简单的重新定位算法),它会接受提交,但不会指示发生了rebase。我们正在修补两种不同的模型。

    我建议立刻将所有人转移到Mercurial上 - 像这样的混合方法只会让Mercurial在短期内变得更加困难,并且可能会使新用户混淆DVCS。

答案 1 :(得分:3)

首先,让我说一下阅读如此详细的问题是多么高兴。 :)

当您从远程执行hg push到svn repo时,问题就出现了。这是您示例中的输出:

hg push
pushing to svn://...
searching for changes
[r3834] bmurphy: database namespace
pulled 1 revisions
saving bundle to /srv/hg/repository/.hg/strip-backup/62539f8df3b2-temp
adding branch
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
rebase completed

我不是一个hg-subversion用户,但是那个输出表明在执行你请求的推送的过程中,它正在从svn repo中提取更改,找到一个新版本,然后执行rebase您的变更集10c1在新撤销的修订版(后代)之后。 rebase command采用分支历史并将其转换为线性历史,但这样做会改变变更集的父级,这会改变它们的哈希值,这看起来就像发生在你身上的事情。

同样,不是hg-subversion用户,所以我不能说是否总是应该发生pull / rebase以及它应该如何工作,但是hgsubversion wiki页面说:

  

您可以使用通常的Mercurial   用于处理此存储库的命令。   如果你有一系列的提交   给定分支,并希望将它们移动到   那个分支的尖端,使用hg   在提示时使用rebase --svn命令   你的工作和那些变化   将自动在顶部进行重新定位   新的上游工作。

这使得它听起来通常不是自动的。

我无法从你的介绍中看出,是否仍然在svn中创建了新的变更集,或者它们是仅在mercurial中创建的?

如果它们只是在mercurial中创建,那么一个解决方法是在远程系统上设置一个svn-gateway repo,并从那里进行推送,并且永远不会从该repo中恢复到mercurial。然后,由于rebase,该repo中的更改集将具有不同的哈希值,但它们不会流回主远程仓库和最终用户系统。

更大的修复方法是找出为什么“hg push svn:// ..正在重新定位所有出站变更集”。回答一个,行为就会停止。

答案 2 :(得分:1)

我们现在正在使用移植命令做类似的事情。有效地,我们在推送之前重新创建每个变更集,以避免必须推送合并变更集。

我们的目标是干净地为使用颠覆的项目做出贡献。

  • 为您的所有更改创建一个subversion分支。在Mercurial中获取它。
    $ cd [svn-checkout] ; svn cp trunk branches/hg-bridge
    $ cd [hgsubversion bridge] ; hg pull ; hg update hg-bridge

  • 检查您当地的仓库是否有新的变化 $ hg in [repo] # shows <rev> IDs you can use later

  • 从本地仓库中拉出您想要进入svn的更改 $ hg pull [repo]

  • 移植您想要贡献的所有更改:
    $ hg graft [rev] [rev] # rev could be 645 or b7a92bbb0e0b. Best use the second>.
    您需要单独指定每个转速,
    但你可以在一个命令中移植多个转速。

  • 检查你要推的是什么:
    $ hg outgoing

  • 推送更改:
    $ hg push
    这个可能显示一些不相关的拉动修订版 并且应该显示您的新修订版本 以及备份包的路径(您不应该使用)。(注释也可以在GPLv2或更高版本下使用)