cvsps
154 lines
| 5.9 KiB
| text/plain
|
TextLexer
Frank Kingswood
|
r6689 | #!/usr/bin/env python | ||
# | ||||
# Commandline front-end for cvsps.py | ||||
# | ||||
# Copyright 2008, Frank Kingswood <frank@kingswood-consulting.co.uk> | ||||
# | ||||
# This software may be used and distributed according to the terms | ||||
# of the GNU General Public License, incorporated herein by reference. | ||||
import sys | ||||
from mercurial import util | ||||
from mercurial.i18n import _ | ||||
from optparse import OptionParser, SUPPRESS_HELP | ||||
from hgext.convert.cvsps import createlog, createchangeset, logerror | ||||
def main(): | ||||
'''Main program to mimic cvsps.''' | ||||
op = OptionParser(usage='%prog [-bpruvxz] path', | ||||
description='Read CVS rlog for current directory or named ' | ||||
'path in repository, and convert the log to changesets ' | ||||
'based on matching commit log entries and dates.') | ||||
# Options that are ignored for compatibility with cvsps-2.1 | ||||
op.add_option('-A', dest='Ignore', action='store_true', help=SUPPRESS_HELP) | ||||
op.add_option('--cvs-direct', dest='Ignore', action='store_true', help=SUPPRESS_HELP) | ||||
op.add_option('-q', dest='Ignore', action='store_true', help=SUPPRESS_HELP) | ||||
# Main options shared with cvsps-2.1 | ||||
op.add_option('-b', dest='Branches', action='append', default=[], | ||||
help='Only return changes on specified branches') | ||||
op.add_option('-p', dest='Prefix', action='store', default='', | ||||
help='Prefix to remove from file names') | ||||
op.add_option('-r', dest='Revisions', action='append', default=[], | ||||
help='Only return changes after or between specified tags') | ||||
op.add_option('-u', dest='Cache', action='store_const', const='update', | ||||
help="Update cvs log cache") | ||||
op.add_option('-v', dest='Verbose', action='count', default=0, | ||||
help='Be verbose') | ||||
op.add_option('-x', dest='Cache', action='store_const', const='write', | ||||
help="Create new cvs log cache") | ||||
op.add_option('-z', dest='Fuzz', action='store', type='int', default=60, | ||||
help='Set commit time fuzz', metavar='seconds') | ||||
op.add_option('--root', dest='Root', action='store', default='', | ||||
help='Specify cvsroot', metavar='cvsroot') | ||||
# Options specific to this version | ||||
op.add_option('--parents', dest='Parents', action='store_true', | ||||
help='Show parent changesets') | ||||
op.add_option('--ancestors', dest='Ancestors', action='store_true', | ||||
help='Show current changeset in ancestor branches') | ||||
options, args = op.parse_args() | ||||
# Create a ui object for printing progress messages | ||||
class UI: | ||||
def __init__(self, verbose): | ||||
if verbose: | ||||
self.status = self.message | ||||
if verbose>1: | ||||
self.note = self.message | ||||
if verbose>2: | ||||
self.debug = self.message | ||||
def message(self, msg): | ||||
sys.stderr.write(msg) | ||||
def nomessage(self, msg): | ||||
pass | ||||
status = nomessage | ||||
note = nomessage | ||||
debug = nomessage | ||||
ui = UI(options.Verbose) | ||||
try: | ||||
if args: | ||||
log = [] | ||||
for d in args: | ||||
log += createlog(ui, d, root=options.Root, cache=options.Cache) | ||||
else: | ||||
log = createlog(ui, root=options.Root, cache=options.Cache) | ||||
except logerror, e: | ||||
print e | ||||
return | ||||
changesets = createchangeset(ui, log, options.Fuzz) | ||||
del log | ||||
# Print changesets (optionally filtered) | ||||
off = len(options.Revisions) | ||||
branches = {} # latest version number in each branch | ||||
ancestors = {} # parent branch | ||||
for cs in changesets: | ||||
if options.Ancestors: | ||||
if cs.branch not in branches and cs.parents and cs.parents[0].id: | ||||
ancestors[cs.branch] = changesets[cs.parents[0].id-1].branch, cs.parents[0].id | ||||
branches[cs.branch] = cs.id | ||||
# limit by branches | ||||
if options.Branches and (cs.branch or 'HEAD') not in options.Branches: | ||||
continue | ||||
if not off: | ||||
# Note: trailing spaces on several lines here are needed to have | ||||
# bug-for-bug compatibility with cvsps. | ||||
print '---------------------' | ||||
print 'PatchSet %d ' % cs.id | ||||
print 'Date: %s' % util.datestr(cs.date, '%Y/%m/%d %H:%M:%S %1%2') | ||||
print 'Author: %s' % cs.author | ||||
print 'Branch: %s' % (cs.branch or 'HEAD') | ||||
print 'Tag%s: %s ' % (['', 's'][len(cs.tags)>1], | ||||
','.join(cs.tags) or '(none)') | ||||
if options.Parents and cs.parents: | ||||
if len(cs.parents)>1: | ||||
print 'Parents: %s' % (','.join([str(p.id) for p in cs.parents])) | ||||
else: | ||||
print 'Parent: %d' % cs.parents[0].id | ||||
if options.Ancestors: | ||||
b = cs.branch | ||||
r = [] | ||||
while b: | ||||
b, c = ancestors[b] | ||||
r.append('%s:%d:%d' % (b or "HEAD", c, branches[b])) | ||||
if r: | ||||
print 'Ancestors: %s' % (','.join(r)) | ||||
print 'Log:' | ||||
print cs.comment | ||||
print 'Members: ' | ||||
for f in cs.entries: | ||||
fn = f.file | ||||
if fn.startswith(options.Prefix): | ||||
fn = fn[len(options.Prefix):] | ||||
print '\t%s:%s->%s%s ' % (fn, '.'.join([str(x) for x in f.parent]) or 'INITIAL', | ||||
'.'.join([str(x) for x in f.revision]), ['', '(DEAD)'][f.dead]) | ||||
# have we seen the start tag? | ||||
if options.Revisions and off: | ||||
if options.Revisions[0] == str(cs.id) or \ | ||||
options.Revisions[0] in cs.tags: | ||||
off = False | ||||
# see if we reached the end tag | ||||
if len(options.Revisions)>1 and not off: | ||||
if options.Revisions[1] == str(cs.id) or \ | ||||
options.Revisions[1] in cs.tags: | ||||
break | ||||
if __name__ == '__main__': | ||||
main() | ||||