Mercurial > hg
changeset 7631:0b2ee57dfdb1
Merge with crew-stable
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Tue, 13 Jan 2009 23:17:19 +0100 |
parents | 97253bcb44a8 (diff) a679bd371091 (current diff) |
children | 9626819b2e3d |
files | mercurial/merge.py |
diffstat | 97 files changed, 1334 insertions(+), 701 deletions(-) [+] |
line wrap: on
line diff
--- a/contrib/zsh_completion Tue Jan 13 22:41:06 2009 +0100 +++ b/contrib/zsh_completion Tue Jan 13 23:17:19 2009 +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 <brendan@kublai.com> # # 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 @@ -118,27 +117,17 @@ typeset -ga _hg_cmd_list typeset -gA _hg_alias_list local hline cmd cmdalias - _call_program help hg --verbose help | while read -A hline + + _call_program hg hg debugcomplete -v 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 + cmd=$hline[1] + _hg_cmd_list+=($cmd) + + for cmdalias in $hline[2,-1] + do + _hg_cmd_list+=($cmdalias) + _hg_alias_list+=($cmdalias $cmd) + done done }
--- a/hgext/bookmarks.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/bookmarks.py Tue Jan 13 23:17:19 2009 +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 @@ -54,11 +64,54 @@ ''' if os.path.exists(repo.join('bookmarks')): util.copyfile(repo.join('bookmarks'), repo.join('undo.bookmarks')) + if current(repo) not in refs: + setcurrent(repo, None) file = repo.opener('bookmarks', 'w+') - for refspec, node in refs.items(): + for refspec, node in refs.iteritems(): 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 <bookmark>). + 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 @@ -85,6 +138,8 @@ raise util.Abort(_("new bookmark name required")) marks[mark] = marks[rename] del marks[rename] + if current(repo) == rename: + setcurrent(repo, mark) write(repo, marks) return @@ -121,7 +176,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 @@ -147,7 +206,7 @@ revisions = _revstostrip(repo.changelog, node) marks = parse(repo) update = [] - for mark, n in marks.items(): + for mark, n in marks.iteritems(): if repo.changelog.rev(n) in revisions: update.append(mark) oldstrip(ui, repo, node, backup) @@ -166,6 +225,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 +252,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 +283,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,
--- a/hgext/bugzilla.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/bugzilla.py Tue Jan 13 23:17:19 2009 +0100 @@ -4,53 +4,111 @@ # # 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 3.0 and + later, '2.18' for Bugzilla versions from 2.18 and '2.16' for + versions prior to 2.18. + bzuser Fallback Bugzilla user name to record comments with, if + changeset committer cannot be found as a Bugzilla user. + bzdir Bugzilla install directory. Used by default notify. + Default '/var/www/html/bugzilla'. + notify The command to run to get Bugzilla to send bug change + notification emails. Substitutes from a map with 3 keys, + 'bzdir', 'id' (bug id) and 'user' (committer bugzilla email). + Default depends on version; from 2.18 it is + "cd %(bzdir)s && perl -T contrib/sendbugmail.pl %(id)s %(user)s". + 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 + bzdir=/opt/bugzilla-3.2 + 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 @@ -82,6 +140,7 @@ self.cursor = self.conn.cursor() self.longdesc_id = self.get_longdesc_id() self.user_ids = {} + self.default_notify = "cd %(bzdir)s && ./processmail %(id)s %(user)s" def run(self, *args, **kwargs): '''run a query.''' @@ -118,15 +177,23 @@ unknown.pop(id, None) return util.sort(unknown.keys()) - def notify(self, ids): + def notify(self, ids, committer): '''tell bugzilla to send mail.''' self.ui.status(_('telling bugzilla to send mail:\n')) + (user, userid) = self.get_bugzilla_user(committer) for id in ids: self.ui.status(_(' bug %s\n') % id) - cmd = self.ui.config('bugzilla', 'notify', - 'cd /var/www/html/bugzilla && ' - './processmail %s nobody@nowhere.com') % id + cmdfmt = self.ui.config('bugzilla', 'notify', self.default_notify) + bzdir = self.ui.config('bugzilla', 'bzdir', '/var/www/html/bugzilla') + try: + # Backwards-compatible with old notify string, which + # took one string. This will throw with a new format + # string. + cmd = cmdfmt % id + except TypeError: + cmd = cmdfmt % {'bzdir': bzdir, 'id': id, 'user': user} + self.ui.note(_('running notify command %s\n') % cmd) fp = util.popen('(%s) 2>&1' % cmd) out = fp.read() ret = fp.close() @@ -161,9 +228,10 @@ return bzuser return user - def add_comment(self, bugid, text, committer): - '''add comment to bug. try adding comment as committer of - changeset, otherwise as default bugzilla user.''' + def get_bugzilla_user(self, committer): + '''see if committer is a registered bugzilla user. Return + bugzilla username and userid if so. If not, return default + bugzilla username and userid.''' user = self.map_committer(committer) try: userid = self.get_user_id(user) @@ -174,9 +242,16 @@ raise util.Abort(_('cannot find bugzilla user id for %s') % user) userid = self.get_user_id(defaultuser) + user = defaultuser except KeyError: raise util.Abort(_('cannot find bugzilla user id for %s or %s') % (user, defaultuser)) + return (user, userid) + + def add_comment(self, bugid, text, committer): + '''add comment to bug. try adding comment as committer of + changeset, otherwise as default bugzilla user.''' + (user, userid) = self.get_bugzilla_user(committer) now = time.strftime('%Y-%m-%d %H:%M:%S') self.run('''insert into longdescs (bug_id, who, bug_when, thetext) @@ -185,12 +260,20 @@ 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): +class bugzilla_2_18(bugzilla_2_16): + '''support for bugzilla 2.18 series.''' + + def __init__(self, ui): + bugzilla_2_16.__init__(self, ui) + self.default_notify = "cd %(bzdir)s && perl -T contrib/sendbugmail.pl %(id)s %(user)s" + +class bugzilla_3_0(bugzilla_2_18): '''support for bugzilla 3.0 series.''' def __init__(self, ui): - bugzilla_2_16.__init__(self, ui) + bugzilla_2_18.__init__(self, ui) def get_longdesc_id(self): '''get identity of longdesc field''' @@ -205,6 +288,7 @@ # different schemas. _versions = { '2.16': bugzilla_2_16, + '2.18': bugzilla_2_18, '3.0': bugzilla_3_0 } @@ -320,7 +404,7 @@ if ids: for id in ids: bz.update(id, ctx) - bz.notify(ids) + bz.notify(ids, util.email(ctx.user())) except MySQLdb.MySQLError, err: raise util.Abort(_('database error: %s') % err[1])
--- a/hgext/churn.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/churn.py Tue Jan 13 23:17:19 2009 +0100 @@ -12,27 +12,6 @@ import os, sys import time, datetime -def get_tty_width(): - if 'COLUMNS' in os.environ: - try: - return int(os.environ['COLUMNS']) - except ValueError: - pass - try: - import termios, array, fcntl - for dev in (sys.stdout, sys.stdin): - try: - fd = dev.fileno() - if not os.isatty(fd): - continue - arri = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * 8) - return array.array('h', arri)[1] - except ValueError: - pass - except ImportError: - pass - return 80 - def maketemplater(ui, repo, tmpl): tmpl = templater.parsestring(tmpl, quoted=False) try: @@ -100,7 +79,7 @@ newpct = int(100.0 * count / max(len(repo), 1)) if pct < newpct: pct = newpct - ui.write(_("\rGenerating stats: %d%%") % pct) + ui.write(_("\rgenerating stats: %d%%") % pct) sys.stdout.flush() if opts.get('progress'): @@ -111,7 +90,7 @@ def churn(ui, repo, *pats, **opts): - '''Graph count of revisions grouped by template + '''graph count of revisions grouped by template Will graph count of changed lines or revisions grouped by template or alternatively by date, if dateformat is used. In this case it will override @@ -157,7 +136,7 @@ maxcount = float(max([v for k, v in rate])) maxname = max([len(k) for k, v in rate]) - ttywidth = get_tty_width() + ttywidth = util.termwidth() ui.debug(_("assuming %i character terminal\n") % ttywidth) width = ttywidth - maxname - 2 - 6 - 2 - 2
--- a/hgext/color.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/color.py Tue Jan 13 23:17:19 2009 +0100 @@ -204,6 +204,7 @@ _diff_prefixes = [('diff', 'diffline'), ('copy', 'extended'), ('rename', 'extended'), + ('old', 'extended'), ('new', 'extended'), ('deleted', 'extended'), ('---', 'file_a'),
--- a/hgext/convert/__init__.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/convert/__init__.py Tue Jan 13 23:17:19 2009 +0100 @@ -7,13 +7,14 @@ '''converting foreign VCS repositories to Mercurial''' import convcmd +import cvsps from mercurial import commands from mercurial.i18n import _ # Commands definition was moved elsewhere to ease demandload job. def convert(ui, src, dest=None, revmapfile=None, **opts): - """Convert a foreign SCM repository to a Mercurial one. + """convert a foreign SCM repository to a Mercurial one. Accepted source formats [identifiers]: - Mercurial [hg] @@ -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]...'), }
--- a/hgext/convert/common.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/convert/common.py Tue Jan 13 23:17:19 2009 +0100 @@ -228,7 +228,9 @@ except TypeError: pass cmdline = [util.shellquote(arg) for arg in cmdline] - cmdline += ['2>', util.nulldev, '<', util.nulldev] + if not self.ui.debugflag: + cmdline += ['2>', util.nulldev] + cmdline += ['<', util.nulldev] cmdline = ' '.join(cmdline) return cmdline
--- a/hgext/convert/convcmd.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/convert/convcmd.py Tue Jan 13 23:17:19 2009 +0100 @@ -206,7 +206,7 @@ _('Overriding mapping for author %s, was %s, will be %s\n') % (srcauthor, self.authors[srcauthor], dstauthor)) else: - self.ui.debug(_('Mapping author %s to %s\n') + self.ui.debug(_('mapping author %s to %s\n') % (srcauthor, dstauthor)) self.authors[srcauthor] = dstauthor except IndexError:
--- a/hgext/convert/cvs.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/convert/cvs.py Tue Jan 13 23:17:19 2009 +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]
--- a/hgext/convert/cvsps Tue Jan 13 22:41:06 2009 +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 <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 - 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()
--- a/hgext/convert/cvsps.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/convert/cvsps.py Tue Jan 13 23:17:19 2009 +0100 @@ -191,7 +191,13 @@ ui.note(_("running %s\n") % (' '.join(cmd))) ui.debug(_("prefix=%r directory=%r root=%r\n") % (prefix, directory, root)) - for line in util.popen(' '.join(cmd)): + pfp = util.popen(' '.join(cmd)) + peek = pfp.readline() + while True: + line = peek + if line == '': + break + peek = pfp.readline() if line.endswith('\n'): line = line[:-1] #ui.debug('state=%d line=%r\n' % (state, line)) @@ -263,7 +269,7 @@ if re_31.match(line): state = 5 else: - assert not re_32.match(line), _('Must have at least some revisions') + assert not re_32.match(line), _('must have at least some revisions') elif state == 5: # expecting revision number and possibly (ignored) lock indication @@ -312,7 +318,7 @@ e.branches = [tuple([int(y) for y in x.strip().split('.')]) for x in m.group(1).split(';')] state = 8 - elif re_31.match(line): + elif re_31.match(line) and re_50.match(peek): state = 5 store = True elif re_32.match(line): @@ -584,3 +590,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
--- a/hgext/convert/darcs.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/convert/darcs.py Tue Jan 13 23:17:19 2009 +0100 @@ -32,7 +32,7 @@ if ElementTree is None: raise util.Abort(_("Python ElementTree module is not available")) - if not os.path.exists(os.path.join(path, '_darcs', 'inventory')): + if not os.path.exists(os.path.join(path, '_darcs', 'inventories')): raise NoRepo("%s does not look like a darcs repo" % path) self.path = os.path.realpath(path)
--- a/hgext/convert/gnuarch.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/convert/gnuarch.py Tue Jan 13 23:17:19 2009 +0100 @@ -3,7 +3,8 @@ from common import NoRepo, commandline, commit, converter_source from mercurial.i18n import _ from mercurial import util -import os, shutil, tempfile, stat +import os, shutil, tempfile, stat, locale +from email.Parser import Parser class gnuarch_source(converter_source, commandline): @@ -13,6 +14,7 @@ self.summary = '' self.date = None self.author = '' + self.continuationof = None self.add_files = [] self.mod_files = [] self.del_files = [] @@ -46,38 +48,74 @@ self.parents = {} self.tags = {} self.modecache = {} + self.catlogparser = Parser() + self.locale = locale.getpreferredencoding() + self.archives = [] def before(self): + # Get registered archives + self.archives = [i.rstrip('\n') + for i in self.runlines0('archives', '-n')] + if self.execmd == 'tla': output = self.run0('tree-version', self.path) else: output = self.run0('tree-version', '-d', self.path) self.treeversion = output.strip() - self.ui.status(_('analyzing tree version %s...\n') % self.treeversion) - # Get name of temporary directory version = self.treeversion.split('/') self.tmppath = os.path.join(tempfile.gettempdir(), 'hg-%s' % version[1]) # Generate parents dictionary - child = [] - output, status = self.runlines('revisions', self.treeversion) - self.checkexit(status, 'archive registered?') - for l in output: - rev = l.strip() - self.changes[rev] = self.gnuarch_rev(rev) + self.parents[None] = [] + treeversion = self.treeversion + child = None + while treeversion: + self.ui.status(_('analyzing tree version %s...\n') % treeversion) + + archive = treeversion.split('/')[0] + if archive not in self.archives: + self.ui.status(_('tree analysis stopped because it points to an unregistered archive %s...\n') % archive) + break + + # Get the complete list of revisions for that tree version + output, status = self.runlines('revisions', '-r', '-f', treeversion) + self.checkexit(status, 'failed retrieveing revisions for %s' % treeversion) + + # No new iteration unless a revision has a continuation-of header + treeversion = None + + for l in output: + rev = l.strip() + self.changes[rev] = self.gnuarch_rev(rev) + self.parents[rev] = [] - # Read author, date and summary - catlog = self.runlines0('cat-log', '-d', self.path, rev) - self._parsecatlog(catlog, rev) + # Read author, date and summary + catlog, status = self.run('cat-log', '-d', self.path, rev) + if status: + catlog = self.run0('cat-archive-log', rev) + self._parsecatlog(catlog, rev) + + # Populate the parents map + self.parents[child].append(rev) - self.parents[rev] = child - child = [rev] - if rev == self.rev: - break - self.parents[None] = child + # Keep track of the current revision as the child of the next + # revision scanned + child = rev + + # Check if we have to follow the usual incremental history + # or if we have to 'jump' to a different treeversion given + # by the continuation-of header. + if self.changes[rev].continuationof: + treeversion = '--'.join(self.changes[rev].continuationof.split('--')[:-1]) + break + + # If we reached a base-0 revision w/o any continuation-of + # header, it means the tree history ends here. + if rev[-6:] == 'base-0': + break def after(self): self.ui.debug(_('cleaning up %s\n') % self.tmppath) @@ -135,7 +173,7 @@ def getcommit(self, rev): changes = self.changes[rev] return commit(author = changes.author, date = changes.date, - desc = changes.summary, parents = self.parents[rev]) + desc = changes.summary, parents = self.parents[rev], rev=rev) def gettags(self): return self.tags @@ -150,26 +188,19 @@ return os.system(cmdline) def _update(self, rev): - if rev == 'base-0': - # Initialise 'base-0' revision + self.ui.debug(_('applying revision %s...\n') % rev) + changeset, status = self.runlines('replay', '-d', self.tmppath, + rev) + if status: + # Something went wrong while merging (baz or tla + # issue?), get latest revision and try from there + shutil.rmtree(self.tmppath, ignore_errors=True) self._obtainrevision(rev) else: - self.ui.debug(_('applying revision %s...\n') % rev) - revision = '%s--%s' % (self.treeversion, rev) - changeset, status = self.runlines('replay', '-d', self.tmppath, - revision) - if status: - # Something went wrong while merging (baz or tla - # issue?), get latest revision and try from there - shutil.rmtree(self.tmppath, ignore_errors=True) - self._obtainrevision(rev) - else: - old_rev = self.parents[rev][0] - self.ui.debug(_('computing changeset between %s and %s...\n') - % (old_rev, rev)) - rev_a = '%s--%s' % (self.treeversion, old_rev) - rev_b = '%s--%s' % (self.treeversion, rev) - self._parsechangeset(changeset, rev) + old_rev = self.parents[rev][0] + self.ui.debug(_('computing changeset between %s and %s...\n') + % (old_rev, rev)) + self._parsechangeset(changeset, rev) def _getfile(self, name, rev): mode = os.lstat(os.path.join(self.tmppath, name)).st_mode @@ -217,8 +248,7 @@ def _obtainrevision(self, rev): self.ui.debug(_('obtaining revision %s...\n') % rev) - revision = '%s--%s' % (self.treeversion, rev) - output = self._execute('get', revision, self.tmppath) + output = self._execute('get', rev, self.tmppath) self.checkexit(output) self.ui.debug(_('analysing revision %s...\n') % rev) files = self._readcontents(self.tmppath) @@ -230,20 +260,27 @@ return path def _parsecatlog(self, data, rev): - summary = [] - for l in data: - l = l.strip() - if summary: - summary.append(l) - elif l.startswith('Summary:'): - summary.append(l[len('Summary: '):]) - elif l.startswith('Standard-date:'): - date = l[len('Standard-date: '):] - strdate = util.strdate(date, '%Y-%m-%d %H:%M:%S') - self.changes[rev].date = util.datestr(strdate) - elif l.startswith('Creator:'): - self.changes[rev].author = l[len('Creator: '):] - self.changes[rev].summary = '\n'.join(summary) + try: + catlog = self.catlogparser.parsestr(data) + + # Commit date + self.changes[rev].date = util.datestr( + util.strdate(catlog['Standard-date'], + '%Y-%m-%d %H:%M:%S')) + + # Commit author + self.changes[rev].author = self.recode(catlog['Creator']) + + # Commit description + self.changes[rev].summary = '\n\n'.join((catlog['Summary'], + catlog.get_payload())) + self.changes[rev].summary = self.recode(self.changes[rev].summary) + + # Commit revision origin when dealing with a branch or tag + if catlog.has_key('Continuation-of'): + self.changes[rev].continuationof = self.recode(catlog['Continuation-of']) + except Exception, err: + raise util.Abort(_('could not parse cat-log of %s') % rev) def _parsechangeset(self, data, rev): for l in data:
--- a/hgext/convert/subversion.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/convert/subversion.py Tue Jan 13 23:17:19 2009 +0100 @@ -601,7 +601,7 @@ part = "/".join(parts[:i]) info = part, copyfrom.get(part, None) if info[1] is not None: - self.ui.debug(_("Found parent directory %s\n") % info[1]) + self.ui.debug(_("found parent directory %s\n") % info[1]) rc = info return rc @@ -616,7 +616,7 @@ self.ui.debug(entrypath[len(frompath):] + '\n') entrypath = froment.copyfrom_path + entrypath[len(frompath):] fromrev = froment.copyfrom_rev - self.ui.debug(_("Info: %s %s %s %s\n") % (frompath, froment, ent, entrypath)) + self.ui.debug(_("info: %s %s %s %s\n") % (frompath, froment, ent, entrypath)) # We can avoid the reparent calls if the module has not changed # but it probably does not worth the pain. @@ -757,7 +757,7 @@ self.ui.note(_('found parent of branch %s at %d: %s\n') % (self.module, prevnum, prevmodule)) else: - self.ui.debug(_("No copyfrom path, don't know what to do.\n")) + self.ui.debug(_("no copyfrom path, don't know what to do.\n")) paths = [] # filter out unrelated paths
--- a/hgext/extdiff.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/extdiff.py Tue Jan 13 23:17:19 2009 +0100 @@ -80,9 +80,7 @@ '''snapshot files from working directory. if not using snapshot, -I/-X does not work and recursive diff in tools like kdiff3 and meld displays too many files.''' - repo_root = repo.root - - dirname = os.path.basename(repo_root) + dirname = os.path.basename(repo.root) if dirname == "": dirname = "root" base = os.path.join(tmproot, dirname) @@ -105,8 +103,7 @@ fp.write(chunk) fp.close() - fns_and_mtime.append((dest, os.path.join(repo_root, fn), - os.path.getmtime(dest))) + fns_and_mtime.append((dest, repo.wjoin(fn), os.path.getmtime(dest))) return dirname, fns_and_mtime @@ -169,7 +166,7 @@ for copy_fn, working_fn, mtime in fns_and_mtime: if os.path.getmtime(copy_fn) != mtime: - ui.debug(_('File changed while diffing. ' + ui.debug(_('file changed while diffing. ' 'Overwriting: %s (src: %s)\n') % (working_fn, copy_fn)) util.copyfile(copy_fn, working_fn)
--- a/hgext/fetch.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/fetch.py Tue Jan 13 23:17:19 2009 +0100 @@ -11,7 +11,7 @@ from mercurial import commands, cmdutil, hg, util, url def fetch(ui, repo, source='default', **opts): - '''Pull changes from a remote repository, merge new changes if needed. + '''pull changes from a remote repository, merge new changes if needed. This finds all changes from the repository at the specified path or URL and adds them to the local repository.
--- a/hgext/hgk.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/hgk.py Tue Jan 13 23:17:19 2009 +0100 @@ -130,7 +130,7 @@ ui.write('\0') def base(ui, repo, node1, node2): - """Output common ancestor information""" + """output common ancestor information""" node1 = repo.lookup(node1) node2 = repo.lookup(node2) n = repo.changelog.ancestor(node1, node2) @@ -282,7 +282,7 @@ count += 1 def revparse(ui, repo, *revs, **opts): - """Parse given revisions""" + """parse given revisions""" def revstr(rev): if rev == 'HEAD': rev = 'tip'
--- a/hgext/keyword.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/keyword.py Tue Jan 13 23:17:19 2009 +0100 @@ -425,14 +425,10 @@ keyword substitutions. Monkeypatches patch and webcommands.''' - try: - if (not repo.local() or not kwtools['inc'] - or kwtools['hgcmd'] in nokwcommands.split() - or '.hg' in util.splitpath(repo.root) - or repo._url.startswith('bundle:')): - return - except AttributeError: - pass + if (not hasattr(repo, 'dirstate') or not kwtools['inc'] + or kwtools['hgcmd'] in nokwcommands.split() + or '.hg' in util.splitpath(repo.root)): + return kwtools['templater'] = kwt = kwtemplater(ui, repo)
--- a/hgext/mq.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/mq.py Tue Jan 13 23:17:19 2009 +0100 @@ -963,10 +963,10 @@ raise top = self.applied[-1].name if ret[0]: - self.ui.write( - "Errors during apply, please fix and refresh %s\n" % top) + self.ui.write(_("errors during apply, please fix and " + "refresh %s\n") % top) else: - self.ui.write("Now at: %s\n" % top) + self.ui.write(_("now at: %s\n") % top) return ret[0] finally: del wlock @@ -993,6 +993,17 @@ self.ui.warn(_("no patches applied\n")) return not all + if all: + start = 0 + elif patch: + start = info[0] + 1 + else: + start = len(self.applied) - 1 + + if start >= len(self.applied): + self.ui.warn(_("qpop: %s is already at the top\n") % patch) + return + if not update: parents = repo.dirstate.parents() rr = [ revlog.bin(x.rev) for x in self.applied ] @@ -1000,31 +1011,31 @@ if p in rr: self.ui.warn(_("qpop: forcing dirstate update\n")) update = True + else: + parents = [p.hex() for p in repo[None].parents()] + needupdate = False + for entry in self.applied[start:]: + if entry.rev in parents: + needupdate = True + break + update = needupdate if not force and update: self.check_localchanges(repo) - self.applied_dirty = 1; + self.applied_dirty = 1 end = len(self.applied) - if not patch: - if all: - popi = 0 - else: - popi = len(self.applied) - 1 - else: - popi = info[0] + 1 - if popi >= end: - self.ui.warn(_("qpop: %s is already at the top\n") % patch) - return - info = [ popi ] + [self.applied[popi].rev, self.applied[popi].name] - - start = info[0] - rev = revlog.bin(info[1]) - + rev = revlog.bin(self.applied[start].rev) if update: top = self.check_toppatch(repo) - if repo.changelog.heads(rev) != [revlog.bin(self.applied[-1].rev)]: + try: + heads = repo.changelog.heads(rev) + except revlog.LookupError: + node = short(rev) + raise util.Abort(_('trying to pop unknown node %s') % node) + + if heads != [revlog.bin(self.applied[-1].rev)]: raise util.Abort(_("popping would remove a revision not " "managed by this patch queue")) @@ -1056,16 +1067,16 @@ del self.applied[start:end] self.strip(repo, rev, update=False, backup='strip') if len(self.applied): - self.ui.write(_("Now at: %s\n") % self.applied[-1].name) + self.ui.write(_("now at: %s\n") % self.applied[-1].name) else: - self.ui.write(_("Patch queue now empty\n")) + self.ui.write(_("patch queue now empty\n")) finally: del wlock def diff(self, repo, pats, opts): top = self.check_toppatch(repo) if not top: - self.ui.write(_("No patches applied\n")) + self.ui.write(_("no patches applied\n")) return qp = self.qparents(repo, top) self._diffopts = patch.diffopts(self.ui, opts) @@ -1073,7 +1084,7 @@ def refresh(self, repo, pats=None, **opts): if len(self.applied) == 0: - self.ui.write(_("No patches applied\n")) + self.ui.write(_("no patches applied\n")) return 1 msg = opts.get('msg', '').rstrip() newuser = opts.get('user') @@ -1602,7 +1613,7 @@ index = self.full_series_end() + i self.full_series[index:index] = [patchname] self.parse_series() - self.ui.warn("adding %s to series file\n" % patchname) + self.ui.warn(_("adding %s to series file\n") % patchname) i += 1 added.append(patchname) patchname = None @@ -1786,7 +1797,7 @@ return q.qseries(repo, start=t-1, length=1, status='A', summary=opts.get('summary')) else: - ui.write("No patches applied\n") + ui.write(_("no patches applied\n")) return 1 def next(ui, repo, **opts): @@ -1794,7 +1805,7 @@ q = repo.mq end = q.series_end() if end == len(q.series): - ui.write("All patches applied\n") + ui.write(_("all patches applied\n")) return 1 return q.qseries(repo, start=end, length=1, summary=opts.get('summary')) @@ -1803,10 +1814,10 @@ q = repo.mq l = len(q.applied) if l == 1: - ui.write("Only one patch applied\n") + ui.write(_("only one patch applied\n")) return 1 if not l: - ui.write("No patches applied\n") + ui.write(_("no patches applied\n")) return 1 return q.qseries(repo, start=l-2, length=1, status='A', summary=opts.get('summary')) @@ -1870,7 +1881,7 @@ message = cmdutil.logmessage(opts) if opts['edit']: if not q.applied: - ui.write(_("No patches applied\n")) + ui.write(_("no patches applied\n")) return 1 if message: raise util.Abort(_('option "-e" incompatible with "-m" or "-l"')) @@ -2018,14 +2029,14 @@ status(q.series.index(q.lookup(patch))) def header(ui, repo, patch=None): - """Print the header of the topmost or specified patch""" + """print the header of the topmost or specified patch""" q = repo.mq if patch: patch = q.lookup(patch) else: if not q.applied: - ui.write('No patches applied\n') + ui.write('no patches applied\n') return 1 patch = q.lookup('qtip') ph = repo.mq.readheaders(patch) @@ -2112,7 +2123,7 @@ patch = q.lookup(patch) else: if not q.applied: - ui.write(_('No patches applied\n')) + ui.write(_('no patches applied\n')) return patch = q.lookup('qtip') absdest = q.join(name) @@ -2126,7 +2137,7 @@ raise util.Abort(_('A patch named %s already exists in the series file') % name) if ui.verbose: - ui.write('Renaming %s to %s\n' % (patch, name)) + ui.write('renaming %s to %s\n' % (patch, name)) i = q.find_series(patch) guards = q.guard_re.findall(q.full_series[i]) q.full_series[i] = name + ''.join([' #' + g for g in guards])
--- a/hgext/patchbomb.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/patchbomb.py Tue Jan 13 23:17:19 2009 +0100 @@ -9,8 +9,7 @@ The remainder of the changeset description. - [Optional] If the diffstat program is installed, the result of - running diffstat on the patch. + [Optional] The result of running diffstat on the patch. The patch itself, as generated by "hg export". @@ -64,23 +63,10 @@ import os, errno, socket, tempfile, cStringIO import email.MIMEMultipart, email.MIMEBase import email.Utils, email.Encoders, email.Generator -from mercurial import cmdutil, commands, hg, mail, patch, util +from mercurial import cmdutil, commands, hg, mail, mdiff, patch, util from mercurial.i18n import _ from mercurial.node import bin -class exportee: - def __init__(self, container): - self.lines = [] - self.container = container - self.name = 'email' - - def write(self, data): - self.lines.append(data) - - def close(self): - self.container.append(''.join(self.lines).split('\n')) - self.lines = [] - def prompt(ui, prompt, default=None, rest=': ', empty_ok=False): if not ui.interactive: return default @@ -99,16 +85,12 @@ def cdiffstat(ui, summary, patchlines): s = patch.diffstat(patchlines) - if s: - if summary: - ui.write(summary, '\n') - ui.write(s, '\n') - ans = prompt(ui, _('Does the diffstat above look okay? '), 'y') - if not ans.lower().startswith('y'): - raise util.Abort(_('diffstat rejected')) - elif s is None: - ui.warn(_('no diffstat information available\n')) - s = '' + if summary: + ui.write(summary, '\n') + ui.write(s, '\n') + ans = prompt(ui, _('does the diffstat above look okay? '), 'y') + if not ans.lower().startswith('y'): + raise util.Abort(_('diffstat rejected')) return s def makepatch(ui, repo, patch, opts, _charsets, idx, total, patchname=None): @@ -239,6 +221,13 @@ o = repo.changelog.nodesbetween(o, revs or None)[0] return [str(repo.changelog.rev(r)) for r in o] + def getpatches(revs): + for r in cmdutil.revrange(repo, revs): + output = cStringIO.StringIO() + p = patch.export(repo, [r], fp=output, + opts=mdiff.diffopts(git=opts.get('git'))) + yield output.getvalue().split('\n') + def getbundle(dest): tmpdir = tempfile.mkdtemp(prefix='hg-email-bundle-') tmpfn = os.path.join(tmpdir, 'bundle') @@ -308,7 +297,7 @@ % len(patches)) name = None - for p, i in zip(patches, xrange(len(patches))): + for i, p in enumerate(patches): jumbo.extend(p) if patchnames: name = patchnames[i] @@ -360,18 +349,14 @@ ui.config('patchbomb', 'from') or prompt(ui, 'From', ui.username())) + # internal option used by pbranches patches = opts.get('patches') if patches: msgs = getpatchmsgs(patches, opts.get('patchnames')) elif opts.get('bundle'): msgs = getbundlemsgs(getbundle(dest)) else: - patches = [] - commands.export(ui, repo, *revs, **{'output': exportee(patches), - 'switch_parent': False, - 'text': None, - 'git': opts.get('git')}) - msgs = getpatchmsgs(patches) + msgs = getpatchmsgs(list(getpatches(revs))) def getaddrs(opt, prpt, default = None): addrs = opts.get(opt) or (ui.config('email', opt) or
--- a/hgext/purge.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/purge.py Tue Jan 13 23:17:19 2009 +0100 @@ -32,28 +32,26 @@ import os def purge(ui, repo, *dirs, **opts): - '''removes files not tracked by mercurial + '''removes files not tracked by Mercurial - Delete files not known to mercurial, this is useful to test local and - uncommitted changes in the otherwise clean source tree. + Delete files not known to Mercurial. This is useful to test local and + uncommitted changes in an otherwise-clean source tree. This means that purge will delete: - Unknown files: files marked with "?" by "hg status" - - Ignored files: files usually ignored by Mercurial because they match - a pattern in a ".hgignore" file - Empty directories: in fact Mercurial ignores directories unless they contain files under source control managment But it will leave untouched: - - Unmodified tracked files - - Modified tracked files + - Modified and unmodified tracked files + - Ignored files (unless --all is specified) - New files added to the repository (with "hg add") If directories are given on the command line, only files in these directories are considered. - Be careful with purge, you could irreversibly delete some files you + Be careful with purge, as you could irreversibly delete some files you forgot to add to the repository. If you only want to print the list of - files that this program would delete use the --print option. + files that this program would delete, use the --print option. ''' act = not opts['print'] eol = '\n' @@ -64,7 +62,7 @@ def remove(remove_func, name): if act: try: - remove_func(os.path.join(repo.root, name)) + remove_func(repo.wjoin(name)) except OSError: m = _('%s cannot be removed') % name if opts['abort_on_err']:
--- a/hgext/rebase.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/rebase.py Tue Jan 13 23:17:19 2009 +0100 @@ -34,7 +34,7 @@ if not first: ancestor.ancestor = newancestor else: - repo.ui.debug(_("First revision, do not change ancestor\n")) + repo.ui.debug(_("first revision, do not change ancestor\n")) stats = merge.update(repo, rev, True, True, False) return stats @@ -281,7 +281,7 @@ f.write(repo[target].hex() + '\n') f.write(repo[external].hex() + '\n') f.write('%d\n' % int(collapse)) - for d, v in state.items(): + for d, v in state.iteritems(): oldrev = repo[d].hex() newrev = repo[v].hex() f.write("%s:%s\n" % (oldrev, newrev))
--- a/hgext/transplant.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/transplant.py Tue Jan 13 23:17:19 2009 +0100 @@ -5,11 +5,6 @@ # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. -from mercurial.i18n import _ -import os, tempfile -from mercurial import bundlerepo, changegroup, cmdutil, hg, merge -from mercurial import patch, revlog, util - '''patch transplanting tool This extension allows you to transplant patches from another branch. @@ -18,6 +13,11 @@ from a changeset hash to its hash in the source repository. ''' +from mercurial.i18n import _ +import os, tempfile +from mercurial import bundlerepo, changegroup, cmdutil, hg, merge +from mercurial import patch, revlog, util + class transplantentry: def __init__(self, lnode, rnode): self.lnode = lnode
--- a/hgext/win32mbcs.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/win32mbcs.py Tue Jan 13 23:17:19 2009 +0100 @@ -8,7 +8,7 @@ # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. # -"""Allow to use MBCS path with problematic encoding. +"""allow to use MBCS path with problematic encoding. Some MBCS encodings are not good for some path operations (i.e. splitting path, case conversion, etc.) with its encoded bytes.
--- a/hgext/zeroconf/__init__.py Tue Jan 13 22:41:06 2009 +0100 +++ b/hgext/zeroconf/__init__.py Tue Jan 13 23:17:19 2009 +0100 @@ -6,6 +6,29 @@ # the GNU General Public License (version 2), incorporated herein by # reference. +'''zeroconf support for mercurial repositories + +Zeroconf enabled repositories will be announced in a network without the need +to configure a server or a service. They can be discovered without knowing +their actual IP address. + +To use the zeroconf extension add the following entry to your hgrc file: + +[extensions] +hgext.zeroconf = + +To allow other people to discover your repository using run "hg serve" in your +repository. + + $ cd test + $ hg serve + +You can discover zeroconf enabled repositories by running "hg paths". + + $ hg paths + zc-test = http://example.com:8000/test +''' + import Zeroconf, socket, time, os from mercurial import ui from mercurial import extensions
--- a/mercurial/bdiff.c Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/bdiff.c Tue Jan 13 23:17:19 2009 +0100 @@ -261,6 +261,7 @@ free(pos); + /* normalize the hunk list, try to push each hunk towards the end */ for (curr = l.base; curr != l.head; curr++) { struct hunk *next = curr+1; int shift = 0;
--- a/mercurial/changelog.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/changelog.py Tue Jan 13 23:17:19 2009 +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:
--- a/mercurial/commands.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/commands.py Tue Jan 13 23:17:19 2009 +0100 @@ -328,29 +328,34 @@ state = hbisect.load_state(repo) if command: + commandpath = util.find_exe(command) changesets = 1 - while changesets: - # update state - status = os.spawnlp(os.P_WAIT, command) - node = repo.lookup(rev or '.') - if status == 125: - transition = "skip" - elif status == 0: - transition = "good" - # status < 0 means process was killed - elif status == 127 or status < 0: - break - else: - transition = "bad" - state[transition].append(node) - ui.note(_('Changeset %s: %s\n') % (short(node), transition)) - check_state(state, interactive=False) - # bisect - nodes, changesets, good = hbisect.bisect(repo.changelog, state) - # update to next check - cmdutil.bail_if_changed(repo) - hg.clean(repo, nodes[0], show_stats=False) - hbisect.save_state(repo, state) + try: + while changesets: + # update state + status = os.spawnl(os.P_WAIT, commandpath) + if status == 125: + transition = "skip" + elif status == 0: + transition = "good" + # status < 0 means process was killed + elif status == 127: + raise util.Abort(_("failed to execute %s") % command) + elif status < 0: + raise util.Abort(_("%s killed") % command) + else: + transition = "bad" + node = repo.lookup(rev or '.') + state[transition].append(node) + ui.note(_('Changeset %s: %s\n') % (short(node), transition)) + check_state(state, interactive=False) + # bisect + nodes, changesets, good = hbisect.bisect(repo.changelog, state) + # update to next check + cmdutil.bail_if_changed(repo) + hg.clean(repo, nodes[0], show_stats=False) + finally: + hbisect.save_state(repo, state) return print_result(nodes, not status) # update state @@ -688,7 +693,10 @@ ui.write("%s\n" % "\n".join(options)) return - ui.write("%s\n" % "\n".join(util.sort(cmdutil.findpossible(cmd, table)))) + cmdlist = cmdutil.findpossible(cmd, table) + if ui.verbose: + cmdlist = [' '.join(c[0]) for c in cmdlist.values()] + ui.write("%s\n" % "\n".join(util.sort(cmdlist))) def debugfsinfo(ui, path = "."): file('.debugfsinfo', 'w').write('') @@ -780,7 +788,7 @@ """show the contents of the current dirstate""" timestr = "" showdate = not nodates - for file_, ent in util.sort(repo.dirstate._map.items()): + for file_, ent in util.sort(repo.dirstate._map.iteritems()): if showdate: if ent[3] == -1: # Pad or slice to locale representation @@ -1007,7 +1015,18 @@ Use the --git option to generate diffs in the git extended diff format. Read the diffs help topic for more information. """ - node1, node2 = cmdutil.revpair(repo, opts.get('rev')) + + revs = opts.get('rev') + change = opts.get('change') + + if revs and change: + msg = _('cannot specify --rev and --change at the same time') + raise util.Abort(msg) + elif change: + node2 = repo.lookup(change) + node1 = repo[node2].parents()[0].node() + else: + node1, node2 = cmdutil.revpair(repo, revs) m = cmdutil.match(repo, pats, opts) it = patch.diff(repo, node1, node2, match=m, opts=patch.diffopts(ui, opts)) @@ -1325,7 +1344,7 @@ # description doc = gettext(i[0].__doc__) if not doc: - doc = _("(No help text available)") + doc = _("(no help text available)") if ui.quiet: doc = doc.splitlines(0)[0] ui.write("\n%s\n" % doc.rstrip()) @@ -1340,7 +1359,7 @@ def helplist(header, select=None): h = {} cmds = {} - for c, e in table.items(): + for c, e in table.iteritems(): f = c.split("|", 1)[0] if select and not select(f): continue @@ -1354,7 +1373,7 @@ continue doc = gettext(e[0].__doc__) if not doc: - doc = _("(No help text available)") + doc = _("(no help text available)") h[f] = doc.splitlines(0)[0].rstrip() cmds[f] = c.lstrip("^") @@ -1397,7 +1416,7 @@ # description if not doc: - doc = _("(No help text available)") + doc = _("(no help text available)") if callable(doc): doc = doc() @@ -1410,7 +1429,7 @@ except KeyError: raise cmdutil.UnknownCommand(name) - doc = gettext(mod.__doc__) or _('No help text available') + doc = gettext(mod.__doc__) or _('no help text available') doc = doc.splitlines(0) ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0])) for d in doc[1:]: @@ -1794,7 +1813,7 @@ if not rev and abs not in repo.dirstate: continue if opts.get('fullpath'): - ui.write(os.path.join(repo.root, abs), end) + ui.write(repo.wjoin(abs), end) else: ui.write(((pats and m.rel(abs)) or abs), end) ret = 0 @@ -2738,7 +2757,7 @@ if node2 is None: added = stat[0] + stat[1] # merged? - for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].items(): + for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems(): if k in added: copy[k] = v elif v in added: @@ -2822,8 +2841,6 @@ def tags(ui, repo): """list repository tags - List the repository tags. - This lists both regular and local tags. When the -v/--verbose switch is used, a third column "local" is printed for local tags. """ @@ -3071,7 +3088,7 @@ ('g', 'good', False, _('mark changeset good')), ('b', 'bad', False, _('mark changeset bad')), ('s', 'skip', False, _('skip testing changeset')), - ('c', 'command', '', _('Use command to check changeset state')), + ('c', 'command', '', _('use command to check changeset state')), ('U', 'noupdate', False, _('do not update to target'))], _("[-gbsr] [-c CMD] [REV]")), "branch": @@ -3166,7 +3183,8 @@ "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')), "^diff": (diff, - [('r', 'rev', [], _('revision')) + [('r', 'rev', [], _('revision')), + ('c', 'change', '', _('change made by revision')) ] + diffopts + diffopts2 + walkopts, _('[OPTION]... [-r REV1 [-r REV2]] [FILE]...')), "^export":
--- a/mercurial/copies.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/copies.py Tue Jan 13 23:17:19 2009 +0100 @@ -189,7 +189,7 @@ # examine each file copy for a potential directory move, which is # when all the files in a directory are moved to a new directory - for dst, src in fullcopy.items(): + for dst, src in fullcopy.iteritems(): dsrc, ddst = _dirname(src), _dirname(dst) if dsrc in invalid: # already seen to be uninteresting
--- a/mercurial/dispatch.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/dispatch.py Tue Jan 13 23:17:19 2009 +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)
--- a/mercurial/filelog.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/filelog.py Tue Jan 13 23:17:19 2009 +0100 @@ -50,7 +50,7 @@ if meta or text.startswith('\1\n'): mt = "" if meta: - mt = [ "%s: %s\n" % (k, v) for k,v in meta.items() ] + mt = ["%s: %s\n" % (k, v) for k, v in meta.iteritems()] text = "\1\n%s\1\n%s" % ("".join(mt), text) return self.addrevision(text, transaction, link, p1, p2)
--- a/mercurial/hbisect.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/hbisect.py Tue Jan 13 23:17:19 2009 +0100 @@ -102,7 +102,7 @@ if value == perfect: # found a perfect candidate? quit early break - if y < perfect: # all downhill from here? + if y < perfect and rev not in skip: # all downhill from here? for c in children.get(rev, []): poison[c] = True # poison children continue
--- a/mercurial/hg.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/hg.py Tue Jan 13 23:17:19 2009 +0100 @@ -252,8 +252,6 @@ note = ", ".join([_("%d files %s") % s for s in stats]) repo.ui.status("%s\n" % note) -def _update(repo, node): return update(repo, node) - def update(repo, node): """update the working directory to node, merging linear changes""" stats = _merge.update(repo, node, False, False, None) @@ -262,6 +260,9 @@ repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n")) return stats[3] > 0 +# naming conflict in clone() +_update = update + def clean(repo, node, show_stats=True): """forcibly switch the working directory to node, clobbering changes""" stats = _merge.update(repo, node, False, True, None)
--- a/mercurial/hgweb/hgweb_mod.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/hgweb/hgweb_mod.py Tue Jan 13 23:17:19 2009 +0100 @@ -284,14 +284,13 @@ raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') allow_read = self.configlist('web', 'allow_read') - result = (not allow_read) or (allow_read == ['*']) or (user in allow_read) - if not result: + result = (not allow_read) or (allow_read == ['*']) + if not result or user in allow_read: raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') if op == 'pull' and not self.allowpull: raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized') - # op is None when checking allow/deny_read permissions for a web-browser request - elif op == 'pull' or op is None: + elif op == 'pull' or op is None: # op is None for interface requests return # enforce that you can only push using POST requests
--- a/mercurial/hgweb/hgwebdir_mod.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/hgweb/hgwebdir_mod.py Tue Jan 13 23:17:19 2009 +0100 @@ -102,11 +102,11 @@ user = req.env.get('REMOTE_USER') - deny_read = ui.configlist('web', 'deny_read', default=None, untrusted=True) + deny_read = ui.configlist('web', 'deny_read', untrusted=True) if deny_read and (not user or deny_read == ['*'] or user in deny_read): return False - allow_read = ui.configlist('web', 'allow_read', default=None, untrusted=True) + allow_read = ui.configlist('web', 'allow_read', untrusted=True) # by default, allow reading if no allow_read option has been set if (not allow_read) or (allow_read == ['*']) or (user in allow_read): return True
--- a/mercurial/hgweb/webcommands.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/hgweb/webcommands.py Tue Jan 13 23:17:19 2009 +0100 @@ -275,7 +275,7 @@ l = len(path) abspath = "/" + path - for f, n in mf.items(): + for f, n in mf.iteritems(): if f[:l] != path: continue remain = f[l:] @@ -386,7 +386,7 @@ parity = paritygen(web.stripecount) b = web.repo.branchtags() - l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.items()] + l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()] for r,n,t in util.sort(l): yield {'parity': parity.next(), 'branch': t,
--- a/mercurial/hgweb/wsgicgi.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/hgweb/wsgicgi.py Tue Jan 13 23:17:19 2009 +0100 @@ -15,7 +15,7 @@ util.set_binary(sys.stdin) util.set_binary(sys.stdout) - environ = dict(os.environ.items()) + environ = dict(os.environ.iteritems()) environ.setdefault('PATH_INFO', '') if '.cgi' in environ['PATH_INFO']: environ['PATH_INFO'] = environ['PATH_INFO'].split('.cgi', 1)[1]
--- a/mercurial/ignore.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/ignore.py Tue Jan 13 23:17:19 2009 +0100 @@ -60,7 +60,7 @@ warn(_("%s: ignoring invalid syntax '%s'\n") % (f, s)) continue pat = syntax + line - for s, rels in syntaxes.items(): + for s, rels in syntaxes.iteritems(): if line.startswith(rels): pat = line break @@ -83,7 +83,7 @@ util.matcher(root, inc=allpats, src='.hgignore')) except util.Abort: # Re-raise an exception where the src is the right file - for f, patlist in pats.items(): + for f, patlist in pats.iteritems(): files, ignorefunc, anypats = ( util.matcher(root, inc=patlist, src=f))
--- a/mercurial/keepalive.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/keepalive.py Tue Jan 13 23:17:19 2009 +0100 @@ -197,7 +197,7 @@ def close_all(self): """close all open connections""" - for host, conns in self._cm.get_all().items(): + for host, conns in self._cm.get_all().iteritems(): for h in conns: self._cm.remove(h) h.close()
--- a/mercurial/localrepo.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/localrepo.py Tue Jan 13 23:17:19 2009 +0100 @@ -265,7 +265,7 @@ h.append(n) filetags[key] = (bin_n, h) - for k, nh in filetags.items(): + for k, nh in filetags.iteritems(): if k not in globaltags: globaltags[k] = nh tagtypes[k] = tagtype @@ -301,7 +301,7 @@ self.tagscache = {} self._tagstypecache = {} - for k,nh in globaltags.items(): + for k, nh in globaltags.iteritems(): n = nh[0] if n != nullid: self.tagscache[k] = n @@ -343,7 +343,7 @@ def tagslist(self): '''return a list of tags ordered by revision''' l = [] - for t, n in self.tags().items(): + for t, n in self.tags().iteritems(): try: r = self.changelog.rev(n) except: @@ -355,7 +355,7 @@ '''return the tags associated with a node''' if not self.nodetagscache: self.nodetagscache = {} - for t, n in self.tags().items(): + for t, n in self.tags().iteritems(): self.nodetagscache.setdefault(n, []).append(t) return self.nodetagscache.get(node, []) @@ -388,7 +388,7 @@ # the branch cache is stored on disk as UTF-8, but in the local # charset internally - for k, v in partial.items(): + for k, v in partial.iteritems(): self.branchcache[util.tolocal(k)] = v self._ubranchcache = partial return self.branchcache @@ -1579,7 +1579,7 @@ if self.ui.verbose or source == 'bundle': self.ui.status(_("%d changesets found\n") % len(nodes)) if self.ui.debugflag: - self.ui.debug(_("List of changesets:\n")) + self.ui.debug(_("list of changesets:\n")) for node in nodes: self.ui.debug("%s\n" % hex(node)) @@ -1756,7 +1756,7 @@ # we only need to see a diff. deltamf = mnfst.readdelta(mnfstnode) # For each line in the delta - for f, fnode in deltamf.items(): + for f, fnode in deltamf.iteritems(): f = changedfiles.get(f, None) # And if the file is in the list of files we care # about.
--- a/mercurial/lsprof.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/lsprof.py Tue Jan 13 23:17:19 2009 +0100 @@ -88,7 +88,7 @@ try: mname = _fn2mod[code.co_filename] except KeyError: - for k, v in sys.modules.items(): + for k, v in sys.modules.iteritems(): if v is None: continue if not hasattr(v, '__file__'):
--- a/mercurial/merge.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/merge.py Tue Jan 13 23:17:19 2009 +0100 @@ -36,7 +36,7 @@ def _write(self): f = self._repo.opener("merge/state", "w") f.write(hex(self._local) + "\n") - for d, v in self._state.items(): + for d, v in self._state.iteritems(): f.write("\0".join([d] + v) + "\n") def add(self, fcl, fco, fca, fd, flags): hash = util.sha1(fcl.path()).hexdigest() @@ -166,7 +166,7 @@ dirs = repo.ui.configbool("merge", "followdirs", True) copy, diverge = copies.copies(repo, p1, p2, pa, dirs) copied = dict.fromkeys(copy.values()) - for of, fl in diverge.items(): + for of, fl in diverge.iteritems(): act("divergent renames", "dr", of, fl) # Compare manifests
--- a/mercurial/patch.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/patch.py Tue Jan 13 23:17:19 2009 +0100 @@ -9,7 +9,7 @@ from i18n import _ from node import hex, nullid, short import base85, cmdutil, mdiff, util, revlog, diffhelpers, copies -import cStringIO, email.Parser, os, re, errno +import cStringIO, email.Parser, os, re, errno, math import sys, tempfile, zlib gitre = re.compile('diff --git a/(.*) b/(.*)') @@ -794,9 +794,7 @@ def readline(self): if self.buf: - l = self.buf[0] - del self.buf[0] - return l + return self.buf.pop(0) return self.fp.readline() def __iter__(self): @@ -1059,7 +1057,7 @@ gp = patches[f] if gp and gp.mode: islink, isexec = gp.mode - dst = os.path.join(repo.root, gp.path) + dst = repo.wjoin(gp.path) # patch won't create empty files if gp.op == 'ADD' and not os.path.exists(dst): flags = (isexec and 'x' or '') + (islink and 'l' or '') @@ -1340,19 +1338,61 @@ for chunk in diff(repo, prev, node, opts=opts): fp.write(chunk) - if fp not in (sys.stdout, repo.ui): - fp.close() for seqno, rev in enumerate(revs): single(rev, seqno+1, fp) -def diffstat(patchlines): - if not util.find_exe('diffstat'): - return - output = util.filter('\n'.join(patchlines), - 'diffstat -p1 -w79 2>%s' % util.nulldev) - stat = [l.lstrip() for l in output.splitlines(True)] - last = stat.pop() - stat.insert(0, last) - stat = ''.join(stat) - return stat +def diffstatdata(lines): + filename = None + for line in lines: + if line.startswith('diff'): + if filename: + yield (filename, adds, removes) + # set numbers to 0 anyway when starting new file + adds = 0 + removes = 0 + if line.startswith('diff --git'): + filename = gitre.search(line).group(1) + else: + # format: "diff -r ... -r ... file name" + filename = line.split(None, 5)[-1] + elif line.startswith('+') and not line.startswith('+++'): + adds += 1 + elif line.startswith('-') and not line.startswith('---'): + removes += 1 + yield (filename, adds, removes) + +def diffstat(lines): + output = [] + stats = list(diffstatdata(lines)) + width = util.termwidth() - 2 + + maxtotal, maxname = 0, 0 + totaladds, totalremoves = 0, 0 + for filename, adds, removes in stats: + totaladds += adds + totalremoves += removes + maxname = max(maxname, len(filename)) + maxtotal = max(maxtotal, adds+removes) + + countwidth = len(str(maxtotal)) + graphwidth = width - countwidth - maxname + if graphwidth < 10: + graphwidth = 10 + + factor = int(math.ceil(float(maxtotal) / graphwidth)) + + for filename, adds, removes in stats: + # If diffstat runs out of room it doesn't print anything, which + # isn't very useful, so always print at least one + or - if there + # were at least some changes + pluses = '+' * max(adds/factor, int(bool(adds))) + minuses = '-' * max(removes/factor, int(bool(removes))) + output.append(' %-*s | %*.d %s%s\n' % (maxname, filename, countwidth, + adds+removes, pluses, minuses)) + + if stats: + output.append(' %d files changed, %d insertions(+), %d deletions(-)\n' % + (len(stats), totaladds, totalremoves)) + + return ''.join(output)
--- a/mercurial/sshrepo.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/sshrepo.py Tue Jan 13 23:17:19 2009 +0100 @@ -115,7 +115,7 @@ def do_cmd(self, cmd, **args): self.ui.debug(_("sending %s command\n") % cmd) self.pipeo.write("%s\n" % cmd) - for k, v in args.items(): + for k, v in args.iteritems(): self.pipeo.write("%s %d\n" % (k, len(v))) self.pipeo.write(v) self.pipeo.flush()
--- a/mercurial/ui.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/ui.py Tue Jan 13 23:17:19 2009 +0100 @@ -340,7 +340,7 @@ if user is None: user = os.environ.get("EMAIL") if user is None and self.configbool("ui", "askusername"): - user = self.prompt(_("Enter a commit username:"), default=None) + user = self.prompt(_("enter a commit username:"), default=None) if user is None: try: user = '%s@%s' % (util.getuser(), socket.getfqdn()) @@ -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):
--- a/mercurial/util.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/util.py Tue Jan 13 23:17:19 2009 +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): @@ -1991,3 +1991,24 @@ def uirepr(s): # Avoid double backslash in Windows path repr() return repr(s).replace('\\\\', '\\') + +def termwidth(): + if 'COLUMNS' in os.environ: + try: + return int(os.environ['COLUMNS']) + except ValueError: + pass + try: + import termios, array, fcntl + for dev in (sys.stdout, sys.stdin): + try: + fd = dev.fileno() + if not os.isatty(fd): + continue + arri = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * 8) + return array.array('h', arri)[1] + except ValueError: + pass + except ImportError: + pass + return 80
--- a/mercurial/util_win32.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/util_win32.py Tue Jan 13 23:17:19 2009 +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,
--- a/mercurial/verify.py Tue Jan 13 22:41:06 2009 +0100 +++ b/mercurial/verify.py Tue Jan 13 23:17:19 2009 +0100 @@ -220,7 +220,7 @@ # cross-check if f in filenodes: - fns = [(mf.linkrev(l), n) for n,l in filenodes[f].items()] + fns = [(mf.linkrev(l), n) for n,l in filenodes[f].iteritems()] for lr, node in util.sort(fns): err(lr, _("%s in manifests not found") % short(node), f)
--- a/setup.py Tue Jan 13 22:41:06 2009 +0100 +++ b/setup.py Tue Jan 13 23:17:19 2009 +0100 @@ -9,6 +9,23 @@ if not hasattr(sys, 'version_info') or sys.version_info < (2, 3, 0, 'final'): raise SystemExit("Mercurial requires python 2.3 or later.") +# Solaris Python packaging brain damage +try: + import hashlib + sha = hashlib.sha1() +except: + try: + import sha + except: + raise SystemExit( + "Couldn't import standard hashlib (incomplete Python install).") + +try: + import zlib +except: + raise SystemExit( + "Couldn't import standard zlib (incomplete Python install).") + import os import shutil import tempfile
--- a/tests/test-acl.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-acl.out Tue Jan 13 23:17:19 2009 +0100 @@ -15,7 +15,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -43,7 +43,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -75,7 +75,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -112,7 +112,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -151,7 +151,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -193,7 +193,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -234,7 +234,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -278,7 +278,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -321,7 +321,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -365,7 +365,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -409,7 +409,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -458,7 +458,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -506,7 +506,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955 @@ -561,7 +561,7 @@ searching for changes common changesets up to 6675d58eff77 3 changesets found -List of changesets: +list of changesets: ef1ea85a6374b77d6da9dcda9541f498f2d17df7 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd 911600dab2ae7a9baff75958b84fe606851ce955
--- a/tests/test-audit-path Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-audit-path Tue Jan 13 23:17:19 2009 +0100 @@ -41,4 +41,8 @@ hg manifest -r3 hg update -Cr3 +echo % attack /tmp/test +hg manifest -r4 +hg update -Cr4 2>&1 | sed -e "s|$HGTMP|[HGTMP]|" + exit 0
--- a/tests/test-audit-path.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-audit-path.out Tue Jan 13 23:17:19 2009 +0100 @@ -10,7 +10,7 @@ adding changesets adding manifests adding file changes -added 4 changesets with 5 changes to 5 files (+3 heads) +added 5 changesets with 6 changes to 6 files (+4 heads) (run 'hg heads' to see heads, 'hg merge' to merge) % attack .hg/test .hg/test @@ -25,3 +25,6 @@ % attack ../test ../test abort: path contains illegal component: ../test +% attack /tmp/test +/tmp/test +abort: No such file or directory: [HGTMP]/test-audit-path/target//tmp/test
--- a/tests/test-bdiff Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-bdiff Tue Jan 13 23:17:19 2009 +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)
--- a/tests/test-bisect Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-bisect Tue Jan 13 23:17:19 2009 +0100 @@ -72,3 +72,13 @@ echo % test no action hg bisect -r hg bisect || echo failure + +echo % reproduce AssertionError, issue1445 +hg bisect -r +hg bisect -b 6 +hg bisect -g 0 +hg bisect -s +hg bisect -s +hg bisect -s +hg bisect -s +hg bisect -g
--- a/tests/test-bisect.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-bisect.out Tue Jan 13 23:17:19 2009 +0100 @@ -286,3 +286,20 @@ % test no action abort: cannot bisect (no known good revisions) failure +% reproduce AssertionError, issue1445 +Testing changeset 3:b53bea5e2fcb (6 changesets remaining, ~2 tests) +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +Testing changeset 2:db07c04beaca (6 changesets remaining, ~2 tests) +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +Testing changeset 4:9b2ba8336a65 (6 changesets remaining, ~2 tests) +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +Testing changeset 1:5cd978ea5149 (6 changesets remaining, ~2 tests) +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +Testing changeset 5:7874a09ea728 (6 changesets remaining, ~2 tests) +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +The first bad revision is: +changeset: 6:a3d5c6fdf0d3 +user: test +date: Thu Jan 01 00:00:06 1970 +0000 +summary: msg 6 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-bookmarks-current Tue Jan 13 23:17:19 2009 +0100 @@ -0,0 +1,41 @@ +#!/bin/sh + +echo "[extensions]" >> $HGRCPATH +echo "bookmarks=" >> $HGRCPATH + +echo "[bookmarks]" >> $HGRCPATH +echo "track.current = True" >> $HGRCPATH + +hg init + +echo % no bookmarks +hg bookmarks + +echo % set bookmark X +hg bookmark X + +echo % update to bookmark X +hg update X + +echo % list bookmarks +hg bookmarks + +echo % rename +hg bookmark -m X Z + +echo % list bookmarks +hg bookmarks + +echo % new bookmark Y +hg bookmark Y + +echo % list bookmarks +hg bookmark + +echo % commit +echo 'b' > b +hg add b +hg commit -m'test' + +echo % list bookmarks +hg bookmark
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-bookmarks-current.out Tue Jan 13 23:17:19 2009 +0100 @@ -0,0 +1,18 @@ +% no bookmarks +no bookmarks set +% set bookmark X +% update to bookmark X +0 files updated, 0 files merged, 0 files removed, 0 files unresolved +% list bookmarks + * X -1:000000000000 +% rename +% list bookmarks + * Z -1:000000000000 +% new bookmark Y +% list bookmarks + Y -1:000000000000 + * Z -1:000000000000 +% commit +% list bookmarks + Y -1:000000000000 + * Z 0:719295282060
--- a/tests/test-bookmarks-rebase.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-bookmarks-rebase.out Tue Jan 13 23:17:19 2009 +0100 @@ -18,6 +18,8 @@ rebase completed changeset: 3:9163974d1cb5 tag: tip +tag: two +tag: one parent: 1:925d80f479bb parent: 2:db815d6d32e6 user: test
--- a/tests/test-bookmarks.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-bookmarks.out Tue Jan 13 23:17:19 2009 +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
--- a/tests/test-convert-bzr-merges Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-convert-bzr-merges Tue Jan 13 23:17:19 2009 +0100 @@ -18,6 +18,7 @@ bzr add -q file-branch1 bzr commit -q -m 'Added branch1 file' cd ../source +sleep 1 echo content > file-parent bzr add -q file-parent bzr commit -q -m 'Added parent file' @@ -27,6 +28,7 @@ echo somecontent > file-branch2 bzr add -q file-branch2 bzr commit -q -m 'Added brach2 file' +sleep 1 cd ../source bzr merge -q ../source-branch1 bzr merge -q --force ../source-branch2
--- a/tests/test-convert-cvs-builtincvsps Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-convert-cvs-builtincvsps Tue Jan 13 23:17:19 2009 +0100 @@ -100,5 +100,22 @@ hgcat b/c hg -R src-filemap log --template '#rev# #desc# files: #files#\n' +echo % commit a new revision with funny log message +cd src +sleep 1 +echo e >> a +cvscall -q commit -m'funny +---------------------------- +log message' . | 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' + 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:/'
--- a/tests/test-convert-cvs-builtincvsps.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-convert-cvs-builtincvsps.out Tue Jan 13 23:17:19 2009 +0100 @@ -124,6 +124,22 @@ 2 update tags files: .hgtags 1 ci0 files: b/c 0 Initial revision files: b/c +% commit a new revision with funny log message +checking in src/a,v +% convert again +using builtin cvsps +collecting CVS rlog +9 log entries +creating changesets +6 changeset entries +connecting to cvsrepo +scanning source... +sorting... +converting... +0 funny +o 6 (branch) funny +| ---------------------------- +| log message files: a o 5 (branch) ci2 files: b/c | | o 4 () ci1 files: a b/c @@ -136,3 +152,85 @@ |/ o 0 () Initial revision files: a b/c +% testing debugcvsps +collecting CVS rlog +9 log entries +creating changesets +6 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 + +--------------------- +PatchSet 6 +Date: +Author: +Branch: branch +Tag: (none) +Log: +funny +---------------------------- +log message + +Members: + a:1.2->1.2.2.1 +
--- a/tests/test-convert.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-convert.out Tue Jan 13 23:17:19 2009 +0100 @@ -1,6 +1,6 @@ hg convert [OPTION]... SOURCE [DEST [REVMAP]] -Convert a foreign SCM repository to a Mercurial one. +convert a foreign SCM repository to a Mercurial one. Accepted source formats [identifiers]: - Mercurial [hg]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-diff-change Tue Jan 13 23:17:19 2009 +0100 @@ -0,0 +1,61 @@ +#!/bin/sh -e + +# test of hg diff --change + +set -e + +ec() { + echo "invoking $@:" + "$@" +} + +hg init a +cd a + +echo "first" > file.txt +hg add file.txt +hg commit -m 'first commit' # 0 + +echo "second" > file.txt +hg commit -m 'second commit' # 1 + +echo "third" > file.txt +hg commit -m 'third commit' # 2 + +ec hg diff --nodates --change 1 + +echo + +#rev=$(hg log -r 1 --template '{node|short}') +rev=e9b286083166 +ec hg diff --nodates --change "$rev" + +## +# Testing diff -c when merge + +for i in 1 2 3 4 5 6 7 8 9 10; do + echo $i >> file.txt +done +hg commit -m "lots of text" # 3 + +sed -i -e 's,^2$,x,' file.txt +hg commit -m "changed 2 to x" # 4 + +hg up -r 3 > /dev/null 2>&1 # updated, merged, removed, unresolved +sed -i -e 's,^8$,y,' file.txt +hg commit -m "change 8 to y" > /dev/null 2>&1 # 5 # created new head + +hg up -C -r 4 > /dev/null 2>&1 # updated, merged, removed, unresolved +hg merge -r 5 > /dev/null 2>&1 # updated, merged, removed, unresolved +hg commit -m "merging 8 to y" # 6 + +echo +ec hg diff --nodates --change 6 # must be similar to hg diff --nodates --change 5 + +#echo +#hg log + +echo +echo "EOF" + +# vim: set ts=4 sw=4 et:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-diff-change.out Tue Jan 13 23:17:19 2009 +0100 @@ -0,0 +1,30 @@ +invoking hg diff --nodates --change 1: +diff -r 4bb65dda5db4 -r e9b286083166 file.txt +--- a/file.txt ++++ b/file.txt +@@ -1,1 +1,1 @@ +-first ++second + +invoking hg diff --nodates --change e9b286083166: +diff -r 4bb65dda5db4 -r e9b286083166 file.txt +--- a/file.txt ++++ b/file.txt +@@ -1,1 +1,1 @@ +-first ++second + +invoking hg diff --nodates --change 6: +diff -r e8a0797e73a6 -r aa9873050139 file.txt +--- a/file.txt ++++ b/file.txt +@@ -6,6 +6,6 @@ + 5 + 6 + 7 +-8 ++y + 9 + 10 + +EOF
--- a/tests/test-hardlinks-safety.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-hardlinks-safety.out Tue Jan 13 23:17:19 2009 +0100 @@ -2,10 +2,10 @@ % init adding foo to series file applying foo -Now at: foo +now at: foo adding bar to series file applying bar -Now at: bar +now at: bar 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c:bar %
--- a/tests/test-help.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-help.out Tue Jan 13 23:17:19 2009 +0100 @@ -221,6 +221,7 @@ options: -r --rev revision + -c --change change made by revision -a --text treat all files as text -g --git use git extended diff format --nodates don't include dates in diff headers
--- a/tests/test-hgweb-filelog Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-hgweb-filelog Tue Jan 13 23:17:19 2009 +0100 @@ -19,6 +19,9 @@ hg mv b c hg ci -m "mv b" +echo c >> c +hg ci -m "change c" + hg log -p hg serve -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
--- a/tests/test-hgweb-filelog.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-hgweb-filelog.out Tue Jan 13 23:17:19 2009 +0100 @@ -1,8 +1,20 @@ adding b adding a adding a +changeset: 6:38d962e6234d +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: change c + +diff -r a3b6a9e4507e -r 38d962e6234d c +--- a/c Thu Jan 01 00:00:00 1970 +0000 ++++ b/c Thu Jan 01 00:00:00 1970 +0000 +@@ -1,1 +1,2 @@ + b ++c + changeset: 5:a3b6a9e4507e -tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: mv b @@ -474,8 +486,8 @@ <a href="/shortlog?style=spartan">shortlog</a> <a href="/graph?style=spartan">graph</a> <a href="/tags?style=spartan">tags</a> -<a href="/file/a3b6a9e4507e/c?style=spartan">file</a> -<a href="/annotate/a3b6a9e4507e/c?style=spartan">annotate</a> +<a href="/file/38d962e6234d/c?style=spartan">file</a> +<a href="/annotate/38d962e6234d/c?style=spartan">annotate</a> <a type="application/rss+xml" href="/rss-log/tip/c">rss</a> <a type="application/atom+xml" href="/atom-log/tip/c" title="Atom feed for test:c">atom</a> </div> @@ -487,6 +499,31 @@ <table class="logEntry parity0"> <tr> <th class="age">many years ago:</th> + <th class="firstline"><a href="/rev/38d962e6234d?style=spartan">change c</a></th> + </tr> + <tr> + <th class="revision">revision 1:</td> + <td class="node"> + <a href="/file/38d962e6234d/c?style=spartan">38d962e6234d</a> + <a href="/diff/38d962e6234d/c?style=spartan">(diff)</a> + <a href="/annotate/38d962e6234d/c?style=spartan">(annotate)</a> + </td> + </tr> + + <tr> + <th class="author">author:</th> + <td class="author">test</td> + </tr> + <tr> + <th class="date">date:</th> + <td class="date">Thu Jan 01 00:00:00 1970 +0000</td> + </tr> +</table> + + +<table class="logEntry parity1"> + <tr> + <th class="age">many years ago:</th> <th class="firstline"><a href="/rev/a3b6a9e4507e?style=spartan">mv b</a></th> </tr> <tr>
--- a/tests/test-highlight Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-highlight Tue Jan 13 23:17:19 2009 +0100 @@ -68,7 +68,7 @@ echo % errors encountered cat errors.log -kill `cat hg.pid` +"$TESTDIR/killdaemons.py" # Change the pygments style cat > .hg/hgrc <<EOF @@ -87,4 +87,3 @@ echo % errors encountered cat errors.log -
--- a/tests/test-keyword.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-keyword.out Tue Jan 13 23:17:19 2009 +0100 @@ -213,15 +213,15 @@ +$Id$ +tests for different changenodes % qpop -Patch queue now empty +patch queue now empty % qgoto - should imply qpush applying mqtest.diff -Now at: mqtest.diff +now at: mqtest.diff % cat $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $ tests for different changenodes % qpop and move on -Patch queue now empty +patch queue now empty % copy % kwfiles added a
--- a/tests/test-mq Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq Tue Jan 13 23:17:19 2009 +0100 @@ -289,7 +289,7 @@ hg strip -qn tip hg tip 2>&1 | sed -e 's/unknown node .*/unknown node/' hg branches 2>&1 | sed -e 's/unknown node .*/unknown node/' -hg qpop +hg qpop 2>&1 | sed -e 's/unknown node .*/unknown node/' cat >>$HGRCPATH <<EOF [diff] @@ -510,3 +510,8 @@ hg st hg diff --config diff.nodates=True hg qdiff --config diff.nodates=True + +echo % test popping revisions not in working dir ancestry +hg qseries -v +hg up qparent +hg qpop
--- a/tests/test-mq-caches.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-caches.out Tue Jan 13 23:17:19 2009 +0100 @@ -5,7 +5,7 @@ No branch cache # some regular revisions -Patch queue now empty +patch queue now empty tip: 1 3f910abad313ff802d3a23a7529433872df9b3ae 1 3f910abad313ff802d3a23a7529433872df9b3ae bar @@ -13,7 +13,7 @@ # add some mq patches applying p1 -Now at: p1 +now at: p1 tip: 2 3f910abad313ff802d3a23a7529433872df9b3ae 1 3f910abad313ff802d3a23a7529433872df9b3ae bar @@ -43,11 +43,11 @@ qbase: 1 # detect an invalid cache -Patch queue now empty +patch queue now empty applying p0 applying p1 applying p2 -Now at: p2 +now at: p2 tip: 3 9539f35bdc80732cc9a3f84e46508f1ed1ec8cff 0 9539f35bdc80732cc9a3f84e46508f1ed1ec8cff foo
--- a/tests/test-mq-guards.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-guards.out Tue Jan 13 23:17:19 2009 +0100 @@ -1,68 +1,68 @@ adding x -Patch queue now empty +patch queue now empty % should fail abort: no patch named does-not-exist.patch % should fail abort: no patches applied applying a.patch -Now at: a.patch +now at: a.patch % should guard a.patch % should print +a a.patch: +a -Patch queue now empty +patch queue now empty % should fail cannot push 'a.patch' - guarded by ['+a'] a.patch: +a % should push b.patch applying b.patch -Now at: b.patch -Patch queue now empty +now at: b.patch +patch queue now empty % test selection of an empty guard abort: guard cannot be an empty string number of unguarded, unapplied patches has changed from 2 to 3 % should push a.patch applying a.patch -Now at: a.patch +now at: a.patch % should print -a c.patch: -a % should skip c.patch applying b.patch skipping c.patch - guarded by '-a' -Now at: b.patch +now at: b.patch % should display b.patch b.patch % should push c.patch applying c.patch -Now at: c.patch -Patch queue now empty +now at: c.patch +patch queue now empty guards deactivated number of unguarded, unapplied patches has changed from 3 to 2 % should push all applying b.patch applying c.patch -Now at: c.patch -Patch queue now empty +now at: c.patch +patch queue now empty number of unguarded, unapplied patches has changed from 1 to 2 % should push a.patch, not b.patch applying a.patch -Now at: a.patch +now at: a.patch applying c.patch -Now at: c.patch -Patch queue now empty +now at: c.patch +patch queue now empty % should push b.patch applying b.patch -Now at: b.patch +now at: b.patch applying c.patch -Now at: c.patch +now at: c.patch c.patch -Patch queue now empty +patch queue now empty number of unguarded, unapplied patches has changed from 2 to 3 % should push a.patch, b.patch applying a.patch -Now at: a.patch +now at: a.patch applying b.patch -Now at: b.patch -Patch queue now empty +now at: b.patch +patch queue now empty number of unguarded, unapplied patches has changed from 3 to 2 % list patches and guards a.patch: +1 +2 -3 @@ -78,15 +78,15 @@ 3 % should push b.patch applying b.patch -Now at: b.patch +now at: b.patch applying c.patch -Now at: c.patch +now at: c.patch guards deactivated popping guarded patches -Patch queue now empty +patch queue now empty reapplying unguarded patches applying c.patch -Now at: c.patch +now at: c.patch % guards in series file: +1 +2 -3 +1 +2 @@ -100,7 +100,7 @@ new.patch: +1 +2 -3 b.patch: +2 c.patch: unguarded -Now at: c.patch +now at: c.patch % should show new.patch and b.patch as Guarded, c.patch as Applied % and d.patch as Unapplied 0 G new.patch @@ -112,7 +112,7 @@ 1 G b.patch 2 A c.patch 3 G d.patch -Patch queue now empty +patch queue now empty new.patch: +1 +2 -3 b.patch: +2 c.patch: unguarded @@ -141,7 +141,7 @@ skipping b.patch - guarded by ['+2'] applying c.patch skipping d.patch - guarded by ['+2'] -Now at: c.patch +now at: c.patch % hg qapplied new.patch c.patch
--- a/tests/test-mq-header-date.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-header-date.out Tue Jan 13 23:17:19 2009 +0100 @@ -42,7 +42,7 @@ +2 1: [mq]: 2.patch - test 0: [mq]: 1.patch - test -Now at: 1.patch +now at: 1.patch ==== qnew -d -m # HG changeset patch # Date 6 0 @@ -127,10 +127,9 @@ 2: Four - test 1: Three (again) - test 0: [mq]: 1.patch - test -Now at: 3.patch +now at: 3.patch ==== qnew with HG header -Now at: 3.patch -Now at: 5.patch +now at: 3.patch # HG changeset patch # Date 10 0 2: imported patch 5.patch - test - 10.00 @@ -186,7 +185,7 @@ 2: [mq]: 5.patch - test 1: Three (again) - test 0: [mq]: 1.patch - test -Now at: 5.patch +now at: 5.patch ==== qnew -d adding 7 # HG changeset patch @@ -241,7 +240,7 @@ 2: [mq]: 5.patch - test 1: Three (again) - test 0: [mq]: 1.patch - test -Now at: 7.patch +now at: 7.patch ==== qnew -m adding 9 Nine @@ -271,14 +270,14 @@ 2: [mq]: 5.patch - test 1: Three (again) - test 0: [mq]: 1.patch - test -Now at: 7.patch +now at: 7.patch ==== qpop -a / qpush -a -Patch queue now empty +patch queue now empty applying 1.patch applying 3.patch applying 5.patch applying 7.patch -Now at: 7.patch +now at: 7.patch 3: imported patch 7.patch - john - 13.00 2: imported patch 5.patch - test - 11.00 1: Three (again) - test - 8.00
--- a/tests/test-mq-header-from Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-header-from Tue Jan 13 23:17:19 2009 +0100 @@ -83,7 +83,7 @@ hg qpop echo "# HG changeset patch" >>.hg/patches/5.patch echo "# User johndoe" >>.hg/patches/5.patch -hg qpush 2>&1 | grep 'Now at' +hg qpush 2>&1 | grep 'now at' catlog 5 echo ==== hg qref
--- a/tests/test-mq-header-from.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-header-from.out Tue Jan 13 23:17:19 2009 +0100 @@ -131,8 +131,8 @@ 1: [mq]: 2.patch - jane 0: [mq]: 1.patch - mary ==== qnew with HG header -Now at: 4.patch -Now at: 5.patch +now at: 4.patch +now at: 5.patch # HG changeset patch # User johndoe 4: imported patch 5.patch - johndoe @@ -184,13 +184,13 @@ 1: [mq]: 2.patch - jane 0: [mq]: 1.patch - mary ==== qpop -a / qpush -a -Patch queue now empty +patch queue now empty applying 1.patch applying 2.patch applying 3.patch applying 4.patch applying 5.patch -Now at: 5.patch +now at: 5.patch 4: imported patch 5.patch - johndeere 3: Four - jane 2: Three (again) - maria
--- a/tests/test-mq-merge.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-merge.out Tue Jan 13 23:17:19 2009 +0100 @@ -8,9 +8,9 @@ b merging with queue at: .hg/patches.1 applying rm_a -Now at: rm_a +now at: rm_a b -Patch queue now empty +patch queue now empty % init t2 adding a @@ -21,4 +21,4 @@ merging with queue at refqueue (working directory not at tip) applying patcha -Now at: patcha +now at: patcha
--- a/tests/test-mq-missingfiles.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-missingfiles.out Tue Jan 13 23:17:19 2009 +0100 @@ -1,12 +1,12 @@ adding b -Patch queue now empty +patch queue now empty % push patch with missing target applying changeb unable to find 'b' for patching 2 out of 2 hunks FAILED -- saving rejects to file b.rej patch failed, unable to continue (try -v) patch failed, rejects left in working dir -Errors during apply, please fix and refresh changeb +errors during apply, please fix and refresh changeb % display added files a c @@ -26,7 +26,7 @@ +c +c adding b -Patch queue now empty +patch queue now empty % push git patch with missing target applying changeb unable to find 'b' for patching @@ -35,7 +35,7 @@ b: No such file or directory b not tracked! patch failed, rejects left in working dir -Errors during apply, please fix and refresh changeb +errors during apply, please fix and refresh changeb ? b.rej % display added files a @@ -49,6 +49,6 @@ % test push creating directory during git copy or rename adding a -Patch queue now empty +patch queue now empty applying patch -Now at: patch +now at: patch
--- a/tests/test-mq-pull-from-bundle.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-pull-from-bundle.out Tue Jan 13 23:17:19 2009 +0100 @@ -13,7 +13,7 @@ 1: main: one updated. ====== Setup queue adding two -Patch queue now empty +patch queue now empty ====== Bundle queue 1 changesets found ====== Clone base
--- a/tests/test-mq-qclone-http.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-qclone-http.out Tue Jan 13 23:17:19 2009 +0100 @@ -25,7 +25,7 @@ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved a applying b.patch -Now at: b.patch +now at: b.patch imported patch b.patch a % test with normal collection @@ -50,7 +50,7 @@ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved a applying b.patch -Now at: b.patch +now at: b.patch imported patch b.patch a % test with old-style collection @@ -75,6 +75,6 @@ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved a applying b.patch -Now at: b.patch +now at: b.patch imported patch b.patch a
--- a/tests/test-mq-qdelete.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-qdelete.out Tue Jan 13 23:17:19 2009 +0100 @@ -1,14 +1,14 @@ adding base abort: qdelete requires at least one revision or patch name abort: cannot delete applied patch c -Now at: b +now at: b a b a b series status -Now at: a +now at: a a b series @@ -27,10 +27,10 @@ no patches applied abort: revision 0 is not managed abort: cannot delete revision 2 above applied patches -Now at: b +now at: b abort: unknown revision 'c'! applying c -Now at: c +now at: c c 3 imported patch c 2 [mq]: b
--- a/tests/test-mq-qdiff.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-qdiff.out Tue Jan 13 23:17:19 2009 +0100 @@ -26,7 +26,7 @@ +patched % revert % qpop -Patch queue now empty +patch queue now empty % qdelete mqbase % commit 2 adding lines
--- a/tests/test-mq-qgoto.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-qgoto.out Tue Jan 13 23:17:19 2009 +0100 @@ -1,21 +1,21 @@ adding a -Now at: a.patch +now at: a.patch applying b.patch applying c.patch -Now at: c.patch -Now at: b.patch +now at: c.patch +now at: b.patch % Using index -Now at: a.patch +now at: a.patch applying b.patch applying c.patch -Now at: c.patch +now at: c.patch % No warnings when using index -Now at: b.patch +now at: b.patch applying c.patch applying bug314159 -Now at: bug314159 +now at: bug314159 % Detect ambiguous non-index patch name "14" is ambiguous:
--- a/tests/test-mq-qimport.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-qimport.out Tue Jan 13 23:17:19 2009 +0100 @@ -6,19 +6,19 @@ % import patch that already exists abort: patch "url.diff" already exists applying url.diff -Now at: url.diff +now at: url.diff foo -Patch queue now empty +patch queue now empty % qimport -f adding url.diff to series file applying url.diff -Now at: url.diff +now at: url.diff foo2 -Patch queue now empty +patch queue now empty % build diff with CRLF adding b 1 files updated, 0 files merged, 0 files removed, 0 files unresolved % qimport CRLF diff adding b.diff to series file applying b.diff -Now at: b.diff +now at: b.diff
--- a/tests/test-mq-qnew.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-qnew.out Tue Jan 13 23:17:19 2009 +0100 @@ -20,7 +20,7 @@ abort: patch "first.patch" already exists abort: patch "first.patch" already exists % qnew -f from a subdirectory -Patch queue now empty +patch queue now empty adding d/b M d/b diff --git a/d/b b/d/b
--- a/tests/test-mq-qpush-fail.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-qpush-fail.out Tue Jan 13 23:17:19 2009 +0100 @@ -1,5 +1,5 @@ adding foo -Patch queue now empty +patch queue now empty applying patch1 applying patch2 applying bad-patch
--- a/tests/test-mq-qrefresh-replace-log-message.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-qrefresh-replace-log-message.out Tue Jan 13 23:17:19 2009 +0100 @@ -1,7 +1,7 @@ ======================= Should fail if no patches applied -No patches applied -No patches applied +no patches applied +no patches applied ======================= Should display 'First commit message' description:
--- a/tests/test-mq-safety.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-safety.out Tue Jan 13 23:17:19 2009 +0100 @@ -1,7 +1,7 @@ % try to commit on top of a patch abort: cannot commit over an applied mq patch % qpop/qrefresh on the wrong revision -abort: working directory revision is not qtip +abort: popping would remove a revision not managed by this patch queue using patch queue: abort: popping would remove a revision not managed by this patch queue abort: working directory revision is not qtip
--- a/tests/test-mq-symlinks.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq-symlinks.out Tue Jan 13 23:17:19 2009 +0100 @@ -1,10 +1,10 @@ a -> a not a symlink a -> b -Now at: base.patch +now at: base.patch applying symlink.patch -Now at: symlink.patch +now at: symlink.patch a -> b -Now at: symlink.patch +now at: symlink.patch applying removesl.patch -Now at: removesl.patch +now at: removesl.patch C b
--- a/tests/test-mq.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-mq.out Tue Jan 13 23:17:19 2009 +0100 @@ -33,7 +33,7 @@ qfold fold the named patches into the current patch qgoto push or pop patches until named patch is at top of stack qguard set or print guards for a patch - qheader Print the header of the topmost or specified patch + qheader print the header of the topmost or specified patch qimport import a patch qinit init a new queue repository qnew create a new patch @@ -108,28 +108,28 @@ a +a % qpop -Patch queue now empty +patch queue now empty % qpush applying test.patch -Now at: test.patch +now at: test.patch % pop/push outside repo -Patch queue now empty +patch queue now empty applying test.patch -Now at: test.patch +now at: test.patch % qrefresh in subdir % pop/push -a in subdir -Patch queue now empty +patch queue now empty applying test.patch applying test2.patch -Now at: test2.patch +now at: test2.patch % qseries test.patch test2.patch -Now at: test.patch +now at: test.patch 0 A test.patch: foo bar 1 U test2.patch: applying test2.patch -Now at: test2.patch +now at: test2.patch % qapplied test.patch test2.patch @@ -138,11 +138,11 @@ % qprev test.patch % qnext -All patches applied +all patches applied % pop, qnext, qprev, qapplied -Now at: test.patch +now at: test.patch test2.patch -Only one patch applied +only one patch applied test.patch % commit should fail abort: cannot commit over an applied mq patch @@ -155,19 +155,19 @@ test2.patch % qpush/qpop with index applying test2.patch -Now at: test2.patch -Now at: test.patch +now at: test2.patch +now at: test.patch applying test1b.patch -Now at: test1b.patch +now at: test1b.patch applying test2.patch -Now at: test2.patch -Now at: test1b.patch -Now at: test.patch +now at: test2.patch +now at: test1b.patch +now at: test.patch applying test1b.patch applying test2.patch -Now at: test2.patch +now at: test2.patch % push should succeed -Patch queue now empty +patch queue now empty pushing to ../../k searching for changes adding changesets @@ -178,9 +178,9 @@ applying test.patch applying test1b.patch applying test2.patch -Now at: test2.patch +now at: test2.patch % pops all patches and succeeds -Patch queue now empty +patch queue now empty qpop -a succeeds % does nothing and succeeds no patches applied @@ -190,15 +190,15 @@ qpop fails % pushes a patch and succeeds applying test.patch -Now at: test.patch +now at: test.patch qpush succeeds % pops a patch and succeeds -Patch queue now empty +patch queue now empty qpop succeeds % pushes up to test1b.patch and succeeds applying test.patch applying test1b.patch -Now at: test1b.patch +now at: test1b.patch qpush test1b.patch succeeds % does nothing and succeeds qpush: test1b.patch is already at the top @@ -213,12 +213,12 @@ abort: patch test2.patch is not applied qpop test2.patch fails % pops up to test.patch and succeeds -Now at: test.patch +now at: test.patch qpop test.patch succeeds % pushes all patches and succeeds applying test1b.patch applying test2.patch -Now at: test2.patch +now at: test2.patch qpush -a succeeds % does nothing and succeeds all patches are currently applied @@ -269,14 +269,14 @@ +f M a % qpush failure -Patch queue now empty +patch queue now empty applying foo applying bar file foo already exists 1 out of 1 hunks FAILED -- saving rejects to file foo.rej patch failed, unable to continue (try -v) patch failed, rejects left in working dir -Errors during apply, please fix and refresh bar +errors during apply, please fix and refresh bar ? foo ? foo.rej % mq tags @@ -284,7 +284,7 @@ 1 qbase foo 2 qtip bar tip % bad node in status -Now at: foo +now at: foo changeset: 0:cb9a9f314b8b mq status file refers to unknown node tag: tip @@ -294,7 +294,7 @@ mq status file refers to unknown node default 0:cb9a9f314b8b -abort: working directory revision is not qtip +abort: trying to pop unknown node new file diff --git a/new b/new @@ -308,9 +308,9 @@ diff --git a/new b/copy copy from new copy to copy -Now at: new +now at: new applying copy -Now at: copy +now at: copy diff --git a/new b/copy copy from new copy to copy @@ -325,10 +325,10 @@ adding manifests adding file changes added 1 changesets with 1 changes to 1 files -Patch queue now empty +patch queue now empty (working directory not at tip) applying bar -Now at: bar +now at: bar diff --git a/bar b/bar new file mode 100644 --- /dev/null @@ -359,10 +359,10 @@ adding manifests adding file changes added 1 changesets with 1 changes to 1 files -Patch queue now empty +patch queue now empty (working directory not at tip) applying bar -Now at: bar +now at: bar diff --git a/foo b/bleh rename from foo rename to bleh @@ -386,16 +386,16 @@ % refresh omitting an added file C newfile A newfile -Now at: bar +now at: bar % create a git patch diff --git a/alexander b/alexander % create a git binary patch 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus diff --git a/bucephalus b/bucephalus % check binary patches can be popped and pushed -Now at: addalexander +now at: addalexander applying addbucephalus -Now at: addbucephalus +now at: addbucephalus 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus % strip again 1 files updated, 0 files merged, 0 files removed, 0 files unresolved @@ -461,7 +461,7 @@ rev 0: add foo patch repo: rev 0: checkpoint -Patch queue now empty +patch queue now empty main repo: rev 0: add foo patch repo: @@ -475,13 +475,13 @@ rev 0: checkpoint % test applying on an empty file (issue 1033) adding a -Patch queue now empty +patch queue now empty applying changea -Now at: changea +now at: changea % test qpush with --force, issue1087 adding bye.txt adding hello.txt -Patch queue now empty +patch queue now empty % qpush should fail, local changes abort: local changes found, refresh first % apply force, should not discard changes with empty patch @@ -489,7 +489,7 @@ patch: **** Only garbage was found in the patch input. patch failed, unable to continue (try -v) patch empty is empty -Now at: empty +now at: empty diff -r bf5fc3f07a0a hello.txt --- a/hello.txt +++ b/hello.txt @@ -512,12 +512,12 @@ summary: imported patch empty -Patch queue now empty +patch queue now empty % qpush should fail, local changes abort: local changes found, refresh first % apply force, should discard changes in hello, but not bye applying empty -Now at: empty +now at: empty M bye.txt diff -r ba252371dbc1 bye.txt --- a/bye.txt @@ -538,3 +538,7 @@ hello +world +universe +% test popping revisions not in working dir ancestry +0 A empty +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +patch queue now empty
--- a/tests/test-notify.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-notify.out Tue Jan 13 23:17:19 2009 +0100 @@ -150,7 +150,8 @@ b diffstat: -files patched: 1 + a | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (6 lines):
--- a/tests/test-patchbomb Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-patchbomb Tue Jan 13 23:17:19 2009 +0100 @@ -11,6 +11,8 @@ echo "[extensions]" >> $HGRCPATH echo "patchbomb=" >> $HGRCPATH +COLUMNS=80; export COLUMNS + hg init t cd t echo a > a
--- a/tests/test-patchbomb.out Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-patchbomb.out Tue Jan 13 23:17:19 2009 +0100 @@ -196,7 +196,8 @@ c -files patched: 1 + c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) Displaying [PATCH] test ... @@ -211,7 +212,8 @@ To: foo Cc: bar -files patched: 1 + c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) # HG changeset patch @@ -232,15 +234,19 @@ a -files patched: 1 + a | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) b -files patched: 1 + b | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) Final summary: -files patched: 2 + a | 1 + + b | 1 + + 2 files changed, 2 insertions(+), 0 deletions(-) Write the introductory message for the patch series. @@ -258,7 +264,9 @@ Cc: bar -files patched: 2 + a | 1 + + b | 1 + + 2 files changed, 2 insertions(+), 0 deletions(-) Displaying [PATCH 1 of 2] a ... Content-Type: text/plain; charset="us-ascii" @@ -274,7 +282,8 @@ To: foo Cc: bar -files patched: 1 + a | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) # HG changeset patch @@ -304,7 +313,8 @@ To: foo Cc: bar -files patched: 1 + b | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) # HG changeset patch
--- a/tests/test-pull-http Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-pull-http Tue Jan 13 23:17:19 2009 +0100 @@ -19,7 +19,7 @@ hg serve -p $HGPORT -d --pid-file=hg.pid -E errors.log cat hg.pid >> $DAEMON_PIDS hg clone http://localhost:$HGPORT/ test3 | sed -e 's,:[0-9][0-9]*/,/,' -kill `cat hg.pid` +"$TESTDIR/killdaemons.py" echo % serve errors cat errors.log
--- a/tests/test-walkrepo.py Tue Jan 13 22:41:06 2009 +0100 +++ b/tests/test-walkrepo.py Tue Jan 13 23:17:19 2009 +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: