【问题标题】:Mercurial to Mercurial to Subversion Workflow ProblemMercurial 到 Mercurial 到 Subversion 工作流问题
【发布时间】:2011-01-30 23:34:43
【问题描述】:

我们正在从 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 存储库的变更集。在这里你可以看到它是带有哈希 625 的修订 #2263...

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.

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

我错过了什么?

【问题讨论】:

  • 所有图片都坏了:-\

标签: svn mercurial hgsubversion


【解决方案1】:

您没有做错任何事,事实上,在您的情况下,您看到的行为是预期的(如果对 Mercurial 新用户有些困惑)结果。

hgsubversion 确实有两个好处:

  1. 使用 Mercurial 作为 Subversion 的客户端,无需在 svn 之外交换更改
  2. 将 Subversion 存储库转换为 Mercurial

您正在尝试将其用作更通用的网关,这是一个困难得多的问题。 Subversion 对世界有非常严格的看法,我们必须在这个范围内工作。事情的真相是,只有在从 Subversion 中提取修订后使用 hgsubversion 时,修订哈希才能被视为最终版本。因此,如果您的开发人员曾经在 Mercurial 存储库之间直接共享变更集,而没有 Subversion 作为中介,就会发生这种情况。

rebase 是自动的和非可选的,因为一个非常根本的原因:Subversion 在你推送时执行那个 rebase。如果您在推送时有未拉取的更改,Subversion 会为您执行 rebase,如果成功(使用愚蠢的简单 rebase 算法)它会接受提交,而不会显示 rebase 发生。我们正在拼凑两个不同的模型。

我建议立即将每个人都转移到 Mercurial - 像这样的混合方法只会在短期内使 Mercurial 的使用变得比实际需要的更加困难,并且可能会使刚接触 DVCS 的用户感到困惑。

【讨论】:

  • @dalroth 需要这样的过程:用户将 r1:r2 推送到 hg-gateway,hg-gateway 需要自动推送到 subversion,用户现在必须拉取,最后用户必须hg strip r1
  • @Harvey - 我可以澄清一下吗?我有一个团队想切换到hg,但是svn统治着这里的荒地。如果我们建立一个主 hg 存储库,并且只从那里推送到主 svn 或从那里拉出,一切都会好吗?更长的版本:我的老板会同意我们切换到 hg,但前提是一个团队首先进行试点计划。有足够多的通用代码(更不用说构建机器仍在运行 svn)完全切换到 hg 是不可能的。
  • @mos:这行得通,事实上,这是我个人所做的。诀窍是学习修改后的 hghgsubversionsvn 工作流程。一旦你“了解”了它的工作原理,你就不会有任何麻烦。您只需键入更多命令。我实际上已经开始编写脚本以使过程(这是重复的)更容易。典型流程: [in "hg" repo] 提交一堆更改;将它们推送到“hgsubversion”; [切换到“hgsubversion”] hg 更新(hgsubversion 需要这个); hg push 到“svn”(在本地推送和删除变更集后会自动重新拉取); ...待续...
  • @mos: ...[switch back to "hg"] hg pull from "hgsubversion"; hg 剥离旧的重复 b/c “hg” 不是 hgsubversion 克隆,也不知道自动剥离旧的变更集
【解决方案2】:

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

当您从远程对 svn 存储库执行 hg push 时,就会出现问题。这是您示例的输出:

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 存储库中提取更改,找到一个新修订版,然后执行您的 rebase更改集10c1 在新提取的修订(的后代)之后。 rebase command 采用分支历史并将其转换为线性历史,但这样做会更改变更集的父项,从而更改它们的哈希值,这看起来就像发生在您身上一样。

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

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

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

我无法从你的介绍中完全看出,新的变更集是否仍在 svn 中创建,还是仅在 mercurial 中创建?

如果它们仅在 mercurial 中创建,那么一种解决方法是在远程系统上设置一个 svn-gateway 存储库,然后从那里进行推送,并且永远不要从该存储库拉回 mercurial。然后,由于 rebase,该仓库中的变更集将具有不同的 hashid,但它们不会流回主远程仓库和最终用户系统。

不过,更大的解决方法是弄清楚为什么“hg push svn://.. 正在重新设置所有出站变更集”。回答那个,行为就会停止。

【讨论】:

  • 我试着仔细看看这个,但还是没有运气。如果不自动执行 rebase,我找不到从中间存储库进行 hg push 的方法,并且 hg rebase --svn 没有做任何事情,因为它已经是最新版本。
  • 是的,请与 hg-subversion 人员谈谈为什么要进行 rebase 以及是否可以避免。恐怕我只适合解决方法(3 repo 解决方案就是这样做的)。
  • @Dalroth, @Ry4an:hgsubversion 必须做 rebase,因为 subversion 的怪癖。最终的解决方案是如果 hgsubversion 可以检测到您何时对 hgsubversion 克隆进行 hg 克隆。然后,它将自动执行必要的下游条带和变基。我现在在工作中使用这个过程。它有效,但你必须习惯它。如果您的 hgsubversion 克隆没有自动与 subversion 服务器保持同步,它会变得更加复杂(因为您必须从 SVN 中提取,然后将您的更改重新定位到新提示上)。
【解决方案3】:

我们现在使用graft 命令来做类似的事情。实际上,我们在推送之前重新创建每个变更集以避免不得不推送合并变更集。

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

  • 为所有更改创建一个颠覆分支。在 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

  • 从本地 repo 中拉取你想要进入 svn 的更改
    $hg pull [repo]

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

  • 检查您要推送的内容:
    $hg outgoing

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 2020-07-15
    • 2010-10-24
    • 2012-02-27
    相关资源
    最近更新 更多