views:

51

answers:

2

Hi,

I've began work in an SVN repository. I've cloned a subfolder of it into a local Hg repo with hg clone.

Afterwards, I wanted to share this with a colleague who does not have access to the SVN repository. I've created a private BitBucket repository, and we occasionally pushed the changes, and hence I had to pull them.

hgsubversion does some nasty things to changesets, such as changing their committer (and I believe even the hash). When I tried pushing and pulling to the BitBucket repo, I had to do a merge.

Now I am unable to push changes back into the Subversion repository due to our beloved friend, abort: Sorry, can't find svn parent of a merge revision..

How would one pull the BitBucket-targetting Mercurial repository with the svn-targetting Mercurial repository, while staying compatible with hgsubversion (that is, without importing the merge revisions)?

Some automated way to do this would be appreciated, of course, but if there is no such thing/easy way to do this, I'd be grateful for any solution.

I use hgsubversion, not hgsvn; that is, the extension in which one does hg clone svn://repo/url. I am open to switching, though, if necessary.

+4  A: 

When you use Mercurial on a subversion repository, you have to still think like SVN does, so a lot of features part of the basic mercurial workflow just won't work. Merging the way mercurial does it is impossible on a svn depot. If you have merged your work with the pulled svn branch, you'll get the infamous about message you're getting now :(

I suggest you read durin42's answer to this question.

EDIT : To get out of your current mess, I suggest you create a patch (or a series of patches) from the point you checkout from the SVN repo. Get a new fresh copy from the subversion repository and apply the patch(es). I am not sure you'll be able to do it from your current repo. You could explore the hg diff command.

hg diff -g -r tip -r XXX > patch

with XXX being your original SVN checkout (I haven't tested it yet.)

Eric-Karl
-1. I'm trying to find a way to convert a hg repository into a hgsubversion repository after messing it up with hg-only operations. "You can't do it, and should not do it" -- I could come up with that myself, but I nevertheless want to import the changes back into the Subversion repo, flattening the history no matter what.
Ivan Vučica
Understanding why it didn't work is the first step towards finding a solution. I updated my answer hoping this would help. I'm not on a computer with mercurial installed, so I haven't tested. But that's the way I would try that.
Eric-Karl
I'll write a script that takes out incremental diffs, but also preserves the log messages. -1 => +1, and accept. Thanks!
Ivan Vučica
+2  A: 

Yes, hgsubversion does change the committer name because it must reflect the name assigned by Subversion. Hgsubversion must then also change the changeset hash. It is not really something that hgsubversion can decide -- it's built into the design of Mercurial that the changeset hash is based on all information in the changeset and that included the name of the committer.

Please read my hgsubversion guide for information on how to work correctly with hgsubversion. The important points to remember is that hgsubversion turns hg into a better svn, but it is still Subversion that is the master. This means that you must linearize your history before pushing it back to Subversion so no merges or other funny DVCS things.

If you do want to take advantage of the distributed features in Mercurial, then do it in small iterations: do some collaboration in Mercurial, linearize the changesets and push back to Subversion, destroy the non-linear part of your clones, pull from Subversion. You can then repeat with a new iterations of collaboration in Mercurial.

Martin Geisler
Thanks! Vote up; as mentioned in another comment, I'll write a script to linearize history manually, preserving just the changeset contents and log messages.
Ivan Vučica