diff --git a/hgext/convert/cvs.py b/hgext/convert/cvs.py --- a/hgext/convert/cvs.py +++ b/hgext/convert/cvs.py @@ -53,11 +53,13 @@ class convert_cvs(converter_source): os.chdir(self.path) id = None state = 0 + filerevids = {} for l in util.popen(cmd): if state == 0: # header if l.startswith("PatchSet"): id = l[9:-2] if maxrev and int(id) > maxrev: + # ignore everything state = 3 elif l.startswith("Date"): date = util.parsedate(l[6:-1], ["%Y/%m/%d %H:%M:%S"]) @@ -68,7 +70,8 @@ class convert_cvs(converter_source): self.lastbranch[branch] = id elif l.startswith("Ancestor branch"): ancestor = l[17:-1] - self.parent[id] = self.lastbranch[ancestor] + # figure out the parent later + self.parent[id] = None elif l.startswith("Author"): author = self.recode(l[8:-1]) elif l.startswith("Tag:") or l.startswith("Tags:"): @@ -77,23 +80,36 @@ class convert_cvs(converter_source): if (len(t) > 1) or (t[0] and (t[0] != "(none)")): self.tags.update(dict.fromkeys(t, id)) elif l.startswith("Log:"): + # switch to gathering log state = 1 log = "" elif state == 1: # log if l == "Members: \n": + # switch to gathering members files = {} + oldrevs = [] log = self.recode(log[:-1]) state = 2 else: + # gather log log += l - elif state == 2: - if l == "\n": # + elif state == 2: # members + if l == "\n": # start of next entry state = 0 p = [self.parent[id]] if id == "1": p = [] if branch == "HEAD": branch = "" + if branch and p[0] == None: + latest = None + # the last changeset that contains a base + # file is our parent + for r in oldrevs: + latest = max(filerevids[r], latest) + p = [latest] + + # add current commit to set c = commit(author=author, date=date, parents=p, desc=log, branch=branch) self.changeset[id] = c @@ -102,9 +118,14 @@ class convert_cvs(converter_source): colon = l.rfind(':') file = l[1:colon] rev = l[colon+1:-2] - rev = rev.split("->")[1] + oldrev, rev = rev.split("->") files[file] = rev + + # save some information for identifying branch points + oldrevs.append("%s:%s" % (oldrev, file)) + filerevids["%s:%s" % (rev, file)] = id elif state == 3: + # swallow all input continue self.heads = self.lastbranch.values() diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py --- a/hgext/convert/hg.py +++ b/hgext/convert/hg.py @@ -30,6 +30,8 @@ class mercurial_sink(converter_sink): if os.path.isdir(path) and len(os.listdir(path)) > 0: try: self.repo = hg.repository(self.ui, path) + if not self.repo.local(): + raise NoRepo(_('%s is not a local Mercurial repo') % path) except hg.RepoError, err: ui.print_exc() raise NoRepo(err.args[0]) @@ -37,6 +39,8 @@ class mercurial_sink(converter_sink): try: ui.status(_('initializing destination %s repository\n') % path) self.repo = hg.repository(self.ui, path, create=True) + if not self.repo.local(): + raise NoRepo(_('%s is not a local Mercurial repo') % path) self.created.append(path) except hg.RepoError, err: ui.print_exc() diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py --- a/hgext/convert/subversion.py +++ b/hgext/convert/subversion.py @@ -646,7 +646,7 @@ class svn_source(converter_source): # '2007-01-04T17:35:00.902377Z' date = util.parsedate(date[:19] + " UTC", ["%Y-%m-%dT%H:%M:%S"]) - log = message and self.recode(message) + log = message and self.recode(message) or '' author = author and self.recode(author) or '' try: branch = self.module.split("/")[-1] diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -15,7 +15,7 @@ platform-specific details from the core. from i18n import _ import cStringIO, errno, getpass, popen2, re, shutil, sys, tempfile, strutil import os, stat, threading, time, calendar, ConfigParser, locale, glob, osutil -import re, urlparse +import urlparse try: set = set diff --git a/tests/test-convert-cvs b/tests/test-convert-cvs --- a/tests/test-convert-cvs +++ b/tests/test-convert-cvs @@ -71,3 +71,25 @@ hg convert --filemap filemap src src-fil cat src-hg/b/c hg -R src-filemap log --template '#rev# #desc# files: #files#\n' +echo % commit branch +cd src +cvs -q update -r1.1 b/c +cvs -q tag -b branch +cvs -q update -r branch +echo d >> b/c +cvs -q commit -mci2 . | grep '<--' |\ + sed -e 's:.*src/\(.*\),v.*:checking in src/\1,v:g' +cd .. + +echo % convert again +hg convert src src-hg | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g' +cat src-hg/a +cat src-hg/b/c + +echo % convert again with --filemap +hg convert --filemap filemap src src-filemap | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g' +cat src-hg/b/c +hg -R src-filemap log --template '#rev# #desc# files: #files#\n' + +echo "graphlog = " >> $HGRCPATH +hg -R src-hg glog --template '#rev# (#branches#) #desc# files: #files#\n' diff --git a/tests/test-convert-cvs.out b/tests/test-convert-cvs.out --- a/tests/test-convert-cvs.out +++ b/tests/test-convert-cvs.out @@ -67,3 +67,43 @@ 3 ci1 files: b/c 2 update tags files: .hgtags 1 ci0 files: b/c 0 Initial revision files: b/c +% commit branch +U b/c +T a +T b/c +checking in src/b/c,v +% convert again +connecting to cvsrepo +scanning source... +sorting... +converting... +0 ci2 +a +a +c +d +% convert again with --filemap +connecting to cvsrepo +scanning source... +sorting... +converting... +0 ci2 +c +d +4 ci2 files: b/c +3 ci1 files: b/c +2 update tags files: .hgtags +1 ci0 files: b/c +0 Initial revision files: b/c +o 5 (branch) ci2 files: b/c +| +| o 4 () ci1 files: a b/c +| | +| o 3 () update tags files: .hgtags +| | +| o 2 () ci0 files: b/c +|/ +| o 1 (INITIAL) import files: +|/ +o 0 () Initial revision files: a b/c +