convert: separate trunk detection from branch layout detection
authorEdouard Gomez <ed.gomez@free.fr>
Sat, 05 Jan 2008 01:51:21 +0100
changeset 5854 8b95f598097c
parent 5853 deb0d3518674
child 5855 a6ccb957fd07
convert: separate trunk detection from branch layout detection In some subversion repositories, trunk is present but no branches are used. The current code is assuming that both trunk and branches must exist before adding trunk's head to the heads list. It's just better to separate the branch layout stuff from the trunk one.
hgext/convert/subversion.py
tests/test-convert-svn-source
tests/test-convert-svn-source.out
--- a/hgext/convert/subversion.py	Sat Jan 12 20:49:07 2008 +0100
+++ b/hgext/convert/subversion.py	Sat Jan 05 01:51:21 2008 +0100
@@ -181,46 +181,48 @@
             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):
--- a/tests/test-convert-svn-source	Sat Jan 12 20:49:07 2008 +0100
+++ b/tests/test-convert-svn-source	Sat Jan 05 01:51:21 2008 +0100
@@ -120,3 +120,58 @@
 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 ..
--- a/tests/test-convert-svn-source.out	Sat Jan 12 20:49:07 2008 +0100
+++ b/tests/test-convert-svn-source.out	Sat Jan 05 01:51:21 2008 +0100
@@ -118,3 +118,71 @@
 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