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.
--- 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