--- a/hgext/convert/cvs.py Sun Jun 15 15:59:53 2008 +0100
+++ b/hgext/convert/cvs.py Sun Jun 15 16:05:46 2008 +0100
@@ -3,8 +3,10 @@
import os, locale, re, socket
from cStringIO import StringIO
from mercurial import util
+from mercurial.i18n import _
from common import NoRepo, commit, converter_source, checktool
+import cvsps
class convert_cvs(converter_source):
def __init__(self, ui, path, rev=None):
@@ -14,10 +16,13 @@
if not os.path.exists(cvs):
raise NoRepo("%s does not look like a CVS checkout" % path)
+ checktool('cvs')
self.cmd = ui.config('convert', 'cvsps', 'cvsps -A -u --cvs-direct -q')
cvspsexe = self.cmd.split(None, 1)[0]
- for tool in (cvspsexe, 'cvs'):
- checktool(tool)
+ self.builtin = cvspsexe == 'builtin'
+
+ if not self.builtin:
+ checktool(cvspsexe)
self.changeset = {}
self.files = {}
@@ -28,10 +33,11 @@
self.cvsroot = file(os.path.join(cvs, "Root")).read()[:-1]
self.cvsrepo = file(os.path.join(cvs, "Repository")).read()[:-1]
self.encoding = locale.getpreferredencoding()
- self._parse()
+
+ self._parse(ui)
self._connect()
- def _parse(self):
+ def _parse(self, ui):
if self.changeset:
return
@@ -56,80 +62,114 @@
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"])
- date = util.datestr(date)
- elif l.startswith("Branch"):
- branch = l[8:-1]
- self.parent[id] = self.lastbranch.get(branch, 'bad')
- self.lastbranch[branch] = id
- elif l.startswith("Ancestor branch"):
- ancestor = l[17:-1]
- # figure out the parent later
- self.parent[id] = self.lastbranch[ancestor]
- elif l.startswith("Author"):
- author = self.recode(l[8:-1])
- elif l.startswith("Tag:") or l.startswith("Tags:"):
- t = l[l.index(':')+1:]
- t = [ut.strip() for ut in t.split(',')]
- 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: # members
- if l == "\n": # start of next entry
- state = 0
- p = [self.parent[id]]
- if id == "1":
- p = []
- if branch == "HEAD":
- branch = ""
- if branch:
- latest = None
- # the last changeset that contains a base
- # file is our parent
- for r in oldrevs:
- latest = max(filerevids.get(r, None), latest)
- if latest:
- p = [latest]
+
+ if self.builtin:
+ # builtin cvsps code
+ ui.status(_('using builtin cvsps\n'))
+
+ db = cvsps.createlog(ui, cache='update')
+ db = cvsps.createchangeset(ui, db,
+ fuzz=int(ui.config('convert', 'cvsps.fuzz', 60)),
+ mergeto=ui.config('convert', 'cvsps.mergeto', None),
+ mergefrom=ui.config('convert', 'cvsps.mergefrom', None))
+
+ for cs in db:
+ if maxrev and cs.id>maxrev:
+ break
+ id = str(cs.id)
+ cs.author = self.recode(cs.author)
+ self.lastbranch[cs.branch] = id
+ cs.comment = self.recode(cs.comment)
+ date = util.datestr(cs.date)
+ self.tags.update(dict.fromkeys(cs.tags, id))
+
+ files = {}
+ for f in cs.entries:
+ files[f.file] = "%s%s" % ('.'.join([str(x) for x in f.revision]),
+ ['', '(DEAD)'][f.dead])
- # add current commit to set
- c = commit(author=author, date=date, parents=p,
- desc=log, branch=branch)
- self.changeset[id] = c
- self.files[id] = files
- else:
- colon = l.rfind(':')
- file = l[1:colon]
- rev = l[colon+1:-2]
- oldrev, rev = rev.split("->")
- files[file] = rev
+ # add current commit to set
+ c = commit(author=cs.author, date=date,
+ parents=[str(p.id) for p in cs.parents],
+ desc=cs.comment, branch=cs.branch or '')
+ self.changeset[id] = c
+ self.files[id] = files
+ else:
+ # external cvsps
+ 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"])
+ date = util.datestr(date)
+ elif l.startswith("Branch"):
+ branch = l[8:-1]
+ self.parent[id] = self.lastbranch.get(branch, 'bad')
+ self.lastbranch[branch] = id
+ elif l.startswith("Ancestor branch"):
+ ancestor = l[17:-1]
+ # figure out the parent later
+ self.parent[id] = self.lastbranch[ancestor]
+ elif l.startswith("Author"):
+ author = self.recode(l[8:-1])
+ elif l.startswith("Tag:") or l.startswith("Tags:"):
+ t = l[l.index(':')+1:]
+ t = [ut.strip() for ut in t.split(',')]
+ 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: # members
+ if l == "\n": # start of next entry
+ state = 0
+ p = [self.parent[id]]
+ if id == "1":
+ p = []
+ if branch == "HEAD":
+ branch = ""
+ if branch:
+ latest = None
+ # the last changeset that contains a base
+ # file is our parent
+ for r in oldrevs:
+ latest = max(filerevids.get(r, None), latest)
+ if latest:
+ p = [latest]
- # 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
+ # add current commit to set
+ c = commit(author=author, date=date, parents=p,
+ desc=log, branch=branch)
+ self.changeset[id] = c
+ self.files[id] = files
+ else:
+ colon = l.rfind(':')
+ file = l[1:colon]
+ rev = l[colon+1:-2]
+ 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()
finally: