tags:

views:

36

answers:

2

The system of record is an SVN repository, but for whatever reasons, I've pulled the repository into Mercurial. I don't want to use the hgsubversion extension because it doesn't recommend creating extra clones and branches and so forth.

I would like to be able to do my own development in Mecurial however I wish and then apply a giant patch (or small patch) against my SVN working copy with changes whenever I like.

So I have:

/dev/repos/hg/project/master
/dev/repos/hg/project/master-feature-foo
...

On the Mercurial side and on the SVN side I have:

/dev/repos/svn/project

I would like to be able overwrite my SVN working copy, /dev/repos/svn/project , with the contents of my mercurial working copy, say /dev/repos/hg/project/master-feature-foo .

Which Mercurial and SVN commands facilitate this? I'm looking at the docs for hg diff, hg export and TortoiseSVN apply patch now for clues, but I haven't found the solution yet.

Thanks, Lloyd

+2  A: 

You have several options to transfer the tip to you svn directory:

hg diff & patch:

cd /svn/working/copy
hg -R /hg/working/copy -r svn.15500:tip | patch -p1`

copying changed files

#!/bin/bash
REV=$1
HG=/hg/working/copy

cd /svn/working/copy

# copy changed files, tar is used instead of cp to preserve file paths
hg -R $HG st --rev $REV:tip -man0 | xargs -0 tar -cC $HG | tar x

# add new files, cuses warnings if there are no new files
hg -R $HG st --rev $REV:tip -an0 | xargs -0 svn add

# remove deleted files, will cause warnings if there are no deleted files
hg -R $HG st --rev $REV:tip -rn0 | xargs svn rm

Another way is to use tortoisehg, where along with the rebase extension cloning is possible. This would be the following workflow:

hgimportsvn http://svn.server/repo/trunk
cd trunk
hgpullsvn
cd ..
hg clone trunk work
cd work
#Hack Hack Hack

cd ../trunk
hgpullsvn
# if there are new revisions rebase ../work before pull
hg pull ../work
hgpushsvn

#rebase
cd work
hg pull --rebase
Rudi
A: 

What I ended up doing was rather lame (I think). My goal was to take the contents of my Mercurial repository and overwrite my SVN working copy with them (so I can commit them to SVN later). I don't really care about the detailed history of the changes from Mercurial - the commit will be "rolled up" in the SVN repo.

Non-working approach, A1: delete SVN working copy contents and then copy over the Mercurial working copy.

Will not work because ... the .svn folders get destroyed.

Working approach, A2: Use the find command to delete everything but the .svn folders from the SVN working copy. Then just copy the Mecurial working copy over. SVN will detect the changes and allow me to commit.

Problems with approach A2: 1. It's manual. 2. If any directories are empty, Mercurial won't be tracking those, but they will be in the SVN repository (I haven't had this problem, but it could happen). 3. Lose Mecurial history on the SVN side. There's not much you can do about this since the SVN metadata is not as rich as Mercurial's. 4. Only good when one developer is committing in the SVN repo. If multiple devs are committing, then you will have to synchronize with all of their changes, including syncing those changes with all clones.

Advantages with approach A2:

1) It's easy.

In the svn working copy root, run this command:

# delete all files in an SVN working copy, except those
# in the .svn folders; directories are not deleted
find . -path "*.svn" -prune -o -type f -exec rm -v {} +

Use the file manager to drag the Mecurial working copy contents into the SVN working copy (you can use a script for this).

Use TortoiseSVN to commit (you can verify all the changes easily that way).

With that said, I'll accept the previous answer as it's probably The Right Way to do it.

LES2