def testComparison(self): """Verify CVS revision comparison is done right""" self.assertEqual(0, compare_cvs_revs('1.1', '1.1')) self.assertEqual(-1, compare_cvs_revs('1.1', '1.3')) self.assertEqual(-1, compare_cvs_revs('1.5', '1.51')) self.assertEqual(-1, compare_cvs_revs('1.1', '1.1.2.2'))
def already_applied(cs, entries=entries): "Loop over changeset entries to determine if it's already applied." applied = False # applied become True when an entry is DELETED *and* there is # no metainfo for it: thus, a changeset that removes a few entries # very late in history would be assumed as applied. Prevent that # by checking for at least one explicit match on an existing entry. onepositive = False for m in cs.entries: info = entries.getFileInfo(m.name) # If the entry's info exists, compare the on-disk # version with what we have: the revision is already # applied if the former is greater or equal than the # latter. The same if the info does not exist and it's # a delete event. if info: odversion = info.cvs_version applied = compare_cvs_revs(odversion, m.new_revision) >= 0 # If only one "hunk" is not yet applied, the whole # changeset is new. if not applied: break else: onepositive = True elif m.action_kind == ChangesetEntry.DELETED: applied = True return applied and onepositive
def changesets_from_cvsps(log, sincerev=None): """ Parse CVSps log. """ from datetime import datetime from vcpx.changes import Changeset, ChangesetEntry from vcpx.repository.cvs import compare_cvs_revs # cvsps output sample: ## --------------------- ## PatchSet 1500 ## Date: 2004/05/09 17:54:22 ## Author: grubert ## Branch: HEAD ## Tag: (none) ## Log: ## Tell the reason for using mbox (not wrapping long lines). ## ## Members: ## docutils/writers/latex2e.py:1.78->1.79 l = None while 1: l = log.readline() if l <> '---------------------\n': break l = log.readline() assert l.startswith('PatchSet '), "Parse error: %s" % l pset = {} pset['revision'] = l[9:-1].strip() l = log.readline() while not l.startswith('Log:'): field, value = l.split(':', 1) pset[field.lower()] = value.strip() l = log.readline() msg = [] l = log.readline() msg.append(l) l = log.readline() while l <> 'Members: \n': msg.append(l) l = log.readline() assert l.startswith('Members:'), "Parse error: %s" % l entries = [] l = log.readline() seen = {} while l.startswith('\t'): if not sincerev or (sincerev < int(pset['revision'])): # Cannot use split here, file may contain ':' cpos = l.rindex(':') file = l[1:cpos] revs = l[cpos + 1:-1] fromrev, torev = revs.strip().split('->') # Due to the fuzzy mechanism, cvsps may group # together two commits on a single entry, thus # giving something like: # # Normalizer.py:1.12->1.13 # Registry.py:1.22->1.23 # Registry.py:1.21->1.22 # Stopwords.py:1.9->1.10 # # Collapse those into a single one. e = seen.get(file) if not e: e = ChangesetEntry(file) e.old_revision = fromrev e.new_revision = torev seen[file] = e entries.append(e) else: if compare_cvs_revs(e.old_revision, fromrev) > 0: e.old_revision = fromrev if compare_cvs_revs(e.new_revision, torev) < 0: e.new_revision = torev if fromrev == 'INITIAL': e.action_kind = e.ADDED elif "(DEAD)" in torev: e.action_kind = e.DELETED e.new_revision = torev[:torev.index('(DEAD)')] else: e.action_kind = e.UPDATED l = log.readline() if not sincerev or (sincerev < int(pset['revision'])): cvsdate = pset['date'] y, m, d = map(int, cvsdate[:10].split('/')) hh, mm, ss = map(int, cvsdate[11:19].split(':')) timestamp = datetime(y, m, d, hh, mm, ss, 0, UTC) pset['date'] = timestamp yield Changeset(pset['revision'], timestamp, pset['author'], ''.join(msg), entries)
def changesets_from_cvsps(log, sincerev=None): """ Parse CVSps log. """ from datetime import datetime from vcpx.changes import Changeset, ChangesetEntry from vcpx.repository.cvs import compare_cvs_revs # cvsps output sample: ## --------------------- ## PatchSet 1500 ## Date: 2004/05/09 17:54:22 ## Author: grubert ## Branch: HEAD ## Tag: (none) ## Log: ## Tell the reason for using mbox (not wrapping long lines). ## ## Members: ## docutils/writers/latex2e.py:1.78->1.79 l = None while 1: l = log.readline() if l <> '---------------------\n': break l = log.readline() assert l.startswith('PatchSet '), "Parse error: %s"%l pset = {} pset['revision'] = l[9:-1].strip() l = log.readline() while not l.startswith('Log:'): field,value = l.split(':',1) pset[field.lower()] = value.strip() l = log.readline() msg = [] l = log.readline() msg.append(l) l = log.readline() while l <> 'Members: \n': msg.append(l) l = log.readline() assert l.startswith('Members:'), "Parse error: %s" % l entries = [] l = log.readline() seen = {} while l.startswith('\t'): if not sincerev or (sincerev<int(pset['revision'])): # Cannot use split here, file may contain ':' cpos = l.rindex(':') file = l[1:cpos] revs = l[cpos+1:-1] fromrev,torev = revs.strip().split('->') # Due to the fuzzy mechanism, cvsps may group # together two commits on a single entry, thus # giving something like: # # Normalizer.py:1.12->1.13 # Registry.py:1.22->1.23 # Registry.py:1.21->1.22 # Stopwords.py:1.9->1.10 # # Collapse those into a single one. e = seen.get(file) if not e: e = ChangesetEntry(file) e.old_revision = fromrev e.new_revision = torev seen[file] = e entries.append(e) else: if compare_cvs_revs(e.old_revision, fromrev)>0: e.old_revision = fromrev if compare_cvs_revs(e.new_revision, torev)<0: e.new_revision = torev if fromrev=='INITIAL': e.action_kind = e.ADDED elif "(DEAD)" in torev: e.action_kind = e.DELETED e.new_revision = torev[:torev.index('(DEAD)')] else: e.action_kind = e.UPDATED l = log.readline() if not sincerev or (sincerev<int(pset['revision'])): cvsdate = pset['date'] y,m,d = map(int, cvsdate[:10].split('/')) hh,mm,ss = map(int, cvsdate[11:19].split(':')) timestamp = datetime(y, m, d, hh, mm, ss, 0, UTC) pset['date'] = timestamp yield Changeset(pset['revision'], timestamp, pset['author'], ''.join(msg), entries)