# HG changeset patch # User Patrick Mezard # Date 1229035003 -3600 # Node ID b3ae5d52c405453c14856fa39cea2a7b5357c249 # Parent d8cd79fbed3c7b358dd820ff5dee44a7cff362bc# Parent 8e76e9f67cb3414f9b7042435758d375dc505ea2 Merge with crew-stable diff -r 8e76e9f67cb3 -r b3ae5d52c405 contrib/zsh_completion --- a/contrib/zsh_completion Thu Dec 11 22:59:35 2008 +0100 +++ b/contrib/zsh_completion Thu Dec 11 23:36:43 2008 +0100 @@ -4,14 +4,13 @@ # it into your zsh function path (/usr/share/zsh/site-functions for # instance) # -# Copyright (C) 2005 Steve Borho +# Copyright (C) 2005-6 Steve Borho # Copyright (C) 2006-8 Brendan Cully # # This is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your # option) any later version. -# emulate -LR zsh setopt extendedglob @@ -117,28 +116,54 @@ _hg_get_commands() { typeset -ga _hg_cmd_list typeset -gA _hg_alias_list - local hline cmd cmdalias - _call_program help hg --verbose help | while read -A hline + local hline cmd cmdalias helpstate + local helpmode=$1 + + _call_program help hg --verbose help $helpmode 2>/dev/null | while read -A hline do - cmd="$hline[1]" - case $cmd in - *:) - cmd=${cmd%:} - _hg_cmd_list+=($cmd) - ;; - *,) - cmd=${cmd%,} - _hg_cmd_list+=($cmd) - integer i=2 - while (( i <= $#hline )) - do - cmdalias=${hline[$i]%(:|,)} - _hg_cmd_list+=($cmdalias) - _hg_alias_list+=($cmdalias $cmd) - (( i++ )) - done - ;; - esac + if [ "$hline" = "list of commands:" ] + then + helpstate="commands" + continue + elif [ "$hline" = "enabled extensions:" ] + then + helpstate="extensions" + continue + elif [ "$hline" = "additional help topics:" ] + then + helpstate="topics" + continue + fi + + if [ "$helpstate" = commands ] + then + cmd="$hline[1]" + case $cmd in + *:) + cmd=${cmd%:} + _hg_cmd_list+=($cmd) + ;; + *,) + cmd=${cmd%,} + _hg_cmd_list+=($cmd) + integer i=2 + while (( i <= $#hline )) + do + cmdalias=${hline[$i]%(:|,)} + _hg_cmd_list+=($cmdalias) + _hg_alias_list+=($cmdalias $cmd) + (( i++ )) + done + ;; + esac + elif [ -z "$helpmode" -a "$helpstate" = extensions ] + then + cmd="$hline[1]" + if [ -n "$cmd" ] + then + _hg_get_commands $cmd + fi + fi done } diff -r 8e76e9f67cb3 -r b3ae5d52c405 hgext/bookmarks.py --- a/hgext/bookmarks.py Thu Dec 11 22:59:35 2008 +0100 +++ b/hgext/bookmarks.py Thu Dec 11 23:36:43 2008 +0100 @@ -14,9 +14,19 @@ It is possible to use bookmark names in every revision lookup (e.g. hg merge, hg update). + +The bookmark extension offers the possiblity to have a more git-like experience +by adding the following configuration option to your .hgrc: + +[bookmarks] +track.current = True + +This will cause bookmarks to track the bookmark that you are currently on, and +just updates it. This is similar to git's approach of branching. ''' from mercurial.commands import templateopts, hex, short +from mercurial import extensions from mercurial.i18n import _ from mercurial import cmdutil, util, commands, changelog from mercurial.node import nullid, nullrev @@ -55,10 +65,53 @@ if os.path.exists(repo.join('bookmarks')): util.copyfile(repo.join('bookmarks'), repo.join('undo.bookmarks')) file = repo.opener('bookmarks', 'w+') + if current(repo) not in refs: + setcurrent(repo, None) for refspec, node in refs.items(): file.write("%s %s\n" % (hex(node), refspec)) file.close() +def current(repo): + '''Get the current bookmark + + If we use gittishsh branches we have a current bookmark that + we are on. This function returns the name of the bookmark. It + is stored in .hg/bookmarks.current + ''' + if repo._bookmarkcurrent: + return repo._bookmarkcurrent + mark = None + if os.path.exists(repo.join('bookmarks.current')): + file = repo.opener('bookmarks.current') + mark = file.readline() + if mark == '': + mark = None + file.close() + repo._bookmarkcurrent = mark + return mark + +def setcurrent(repo, mark): + '''Set the name of the bookmark that we are currently on + + Set the name of the bookmark that we are on (hg update ). + The name is recoreded in .hg/bookmarks.current + ''' + if current(repo) == mark: + return + + refs = parse(repo) + + # do not update if we do update to a rev equal to the current bookmark + if (mark not in refs and + current(repo) and refs[current(repo)] == repo.changectx('.').node()): + return + if mark not in refs: + mark = '' + file = repo.opener('bookmarks.current', 'w+') + file.write(mark) + file.close() + repo._bookmarkcurrent = mark + def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False, rename=None): '''mercurial bookmarks @@ -121,7 +174,11 @@ ui.status("no bookmarks set\n") else: for bmark, n in marks.iteritems(): - prefix = (n == cur) and '*' or ' ' + if ui.configbool('bookmarks', 'track.current'): + prefix = (bmark == current(repo) and n == cur) and '*' or ' ' + else: + prefix = (n == cur) and '*' or ' ' + ui.write(" %s %-25s %d:%s\n" % ( prefix, bmark, repo.changelog.rev(n), hexfn(n))) return @@ -166,6 +223,7 @@ # init a bookmark cache as otherwise we would get a infinite reading # in lookup() repo._bookmarks = None + repo._bookmarkcurrent = None class bookmark_repo(repo.__class__): def rollback(self): @@ -192,9 +250,14 @@ marks = parse(repo) update = False for mark, n in marks.items(): - if n in parents: - marks[mark] = node - update = True + if ui.configbool('bookmarks', 'track.current'): + if mark == current(repo) and n in parents: + marks[mark] = node + update = True + else: + if n in parents: + marks[mark] = node + update = True if update: write(repo, marks) return node @@ -218,8 +281,35 @@ write(repo, marks) return result + def tags(self): + """Merge bookmarks with normal tags""" + if self.tagscache: + return self.tagscache + + tagscache = super(bookmark_repo, self).tags() + tagscache.update(parse(repo)) + return tagscache + repo.__class__ = bookmark_repo +def updatecurbookmark(orig, ui, repo, *args, **opts): + '''Set the current bookmark + + If the user updates to a bookmark we update the .hg/bookmarks.current + file. + ''' + res = orig(ui, repo, *args, **opts) + rev = opts['rev'] + if not rev and len(args) > 0: + rev = args[0] + setcurrent(repo, rev) + return res + +def uisetup(ui): + 'Replace push with a decorator to provide --non-bookmarked option' + if ui.configbool('bookmarks', 'track.current'): + extensions.wrapcommand(commands.table, 'update', updatecurbookmark) + cmdtable = { "bookmarks": (bookmark, diff -r 8e76e9f67cb3 -r b3ae5d52c405 hgext/bugzilla.py --- a/hgext/bugzilla.py Thu Dec 11 22:59:35 2008 +0100 +++ b/hgext/bugzilla.py Thu Dec 11 23:36:43 2008 +0100 @@ -4,53 +4,107 @@ # # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. -# -# hook extension to update comments of bugzilla bugs when changesets -# that refer to bugs by id are seen. this hook does not change bug -# status, only comments. -# -# to configure, add items to '[bugzilla]' section of hgrc. -# -# to use, configure bugzilla extension and enable like this: -# -# [extensions] -# hgext.bugzilla = -# -# [hooks] -# # run bugzilla hook on every change pulled or pushed in here -# incoming.bugzilla = python:hgext.bugzilla.hook -# -# config items: -# -# section name is 'bugzilla'. -# [bugzilla] -# -# REQUIRED: -# host = bugzilla # mysql server where bugzilla database lives -# password = ** # user's password -# version = 2.16 # version of bugzilla installed -# -# OPTIONAL: -# bzuser = ... # fallback bugzilla user name to record comments with -# db = bugs # database to connect to -# notify = ... # command to run to get bugzilla to send mail -# regexp = ... # regexp to match bug ids (must contain one "()" group) -# strip = 0 # number of slashes to strip for url paths -# style = ... # style file to use when formatting comments -# template = ... # template to use when formatting comments -# timeout = 5 # database connection timeout (seconds) -# user = bugs # user to connect to database as -# [web] -# baseurl = http://hgserver/... # root of hg web site for browsing commits -# -# if hg committer names are not same as bugzilla user names, use -# "usermap" feature to map from committer email to bugzilla user name. -# usermap can be in hgrc or separate config file. -# -# [bugzilla] -# usermap = filename # cfg file with "committer"="bugzilla user" info -# [usermap] -# committer_email = bugzilla_user_name + +'''Bugzilla integration + +This hook extension adds comments on bugs in Bugzilla when changesets +that refer to bugs by Bugzilla ID are seen. The hook does not change bug +status. + +The hook updates the Bugzilla database directly. Only Bugzilla installations +using MySQL are supported. + +The hook relies on a Bugzilla script to send bug change notification emails. +That script changes between Bugzilla versions; the 'processmail' script used +prior to 2.18 is replaced in 2.18 and subsequent versions by +'config/sendbugmail.pl'. Note that these will be run by Mercurial as the user +pushing the change; you will need to ensure the Bugzilla install file +permissions are set appropriately. + +Configuring the extension: + + [bugzilla] + host Hostname of the MySQL server holding the Bugzilla database. + db Name of the Bugzilla database in MySQL. Default 'bugs'. + user Username to use to access MySQL server. Default 'bugs'. + password Password to use to access MySQL server. + timeout Database connection timeout (seconds). Default 5. + version Bugzilla version. Specify '3.0' for Bugzilla versions from + 3.0 onwards, and '2.16' for versions prior to 3.0. + bzuser Fallback Bugzilla user name to record comments with, if + changeset committer cannot be found as a Bugzilla user. + notify The command to run to get Bugzilla to send bug change + notification emails. Substitutes one string parameter, + the bug ID. Default 'cd /var/www/html/bugzilla && ' + './processmail %s nobody@nowhere.com'. + regexp Regular expression to match bug IDs in changeset commit message. + Must contain one "()" group. The default expression matches + 'Bug 1234', 'Bug no. 1234', 'Bug number 1234', + 'Bugs 1234,5678', 'Bug 1234 and 5678' and variations thereof. + Matching is case insensitive. + style The style file to use when formatting comments. + template Template to use when formatting comments. Overrides + style if specified. In addition to the usual Mercurial + keywords, the extension specifies: + {bug} The Bugzilla bug ID. + {root} The full pathname of the Mercurial repository. + {webroot} Stripped pathname of the Mercurial repository. + {hgweb} Base URL for browsing Mercurial repositories. + Default 'changeset {node|short} in repo {root} refers ' + 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}' + strip The number of slashes to strip from the front of {root} + to produce {webroot}. Default 0. + usermap Path of file containing Mercurial committer ID to Bugzilla user + ID mappings. If specified, the file should contain one mapping + per line, "committer"="Bugzilla user". See also the + [usermap] section. + + [usermap] + Any entries in this section specify mappings of Mercurial committer ID + to Bugzilla user ID. See also [bugzilla].usermap. + "committer"="Bugzilla user" + + [web] + baseurl Base URL for browsing Mercurial repositories. Reference from + templates as {hgweb}. + +Activating the extension: + + [extensions] + hgext.bugzilla = + + [hooks] + # run bugzilla hook on every change pulled or pushed in here + incoming.bugzilla = python:hgext.bugzilla.hook + +Example configuration: + +This example configuration is for a collection of Mercurial repositories +in /var/local/hg/repos/ used with a local Bugzilla 3.2 installation in +/opt/bugzilla-3.2. + + [bugzilla] + host=localhost + password=XYZZY + version=3.0 + bzuser=unknown@domain.com + notify=cd /opt/bugzilla-3.2 && perl -T contrib/sendbugmail.pl %%s bugmail@domain.com + template=Changeset {node|short} in {root|basename}.\\n{hgweb}/{webroot}/rev/{node|short}\\n\\n{desc}\\n + strip=5 + + [web] + baseurl=http://dev.domain.com/hg + + [usermap] + user@emaildomain.com=user.name@bugzilladomain.com + +Commits add a comment to the Bugzilla bug record of the form: + + Changeset 3b16791d6642 in repository-name. + http://dev.domain.com/hg/repository-name/rev/3b16791d6642 + + Changeset commit comment. Bug 1234. +''' from mercurial.i18n import _ from mercurial.node import short @@ -185,6 +239,7 @@ self.run('''insert into bugs_activity (bug_id, who, bug_when, fieldid) values (%s, %s, %s, %s)''', (bugid, userid, now, self.longdesc_id)) + self.conn.commit() class bugzilla_3_0(bugzilla_2_16): '''support for bugzilla 3.0 series.''' diff -r 8e76e9f67cb3 -r b3ae5d52c405 hgext/convert/__init__.py --- a/hgext/convert/__init__.py Thu Dec 11 22:59:35 2008 +0100 +++ b/hgext/convert/__init__.py Thu Dec 11 23:36:43 2008 +0100 @@ -7,6 +7,7 @@ '''converting foreign VCS repositories to Mercurial''' import convcmd +import cvsps from mercurial import commands from mercurial.i18n import _ @@ -183,7 +184,18 @@ def debugsvnlog(ui, **opts): return convcmd.debugsvnlog(ui, **opts) -commands.norepo += " convert debugsvnlog" +def debugcvsps(ui, *args, **opts): + '''Create changeset information from CVS + + This command is intended as a debugging tool for the CVS to Mercurial + converter, and can be used as a direct replacement for cvsps. + + Hg debugcvsps reads the CVS rlog for current directory (or any named + directory) in the CVS repository, and converts the log to a series of + changesets based on matching commit log entries and dates.''' + return cvsps.debugcvsps(ui, *args, **opts) + +commands.norepo += " convert debugsvnlog debugcvsps" cmdtable = { "convert": @@ -200,4 +212,22 @@ (debugsvnlog, [], 'hg debugsvnlog'), + "debugcvsps": + (debugcvsps, + [ + # Main options shared with cvsps-2.1 + ('b', 'branches', [], _('Only return changes on specified branches')), + ('p', 'prefix', '', _('Prefix to remove from file names')), + ('r', 'revisions', [], _('Only return changes after or between specified tags')), + ('u', 'update-cache', None, _("Update cvs log cache")), + ('x', 'new-cache', None, _("Create new cvs log cache")), + ('z', 'fuzz', 60, _('Set commit time fuzz in seconds')), + ('', 'root', '', _('Specify cvsroot')), + # Options specific to builtin cvsps + ('', 'parents', '', _('Show parent changesets')), + ('', 'ancestors', '', _('Show current changeset in ancestor branches')), + # Options that are ignored for compatibility with cvsps-2.1 + ('A', 'cvs-direct', None, 'Ignored for compatibility'), + ], + 'hg debugcvsps [OPTION]... [PATH]...'), } diff -r 8e76e9f67cb3 -r b3ae5d52c405 hgext/convert/cvs.py --- a/hgext/convert/cvs.py Thu Dec 11 22:59:35 2008 +0100 +++ b/hgext/convert/cvs.py Thu Dec 11 23:36:43 2008 +0100 @@ -144,11 +144,11 @@ if branch == "HEAD": branch = "" if branch: - latest = None + latest = 0 # the last changeset that contains a base # file is our parent for r in oldrevs: - latest = max(filerevids.get(r, None), latest) + latest = max(filerevids.get(r, 0), latest) if latest: p = [latest] diff -r 8e76e9f67cb3 -r b3ae5d52c405 hgext/convert/cvsps --- a/hgext/convert/cvsps Thu Dec 11 22:59:35 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +0,0 @@ -#!/usr/bin/env python -# -# Commandline front-end for cvsps.py -# -# Copyright 2008, Frank Kingswood -# -# 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 - 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]) - print - - # 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() diff -r 8e76e9f67cb3 -r b3ae5d52c405 hgext/convert/cvsps.py --- a/hgext/convert/cvsps.py Thu Dec 11 22:59:35 2008 +0100 +++ b/hgext/convert/cvsps.py Thu Dec 11 23:36:43 2008 +0100 @@ -584,3 +584,95 @@ ui.status(_('%d changeset entries\n') % len(changesets)) return changesets + + +def debugcvsps(ui, *args, **opts): + '''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.''' + + if opts["new_cache"]: + cache = "write" + elif opts["update_cache"]: + cache = "update" + else: + cache = None + + revisions = opts["revisions"] + + try: + if args: + log = [] + for d in args: + log += createlog(ui, d, root=opts["root"], cache=cache) + else: + log = createlog(ui, root=opts["root"], cache=cache) + except logerror, e: + ui.write("%r\n"%e) + return + + changesets = createchangeset(ui, log, opts["fuzz"]) + del log + + # Print changesets (optionally filtered) + + off = len(revisions) + branches = {} # latest version number in each branch + ancestors = {} # parent branch + for cs in changesets: + + if opts["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 opts["branches"] and (cs.branch or 'HEAD') not in opts["branches"]: + continue + + if not off: + # Note: trailing spaces on several lines here are needed to have + # bug-for-bug compatibility with cvsps. + ui.write('---------------------\n') + ui.write('PatchSet %d \n' % cs.id) + ui.write('Date: %s\n' % util.datestr(cs.date, '%Y/%m/%d %H:%M:%S %1%2')) + ui.write('Author: %s\n' % cs.author) + ui.write('Branch: %s\n' % (cs.branch or 'HEAD')) + ui.write('Tag%s: %s \n' % (['', 's'][len(cs.tags)>1], + ','.join(cs.tags) or '(none)')) + if opts["parents"] and cs.parents: + if len(cs.parents)>1: + ui.write('Parents: %s\n' % (','.join([str(p.id) for p in cs.parents]))) + else: + ui.write('Parent: %d\n' % cs.parents[0].id) + + if opts["ancestors"]: + b = cs.branch + r = [] + while b: + b, c = ancestors[b] + r.append('%s:%d:%d' % (b or "HEAD", c, branches[b])) + if r: + ui.write('Ancestors: %s\n' % (','.join(r))) + + ui.write('Log:\n') + ui.write('%s\n\n' % cs.comment) + ui.write('Members: \n') + for f in cs.entries: + fn = f.file + if fn.startswith(opts["prefix"]): + fn = fn[len(opts["prefix"]):] + ui.write('\t%s:%s->%s%s \n' % (fn, '.'.join([str(x) for x in f.parent]) or 'INITIAL', + '.'.join([str(x) for x in f.revision]), ['', '(DEAD)'][f.dead])) + ui.write('\n') + + # have we seen the start tag? + if revisions and off: + if revisions[0] == str(cs.id) or \ + revisions[0] in cs.tags: + off = False + + # see if we reached the end tag + if len(revisions)>1 and not off: + if revisions[1] == str(cs.id) or \ + revisions[1] in cs.tags: + break diff -r 8e76e9f67cb3 -r b3ae5d52c405 mercurial/changelog.py --- a/mercurial/changelog.py Thu Dec 11 22:59:35 2008 +0100 +++ b/mercurial/changelog.py Thu Dec 11 23:36:43 2008 +0100 @@ -179,7 +179,7 @@ user = user.strip() if "\n" in user: - raise RevlogError(_("username %s contains a newline") % `user`) + raise RevlogError(_("username %s contains a newline") % repr(user)) user, desc = util.fromlocal(user), util.fromlocal(desc) if date: diff -r 8e76e9f67cb3 -r b3ae5d52c405 mercurial/dispatch.py --- a/mercurial/dispatch.py Thu Dec 11 22:59:35 2008 +0100 +++ b/mercurial/dispatch.py Thu Dec 11 23:36:43 2008 +0100 @@ -90,7 +90,7 @@ else: raise except socket.error, inst: - ui.warn(_("abort: %s\n") % inst[-1]) + ui.warn(_("abort: %s\n") % inst.args[-1]) except IOError, inst: if hasattr(inst, "code"): ui.warn(_("abort: %s\n") % inst) @@ -100,7 +100,7 @@ except: # it might be anything, for example a string reason = inst.reason ui.warn(_("abort: error: %s\n") % reason) - elif hasattr(inst, "args") and inst[0] == errno.EPIPE: + elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE: if ui.debugflag: ui.warn(_("broken pipe\n")) elif getattr(inst, "strerror", None): @@ -116,13 +116,13 @@ else: ui.warn(_("abort: %s\n") % inst.strerror) except util.UnexpectedOutput, inst: - ui.warn(_("abort: %s") % inst[0]) - if not isinstance(inst[1], basestring): - ui.warn(" %r\n" % (inst[1],)) - elif not inst[1]: + ui.warn(_("abort: %s") % inst.args[0]) + if not isinstance(inst.args[1], basestring): + ui.warn(" %r\n" % (inst.args[1],)) + elif not inst.args[1]: ui.warn(_(" empty string\n")) else: - ui.warn("\n%r\n" % util.ellipsis(inst[1])) + ui.warn("\n%r\n" % util.ellipsis(inst.args[1])) except ImportError, inst: m = str(inst).split()[-1] ui.warn(_("abort: could not import module %s!\n") % m) diff -r 8e76e9f67cb3 -r b3ae5d52c405 mercurial/ui.py --- a/mercurial/ui.py Thu Dec 11 22:59:35 2008 +0100 +++ b/mercurial/ui.py Thu Dec 11 23:36:43 2008 +0100 @@ -350,7 +350,7 @@ if not user: raise util.Abort(_("Please specify a username.")) if "\n" in user: - raise util.Abort(_("username %s contains a newline\n") % `user`) + raise util.Abort(_("username %s contains a newline\n") % repr(user)) return user def shortuser(self, user): diff -r 8e76e9f67cb3 -r b3ae5d52c405 mercurial/util.py --- a/mercurial/util.py Thu Dec 11 22:59:35 2008 +0100 +++ b/mercurial/util.py Thu Dec 11 23:36:43 2008 +0100 @@ -705,7 +705,7 @@ if cwd is not None and oldcwd != cwd: os.chdir(oldcwd) -class SignatureError: +class SignatureError(Exception): pass def checksignature(func): diff -r 8e76e9f67cb3 -r b3ae5d52c405 mercurial/util_win32.py --- a/mercurial/util_win32.py Thu Dec 11 22:59:35 2008 +0100 +++ b/mercurial/util_win32.py Thu Dec 11 23:36:43 2008 +0100 @@ -19,7 +19,7 @@ import util from win32com.shell import shell,shellcon -class WinError: +class WinError(Exception): winerror_map = { winerror.ERROR_ACCESS_DENIED: errno.EACCES, winerror.ERROR_ACCOUNT_DISABLED: errno.EACCES, diff -r 8e76e9f67cb3 -r b3ae5d52c405 tests/test-bdiff --- a/tests/test-bdiff Thu Dec 11 22:59:35 2008 +0100 +++ b/tests/test-bdiff Thu Dec 11 23:36:43 2008 +0100 @@ -9,13 +9,13 @@ if d: c = mpatch.patches(a, [d]) if c != b: - print "***", `a`, `b` + print "***", repr(a), repr(b) print "bad:" - print `c`[:200] - print `d` + print repr(c)[:200] + print repr(d) def test(a, b): - print "***", `a`, `b` + print "***", repr(a), repr(b) test1(a, b) test1(b, a) diff -r 8e76e9f67cb3 -r b3ae5d52c405 tests/test-bookmarks-rebase.out --- a/tests/test-bookmarks-rebase.out Thu Dec 11 22:59:35 2008 +0100 +++ b/tests/test-bookmarks-rebase.out Thu Dec 11 23:36:43 2008 +0100 @@ -18,6 +18,8 @@ rebase completed changeset: 3:9163974d1cb5 tag: tip +tag: two +tag: one parent: 1:925d80f479bb parent: 2:db815d6d32e6 user: test diff -r 8e76e9f67cb3 -r b3ae5d52c405 tests/test-bookmarks.out --- a/tests/test-bookmarks.out Thu Dec 11 22:59:35 2008 +0100 +++ b/tests/test-bookmarks.out Thu Dec 11 23:36:43 2008 +0100 @@ -7,6 +7,7 @@ * X 0:f7b1eb17ad24 % look up bookmark changeset: 0:f7b1eb17ad24 +tag: X tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 @@ -51,7 +52,10 @@ * x y 2:0316ce92851d % look up stripped bookmark name changeset: 2:0316ce92851d +tag: X2 +tag: Y tag: tip +tag: x y user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: 2 diff -r 8e76e9f67cb3 -r b3ae5d52c405 tests/test-convert-cvs-builtincvsps --- a/tests/test-convert-cvs-builtincvsps Thu Dec 11 22:59:35 2008 +0100 +++ b/tests/test-convert-cvs-builtincvsps Thu Dec 11 23:36:43 2008 +0100 @@ -102,3 +102,7 @@ echo "graphlog = " >> $HGRCPATH hg -R src-hg glog --template '#rev# (#branches#) #desc# files: #files#\n' + +echo % testing debugcvsps +cd src +hg debugcvsps | sed -e 's/Author:.*/Author:/' -e 's/Date:.*/Date:/' diff -r 8e76e9f67cb3 -r b3ae5d52c405 tests/test-convert-cvs-builtincvsps.out --- a/tests/test-convert-cvs-builtincvsps.out Thu Dec 11 22:59:35 2008 +0100 +++ b/tests/test-convert-cvs-builtincvsps.out Thu Dec 11 23:36:43 2008 +0100 @@ -136,3 +136,71 @@ |/ o 0 () Initial revision files: a b/c +% testing debugcvsps +collecting CVS rlog +8 log entries +creating changesets +5 changeset entries +--------------------- +PatchSet 1 +Date: +Author: +Branch: HEAD +Tag: (none) +Log: +Initial revision + +Members: + a:INITIAL->1.1 + b/c:INITIAL->1.1 + +--------------------- +PatchSet 2 +Date: +Author: +Branch: INITIAL +Tag: start +Log: +import + +Members: + a:1.1->1.1.1.1 + b/c:1.1->1.1.1.1 + +--------------------- +PatchSet 3 +Date: +Author: +Branch: HEAD +Tag: (none) +Log: +ci0 + +Members: + b/c:1.1->1.2 + +--------------------- +PatchSet 4 +Date: +Author: +Branch: HEAD +Tag: (none) +Log: +ci1 + +Members: + a:1.1->1.2 + b/c:1.2->1.3 + +--------------------- +PatchSet 5 +Date: +Author: +Branch: branch +Tag: (none) +Log: +ci2 + +Members: + b/c:1.1->1.1.2.1 + diff -r 8e76e9f67cb3 -r b3ae5d52c405 tests/test-walkrepo.py --- a/tests/test-walkrepo.py Thu Dec 11 22:59:35 2008 +0100 +++ b/tests/test-walkrepo.py Thu Dec 11 23:36:43 2008 +0100 @@ -24,26 +24,26 @@ reposet = frozenset(walkrepos('.', followsym=True)) if sym and (len(reposet) != 3): print "reposet = %r" % (reposet,) - raise SystemExit(1, "Found %d repositories when I should have found 3" % (len(reposet),)) + print "Found %d repositories when I should have found 3" % (len(reposet),) if (not sym) and (len(reposet) != 2): print "reposet = %r" % (reposet,) - raise SystemExit(1, "Found %d repositories when I should have found 2" % (len(reposet),)) + print "Found %d repositories when I should have found 2" % (len(reposet),) sub1set = frozenset((pjoin('.', 'sub1'), pjoin('.', 'circle', 'subdir', 'sub1'))) if len(sub1set & reposet) != 1: print "sub1set = %r" % (sub1set,) print "reposet = %r" % (reposet,) - raise SystemExit(1, "sub1set and reposet should have exactly one path in common.") + print "sub1set and reposet should have exactly one path in common." sub2set = frozenset((pjoin('.', 'subsub1'), pjoin('.', 'subsubdir', 'subsub1'))) if len(sub2set & reposet) != 1: print "sub2set = %r" % (sub2set,) print "reposet = %r" % (reposet,) - raise SystemExit(1, "sub1set and reposet should have exactly one path in common.") + print "sub1set and reposet should have exactly one path in common." sub3 = pjoin('.', 'circle', 'top1') if sym and not (sub3 in reposet): print "reposet = %r" % (reposet,) - raise SystemExit(1, "Symbolic links are supported and %s is not in reposet" % (sub3,)) + print "Symbolic links are supported and %s is not in reposet" % (sub3,) runtest() if sym: