diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py --- a/hgext/convert/subversion.py +++ b/hgext/convert/subversion.py @@ -181,46 +181,48 @@ class svn_source(converter_source): return False def getheads(self): - # detect standard /branches, /tags, /trunk layout + + def getcfgpath(name, rev): + cfgpath = self.ui.config('convert', 'svn.' + name) + path = (cfgpath or name).strip('/') + if not self.exists(path, rev): + if cfgpath: + raise util.Abort(_('expected %s to be at %r, but not found') + % (name, path)) + return None + self.ui.note(_('found %s at %r\n') % (name, path)) + return path + rev = optrev(self.last_changed) - rpath = self.url.strip('/') - cfgtrunk = self.ui.config('convert', 'svn.trunk') - cfgbranches = self.ui.config('convert', 'svn.branches') - cfgtags = self.ui.config('convert', 'svn.tags') - trunk = (cfgtrunk or 'trunk').strip('/') - branches = (cfgbranches or 'branches').strip('/') - tags = (cfgtags or 'tags').strip('/') - if self.exists(trunk, rev) and self.exists(branches, rev) and self.exists(tags, rev): - self.ui.note('found trunk at %r, branches at %r and tags at %r\n' % - (trunk, branches, tags)) - oldmodule = self.module + oldmodule = '' + trunk = getcfgpath('trunk', rev) + tags = getcfgpath('tags', rev) + branches = getcfgpath('branches', rev) + + # If the project has a trunk or branches, we will extract heads + # from them. We keep the project root otherwise. + if trunk: + oldmodule = self.module or '' self.module += '/' + trunk lt = self.latest(self.module, self.last_changed) self.head = self.revid(lt) - self.heads = [self.head] + + # First head in the list is the module's head + self.heads = [self.head] + self.tags = '%s/%s' % (oldmodule , (tags or 'tags')) + + # Check if branches bring a few more heads to the list + if branches: + rpath = self.url.strip('/') branchnames = svn.client.ls(rpath + '/' + branches, rev, False, self.ctx) for branch in branchnames.keys(): - if oldmodule: - module = oldmodule + '/' + branches + '/' + branch - else: - module = '/' + branches + '/' + branch + module = '%s/%s/%s' % (oldmodule, branches, branch) brevnum = self.latest(module, self.last_changed) brev = self.revid(brevnum, module) self.ui.note('found branch %s at %d\n' % (branch, brevnum)) self.heads.append(brev) - if oldmodule: - self.tags = '%s/%s' % (oldmodule, tags) - else: - self.tags = '/%s' % tags - - elif cfgtrunk or cfgbranches or cfgtags: - raise util.Abort('trunk/branch/tags layout expected, but not found') - else: - self.ui.note('working with one branch\n') - self.heads = [self.head] - self.tags = tags return self.heads def getfile(self, file, rev): diff --git a/tests/test-convert-svn-source b/tests/test-convert-svn-source --- a/tests/test-convert-svn-source +++ b/tests/test-convert-svn-source @@ -120,3 +120,58 @@ cd A-hg hg glog --template '#rev# #desc|firstline# files: #files#\n' hg tags -q cd .. + +######################################## + +echo "# now tests that it works with trunk/tags layout, but no branches yet" +echo +echo % initial svn import +mkdir projB +cd projB +mkdir trunk +mkdir tags +cd .. + +svnurl=file://$svnpath/svn-repo/projB +svn import -m "init projB" projB $svnurl | fix_path + + +echo % update svn repository +svn co $svnurl/trunk B | fix_path +cd B +echo hello > letter.txt +svn add letter.txt +svn ci -m hello + +echo world >> letter.txt +svn ci -m world + +svn copy -m "tag v0.1" $svnurl/trunk $svnurl/tags/v0.1 + +echo 'nice day today!' >> letter.txt +svn ci -m "nice day" +cd .. + +echo % convert to hg once +hg convert $svnurl B-hg + +echo % update svn repository again +cd B +echo "see second letter" >> letter.txt +echo "nice to meet you" > letter2.txt +svn add letter2.txt +svn ci -m "second letter" + +svn copy -m "tag v0.2" $svnurl/trunk $svnurl/tags/v0.2 + +echo "blah-blah-blah" >> letter2.txt +svn ci -m "work in progress" +cd .. + +echo % test incremental conversion +hg convert $svnurl B-hg + +cd B-hg +hg glog --template '#rev# #desc|firstline# files: #files#\n' +hg tags -q +cd .. diff --git a/tests/test-convert-svn-source.out b/tests/test-convert-svn-source.out --- a/tests/test-convert-svn-source.out +++ b/tests/test-convert-svn-source.out @@ -118,3 +118,71 @@ o 0 init projA files: tip v0.2 v0.1 +# now tests that it works with trunk/tags layout, but no branches yet + +% initial svn import +Adding projB/trunk +Adding projB/tags + +Committed revision 12. +% update svn repository +Checked out revision 12. +A letter.txt +Adding letter.txt +Transmitting file data . +Committed revision 13. +Sending letter.txt +Transmitting file data . +Committed revision 14. + +Committed revision 15. +Sending letter.txt +Transmitting file data . +Committed revision 16. +% convert to hg once +initializing destination B-hg repository +scanning source... +sorting... +converting... +3 init projB +2 hello +1 world +0 nice day +updating tags +% update svn repository again +A letter2.txt +Sending letter.txt +Adding letter2.txt +Transmitting file data .. +Committed revision 17. + +Committed revision 18. +Sending letter2.txt +Transmitting file data . +Committed revision 19. +% test incremental conversion +scanning source... +sorting... +converting... +1 second letter +0 work in progress +updating tags +o 7 update tags files: .hgtags +| +o 6 work in progress files: letter2.txt +| +o 5 second letter files: letter.txt letter2.txt +| +o 4 update tags files: .hgtags +| +o 3 nice day files: letter.txt +| +o 2 world files: letter.txt +| +o 1 hello files: letter.txt +| +o 0 init projB files: + +tip +v0.2 +v0.1