Mercurial to Mercurial to Subversion Workflow Problem

╄→尐↘猪︶ㄣ 提交于 2019-11-28 05:00:41

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:

  1. using Mercurial as a client for Subversion, without exchanging changes outside of svn
  2. Converting Subversion repositories to Mercurial

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.

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:

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

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 changeset 10c1 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:

You can use the usual Mercurial commands to work with this repository. If you have a series of commits on a given branch, and want to move them to the tip of that branch, use the hg rebase --svn command while on the tip of your work, and those changesets will automatically be rebased over top of the new upstream work.

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.

Arne Babenhauserheide

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)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!