Steps needed to allow hgsubversion SVN clone to push back
Asked Answered
G

1

7

I am working on a team that uses SVN primarily, whereas I prefer to use Mercurial when possible. I set up an hg clone of the SVN repo using hgsubversion, and several basic pulls/commits/pushes seemed to function fine.

Now after 2 weeks of local development (during which time I've merged in changes from an external hg repo, and merged in changes from the SVN repo multiple times), I've attempted to push to the SVN repo, but failed with this message:

abort: Sorry, can't find svn parent of a merge revision.

I've found other users encountering the same problem, with how-tos on how to avoid this issue going forward, but I haven't encountered anything that seems to address condensing multiple parallel commits to clean up an existing hgsubversion repo.

What is the best way that I can rectify matters without losing my own commits? (With step-by-step instructions?)

Gnosis answered 17/3, 2011 at 7:39 Comment(0)
C
9

You can't push hg merges into a subversion repository, since SVN can't understand them. You need to rebase your changes on top of the latest SVN commit.

Edit Steps to flatten the history:

Warning, be prepared to do have lots of merge conflicts

You need the mq and rebase extension activated

The first step is to create a backup repo, since you will need it as a reference for the upcoming merge conflicts (expect many of them).

Say your graph looks like this:

C1--C2--C3------M1--C5--C6--C7---M2--
  \            / \              /
   \--B1--B2--/   \--B3--B4-B5-/

Then the second step is to rebase B1+B2 on top of C3: hg rebase -b B2 -d C3

-b use the common base of both branches as the start for the branch to rebase, so mercurial finds that B1 is the first deviation commit und uses this even when you say B2 to rebase. -d specifies the destination of the rebased branch.

Wen you encounter merge conflicts then ensure that the result of B2' = M1, else you will get lots of conflicts in the following revisions.

Afterwards Merge M1 is gone and your graph looks like this:

C1--C2--C3--B1'--B2'--C5'--C6'--C7'---M2'--
                   \                 /
                    \--B3'--B4'-B5'-/

and now you do the same for the second merge: hg rebase -b B3' -d C7', which makes your repo look like this:

C1--C2--C3--B1'--B2'--C5'--C6'--C7'--B3''--B4''--B5''

Repeat until you have an all linear version history.

After you have flattened the history you need to reorder your commits on top of the svn commits. Say your repo now looks like this (S=subversion commit, C=local commit):

S1--S2--S3--C1--C2--S4--S5--C3-C4--C5--C6--C7--S6--S7

Now you import everything from (including) C1 into a mercurial queue (hg qimport -rC1:). To view all created patches use hg qseries.

Then you unapply all patches (hg qgoto C1.diff [this is the first one in qseries], followed by hg qpop). Then you remove the subversion ones (hg qdelete S4.diff S5.diff S6.diff S7.diff).

Now is the time to re-fetch the svn commits (hg pull »svn-remote«). Then you reapply all local patches, one by one with hg qpush, and fix all merge conflicts which are now occurring. When you are done with one conflict, you can move the current patch into a mercurial commit with hg qfinish -a, and send your current state with hg push »svn-remote«.

Claude answered 17/3, 2011 at 12:20 Comment(3)
Right, I've gathered that from other posts, after-the-fact. So, how can I fix what's already been done? (Which was my original question in fact)Gnosis
Ahhh, perfect. I had attempted to figure out how to make this happen using rebase & collapse, but didn't have the right commands. This is a great how-to, thanks. As I had to get my code committed to SVN sooner-than-later, I went ahead and created an SVN diff of my changed repo vs default SVN, and applied that as a single commit. History is lost for SVN, but thanks to your post, I now know how to repair this in the future if it happens again. CheersGnosis
@Jon Against the normal hg best practices it is better never to merge diverged history on a SVN connected repo. When you rebase your work after a pull from a svn repo, you are in a potential pushable state afterwards.Claude

© 2022 - 2024 — McMap. All rights reserved.