Mercurial 到 Mercurial 到 Subversion 工作流程问题
我们正在从 Subversion 迁移到 Mercurial。为了促进迁移,我们正在创建一个中间 Mercurial 存储库,它是 Subversion 存储库的克隆。所有开发人员都将开始切换到 Mercurial 存储库,我们将定期将更改从中间 Mercurial 存储库推送到现有的 Subversion 存储库。一段时间后,我们将简单地废弃 Subversion 存储库,中间的 Mercurial 存储库将成为新的记录系统。
Dev 1 Local --+--> Mercurial --+--> Subversion
Dev 2 Local --+ +
Dev 3 Local --+ +
Dev 4 -------------------------+
我一直在对此进行测试,但是当我将更改从本地存储库推送到中间 Mercurial 存储库,然后再推送到我们的 Subversion 存储库时,我不断遇到问题。
替代文本 http://bmurphy.mediafly.com.s3.amazonaws.com/images/ Mercurial/01.png
在我的本地计算机上,我有一个已提交并准备好推送到我们的中间 Mercurial 存储库的变更集。在这里您可以看到它是修订版 #2263,哈希值 625...
替代文本 http:// /bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/02.png
我仅将此变更集推送到远程存储库。
替代文本 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 存储库中,我将注意力返回到本地客户端。
替代文本 http://bmurphy.mediafly.com.s3.amazonaws.com/images/ Mercurial/04.png
我将更改拉到本地计算机上。啊?我现在有两个变更集。我原来的变更集现在显示为本地分支。
替代文本 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
无论如何,我将本地存储库更新为新版本。
替代文本 http://bmurphy.mediafly.com.s3.amazonaws.com/images/ Mercurial/07.png
我现在已经切换了。
替代文本 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.
并且我必须回滚合并才能恢复到工作状态。
我缺少什么?
We're migrating from Subversion to Mercurial. To facilitate the migration, we're creating an intermediate Mercurial repository that is a clone of our Subversion repository. All developers will be begin switching over to the Mercurial repository, and we'll periodically push changes from the intermediate Mercurial repository to the existing Subversion repository. After a period of time, we'll simply obsolete the Subversion repository and the intermediate Mercurial repository will become the new system of record.
Dev 1 Local --+--> Mercurial --+--> Subversion
Dev 2 Local --+ +
Dev 3 Local --+ +
Dev 4 -------------------------+
I've been testing this out, but I keep running into a problem when I push changes from my local repository, to the intermediate Mercurial repository, and then up into our Subversion repository.
alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/01.png
On my local machine, I have a changeset that is committed and ready to be pushed to our intermediate Mercurial repository. Here you can see it is revision #2263 with hash 625...
alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/02.png
I push only this changeset to the remote repository.
alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/03.png
So far, everything looks good. The changeset has been pushed.
hg update
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
I now switch over to the remote repository, and update the working directory.
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
Next, I push the change up to Subversion, works great. At this point, the change is in the Subversion repository and I return attention back to my local client.
alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/04.png
I pull changes to my local machine. Huh? I've now got two changesets. My original changeset appears as a local branch now.
alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/05.png
The other changeset has a new revision number 2264, and a new hash 10c1...
alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/06.png
Anyway, I update my local repo to the new revision.
alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/07.png
I'm now switched over.
alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/08.png
So, I finally click the "determine and mark outgoing changesets" and as you can see Mercurial still wants to push out my previous changesets even though they've already been pushed.
Clearly, I'm doing something wrong.
I also can't merge the two revisions. If I merge the two revisions on my local machine, I end up with a "merge" commit. When I push that merge commit out to the intermediate Mercurial repository, I can no longer push changes out to our Subversion repository. I end up with the following problem:
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.
and I have to rollback the merge to get back to a working state.
What am I missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你没有做错任何事,事实上,在你的情况下,你看到的行为是预期的(如果对新的 Mercurial 用户来说有些困惑)结果。
hgsubversion 确实有两点好处:
您正尝试将其用作更通用的网关,这是一个困难得多的问题。 Subversion 对世界有非常严格的看法,我们必须在这个范围内工作。事实是,只有在从 Subversion 中提取修订版后使用 hgsubversion 时,修订版哈希才能被视为最终版本。因此,如果您的开发人员在没有 Subversion 作为中介的情况下直接在 Mercurial 存储库之间共享变更集,就会发生这种情况。
出于一个非常根本的原因,变基是自动且非可选的:当您推送时,Subversion 会执行变基。如果您在推送时取消了更改,Subversion 会为您执行变基操作,如果成功(使用极其简单的变基算法),它会接受提交,而不会表明发生了变基操作。我们正在将两个不同的模型拼凑在一起。
我建议立即将所有人转移到 Mercurial - 像这样的混合方法只会在短期内使 Mercurial 的使用变得比实际需要的更加困难,并且可能会让刚接触 DVCS 的用户感到困惑。
You're not doing anything wrong, in fact in your situation the behavior you're seeing is the expected (if somewhat confusing to a new Mercurial user) result.
hgsubversion is really good for two things:
You're trying to use it as a more generalized gateway, which is a much much harder problem. Subversion has a very rigid view of the world, and we have to work within that. The truth of the matter is that the revision hash can only be viewed as final when using hgsubversion after the revision has been pulled from Subversion. Thus, if your developers ever share changesets between Mercurial repositories directly, without Subversion as an intermediary, this will occur.
The rebase is automatic and non-optional for a very fundamental reason: Subversion performs that rebase when you push. If you had unpulled changes when you pushed, Subversion did that rebase for you, and if successful (with a stupidly simple rebasing algorithm) it accepts the commit with no indication that a rebase occurred. We're patching together two different models.
I'd recommend moving everyone over to Mercurial at once - a hybrid approach like this is only going to make using Mercurial more difficult in the short term than it needs to be, and potentially confuse users new to DVCS.
首先,让我说阅读如此详细的问题文章是多么愉快。 :)
当您从远程对 svn 存储库执行
hg Push
时,就会出现问题。这是您的示例的输出:我不是 hg-subversion 用户,但该输出表示在执行您请求的推送过程中,它从 svn 存储库中提取更改,找到新的修订版本,然后执行 <在新拉取的修订版(的后代)之后,您的变更集
10c1
的 code>rebase 。 rebase 命令 采用分支历史并将其转换为线性历史,但这样做会改变变更集的父级,它改变了它们的哈希值,这看起来就像发生在你身上的事情。再说一次,不是 hg-subversion 用户,所以我不能说拉/变基是否总是应该发生以及它应该如何工作,但是 hgsubversion wiki 页面说:
这使得它听起来通常不是自动的。
从你的介绍中我不太清楚,新的变更集是否仍在 svn 中创建,或者它们仅在 Mercurial 中创建?
如果它们仅在 Mercurial 中创建,那么一种解决方法是在远程系统上设置 svn-gateway 存储库,并从那里进行推送,并且永远不要从该存储库拉回 Mercurial。然后,由于变基,该存储库中的变更集将具有不同的哈希值,但它们不会流回主远程存储库和最终用户系统。
不过,更大的解决办法是弄清楚为什么“hg push svn://..正在重新调整所有出站变更集的基础”。回答这个问题,这种行为就会停止。
First, let me say what a pleasure it was to read such a detailed question write up. :)
The problem is happening when you do the
hg push
to the svn repo from remote. Here's that output from your example:I'm not a hg-subversion user, but that output says that in the process of doing the push you requested, it's pulling the changes from the svn repo, finding a new revision and then doing a
rebase
of your changeset10c1
after (descendent of) the newly pulled revision. The rebase command takes branching histories and turns the into linear histories, but in doing so it changes the parents of the changesets, which changes their hashes, which looks like just what's happening to you.Again, not a hg-subversion user, so I can't say if that pull/rebase is always supposed to happen and how that's supposed to work, but the hgsubversion wiki page says:
which makes it sound not normally automatic.
I couldn't quite tell from your intro, are new changesets still being created in svn, or are they created only in mercurial?
If they're only created in mercurial then one work-around would be to set up a svn-gateway repo on the remote system, and do the push from there, and never pull from that repo back into mercurial. Then the changesets in that repo would have different hashids due to the rebase, but they'd not flow back into the main remote repo and the end user systems.
The bigger fix though is to figure out why "hg push svn://.. is rebasing all the outbound changesets". Answer that one and the behavior will stop.
我们现在正在使用移植命令来执行类似的操作。实际上,我们在推送每个变更集之前重新创建它,以避免推送合并变更集。
我们的目标是干净地为使用 subversion 的项目做出贡献。
为您的所有更改创建一个 subversion 分支。在 Mercurial 中获取它。
$
cd [svn-checkout] ; svn cp 主干分支/hg-bridge
$ cd [hgsubversion 桥] ;汞拉; hg update hg-bridge
检查本地存储库是否有新更改
$
hg in [repo] # 显示;您稍后可以使用的 ID
从本地存储库将您想要进入 svn 的更改拉取
$
hg pull [repo]
移植您想要贡献的所有更改:
$
hgraft [rev] [rev] # rev 可以是 645 或 b7a92bbb0e0b。最好使用第二个>。
您需要单独指定每个转速,
但您可以在一个命令中移植多个转速。
检查您要推送的内容:
$
hg moving
推送更改:
$
hg 推送
这可能显示一些不相关的拉取修订
并且应该将您的新修订显示为已拉取,
以及备份包的路径(您不需要)。(注释也可以在 GPLv2 或更高版本下使用)
We are using the graft command now to do something similar to this. Effectively we recreate every changeset before pushing it to avoid having to push merge-changesets.
Our goal is to cleanly contribute to a project which uses subversion.
Create a subversion branch for all your changes. Get it in Mercurial.
$
cd [svn-checkout] ; svn cp trunk branches/hg-bridge
$
cd [hgsubversion bridge] ; hg pull ; hg update hg-bridge
Check your local repo for new changes
$
hg in [repo] # shows <rev> IDs you can use later
Pull the changes you want to get into svn from a local repo
$
hg pull [repo]
Graft all changes you want to contribute:
$
hg graft [rev] [rev] # rev could be 645 or b7a92bbb0e0b. Best use the second>.
You need to specify every rev individually,
but you can graft multiple revs in one command.
Check what you would push:
$
hg outgoing
Push the changes:
$
hg push
This might show some unrelated pulled revisions
and should show your new revisions as pulled,
along with paths to backup bundles (which you should not need).(comment can also be used under the GPLv2 or later)