tags:

views:

367

answers:

4

Hi,

I know there is hgsubversion extension for mercurial. But before I knew how it works, I maintain two separate repositories, one is SVN repo and one is Hg repo. I made most of my recent changes in the Hg repository and I need to "push" them to the svn repository.

The most straight forward way to do this is to get one revision from svn which is in sync with one revision from hg.

From there, I update to the next revision (from Hg), then commit it (to svn). Repeating these steps for many changesets is rather inconvenient. Are there more convenient ways to do this?

And if possible, solution that works in Windows OS.

Regards,

Afriza

+1  A: 

If you're talking about a linear series of changesets (no merges) you could employ a shell for loop

for therev in $(seq $(hg id -n -r .) $(hg id -n -r tip)) ; do
  hg update $therev
  svn commit -m "$(hg log --template '{desc}' -r .)"
done

That loops from the checkedout revision to the tip and commits each in turn preserving the commit message. You probably need to do something fancy arround added/removes files.

Ry4an
I think I need to do 'svn addremove' (equivalent of 'hg addremove') before doing 'svn commit'. do you know how to do it?
afriza
I don't but presumably you just do a status and add anything that's unrecognized and remove anything that's missing. If there's not a built in command for it; it'd be easy to script. You could even get the list by using the lsdiff command on 'hg diff $therev' I'd imagine.
Ry4an
A: 

It looks like you could use hg convert to do what you want retroactively. Enable the ConvertExtension and then just do hg convert -d svn file/path/to/mercurial/repo svn://repo/path/ though I've not tried it.

Ry4an
After a quick look at hg help convert, It doesn't seem like it can handle which revision to start exporting, It only handles until which revision it should convert.
afriza
That's correct. It's incremental (detects already converted revisions) when the destination is mercurial, but I don't imagine that works with a svn destination.
Ry4an
+2  A: 
chinmaya
Nice! a hook to auto commit to svn. Btw, I cannot change the author of the svn commit during the commit, am I right? I need to set the svn property for author only after the commit, correct?
afriza
After looking at the docs, I think I should use 'incoming' hooks, but what is the equivalent of 'hg addremove' in svn? I need to 'svn addremove' before 'svn commit'
afriza
+1  A: 

I took Ry4an's answer and added add/remove handling. Here it is:

for therev in $(seq $(hg id -n -r .) $(hg id -n -r tip)) ; do
  hg update -C $therev
  svn st | perl -lne 'if (/^([?!])\s*(\S*)/) { my $command = ($1 eq "?") ? "add" : "rm"; my $fname=$2; $fname =~ s[\\][\/]g; system(qq(svn $command $fname));}'
  svn commit -m "$(hg log --template '{desc}' -r .)"
done

I found the -C was required when branches were involved. This gets pretty ugly, though, since files get removed and re-added when switching between branches. Also generally, renames info is lost, as well as the dates and identity of original commiter, of course.

itsadok
thanks for the effort : )
afriza
@afriza I actually did this for myself, just thought I'd share.
itsadok