Mercurial > hg
changeset 9778:6cb1808e5ae7
Merge with i18n
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sat, 07 Nov 2009 14:13:15 -0600 |
parents | ffda19f351fa (diff) b2dfe76459dc (current diff) |
children | 58a6f3f4d553 54d292da1df7 a0bf760c0dae |
files | |
diffstat | 120 files changed, 1876 insertions(+), 918 deletions(-) [+] |
line wrap: on
line diff
--- a/contrib/hg-relink Wed Nov 04 22:14:26 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (C) 2007 Brendan Cully <brendan@kublai.com> -# -# This software may be used and distributed according to the terms of the -# GNU General Public License version 2, incorporated herein by reference. - -import os, sys - -class ConfigError(Exception): pass - -def usage(): - print """relink <source> <destination> - Recreate hard links between source and destination repositories""" - -class Config: - def __init__(self, args): - if len(args) != 3: - raise ConfigError("wrong number of arguments") - self.src = os.path.abspath(args[1]) - self.dst = os.path.abspath(args[2]) - for d in (self.src, self.dst): - if not os.path.exists(os.path.join(d, '.hg')): - raise ConfigError("%s: not a mercurial repository" % d) - -def collect(src): - seplen = len(os.path.sep) - candidates = [] - for dirpath, dirnames, filenames in os.walk(src): - relpath = dirpath[len(src) + seplen:] - for filename in filenames: - if not filename.endswith('.i'): - continue - st = os.stat(os.path.join(dirpath, filename)) - candidates.append((os.path.join(relpath, filename), st)) - - return candidates - -def prune(candidates, dst): - def getdatafile(path): - if not path.endswith('.i'): - return None, None - df = path[:-1] + 'd' - try: - st = os.stat(df) - except OSError: - return None, None - return df, st - - def linkfilter(dst, st): - try: - ts = os.stat(dst) - except OSError: - # Destination doesn't have this file? - return False - if st.st_ino == ts.st_ino: - return False - if st.st_dev != ts.st_dev: - # No point in continuing - raise Exception('Source and destination are on different devices') - if st.st_size != ts.st_size: - # TODO: compare revlog heads - return False - return st - - targets = [] - for fn, st in candidates: - tgt = os.path.join(dst, fn) - ts = linkfilter(tgt, st) - if not ts: - continue - targets.append((fn, ts.st_size)) - df, ts = getdatafile(tgt) - if df: - targets.append((fn[:-1] + 'd', ts.st_size)) - - return targets - -def relink(src, dst, files): - def relinkfile(src, dst): - bak = dst + '.bak' - os.rename(dst, bak) - try: - os.link(src, dst) - except OSError: - os.rename(bak, dst) - raise - os.remove(bak) - - CHUNKLEN = 65536 - relinked = 0 - savedbytes = 0 - - for f, sz in files: - source = os.path.join(src, f) - tgt = os.path.join(dst, f) - sfp = file(source) - dfp = file(tgt) - sin = sfp.read(CHUNKLEN) - while sin: - din = dfp.read(CHUNKLEN) - if sin != din: - break - sin = sfp.read(CHUNKLEN) - if sin: - continue - try: - relinkfile(source, tgt) - print 'Relinked %s' % f - relinked += 1 - savedbytes += sz - except OSError, inst: - print '%s: %s' % (tgt, str(inst)) - - print 'Relinked %d files (%d bytes reclaimed)' % (relinked, savedbytes) - -try: - cfg = Config(sys.argv) -except ConfigError, inst: - print str(inst) - usage() - sys.exit(1) - -src = os.path.join(cfg.src, '.hg') -dst = os.path.join(cfg.dst, '.hg') -candidates = collect(src) -targets = prune(candidates, dst) -relink(src, dst, targets)
--- a/contrib/shrink-revlog.py Wed Nov 04 22:14:26 2009 +0100 +++ b/contrib/shrink-revlog.py Sat Nov 07 14:13:15 2009 -0600 @@ -87,12 +87,12 @@ count += 1 finally: write('\n') - + def report(olddatafn, newdatafn): oldsize = float(os.stat(olddatafn).st_size) newsize = float(os.stat(newdatafn).st_size) - # argh: have to pass an int to %d, because a float >= 2^32 + # argh: have to pass an int to %d, because a float >= 2^32 # blows up under Python 2.5 or earlier sys.stdout.write('old file size: %12d bytes (%6.1f MiB)\n' % (int(oldsize), oldsize/1024/1024))
--- a/doc/Makefile Wed Nov 04 22:14:26 2009 +0100 +++ b/doc/Makefile Sat Nov 07 14:13:15 2009 -0600 @@ -1,6 +1,7 @@ SOURCES=$(wildcard *.[0-9].txt) MAN=$(SOURCES:%.txt=%) HTML=$(SOURCES:%.txt=%.html) +GENDOC=gendoc.py ../mercurial/commands.py ../mercurial/help.py ../help/*.txt PREFIX=/usr/local MANDIR=$(PREFIX)/share/man INSTALL=install -c -m 644 @@ -16,7 +17,7 @@ hg.1.txt: hg.1.gendoc.txt touch hg.1.txt -hg.1.gendoc.txt: gendoc.py ../mercurial/commands.py ../mercurial/help.py +hg.1.gendoc.txt: $(GENDOC) ${PYTHON} gendoc.py > $@.tmp mv $@.tmp $@
--- a/doc/hg.1.txt Wed Nov 04 22:14:26 2009 +0100 +++ b/doc/hg.1.txt Sat Nov 07 14:13:15 2009 -0600 @@ -30,7 +30,7 @@ files... indicates one or more filename or relative path filenames; see - "FILE NAME PATTERNS" for information on pattern matching + `File Name Patterns`_ for information on pattern matching path indicates a path on the local machine @@ -72,7 +72,7 @@ BUGS ---- -Probably lots, please post them to the mailing list (See Resources +Probably lots, please post them to the mailing list (see Resources_ below) when you find them. SEE ALSO @@ -93,7 +93,7 @@ COPYING ------- -Copyright \(C) 2005-2009 Matt Mackall. +Copyright (C) 2005-2009 Matt Mackall. Free use of this software is granted under the terms of the GNU General Public License version 2.
--- a/doc/hgrc.5.txt Wed Nov 04 22:14:26 2009 +0100 +++ b/doc/hgrc.5.txt Sat Nov 07 14:13:15 2009 -0600 @@ -29,50 +29,9 @@ The names of these files depend on the system on which Mercurial is installed. ``*.rc`` files from a single directory are read in alphabetical order, later ones overriding earlier ones. Where multiple -paths are given below, settings from later paths override earlier +paths are given below, settings from earlier paths override later ones. -| (Unix) ``<install-root>/etc/mercurial/hgrc.d/*.rc`` -| (Unix) ``<install-root>/etc/mercurial/hgrc`` - - Per-installation configuration files, searched for in the - directory where Mercurial is installed. ``<install-root>`` is the - parent directory of the **hg** executable (or symlink) being run. For - example, if installed in ``/shared/tools/bin/hg``, Mercurial will look - in ``/shared/tools/etc/mercurial/hgrc``. Options in these files apply - to all Mercurial commands executed by any user in any directory. - -| (Unix) ``/etc/mercurial/hgrc.d/*.rc`` -| (Unix) ``/etc/mercurial/hgrc`` - - Per-system configuration files, for the system on which Mercurial - is running. Options in these files apply to all Mercurial commands - executed by any user in any directory. Options in these files - override per-installation options. - -| (Windows) ``<install-dir>\Mercurial.ini`` or else -| (Windows) ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` or else -| (Windows) ``C:\Mercurial\Mercurial.ini`` - - Per-installation/system configuration files, for the system on - which Mercurial is running. Options in these files apply to all - Mercurial commands executed by any user in any directory. Registry - keys contain PATH-like strings, every part of which must reference - a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will - be read. - -| (Unix) ``$HOME/.hgrc`` -| (Windows) ``%HOME%\Mercurial.ini`` -| (Windows) ``%HOME%\.hgrc`` -| (Windows) ``%USERPROFILE%\Mercurial.ini`` -| (Windows) ``%USERPROFILE%\.hgrc`` - - Per-user configuration file(s), for the user running Mercurial. On - Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``. Options in these - files apply to all Mercurial commands executed by this user in any - directory. Options in these files override per-installation and - per-system options. - | (Unix, Windows) ``<repo>/.hg/hgrc`` Per-repository configuration options that only apply in a @@ -81,7 +40,48 @@ this file override options in all other configuration files. On Unix, most of this file will be ignored if it doesn't belong to a trusted user or to a trusted group. See the documentation for the - trusted section below for more details. + trusted_ section below for more details. + +| (Unix) ``$HOME/.hgrc`` +| (Windows) ``%USERPROFILE%\.hgrc`` +| (Windows) ``%USERPROFILE%\Mercurial.ini`` +| (Windows) ``%HOME%\.hgrc`` +| (Windows) ``%HOME%\Mercurial.ini`` + + Per-user configuration file(s), for the user running Mercurial. On + Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``. Options in these + files apply to all Mercurial commands executed by this user in any + directory. Options in these files override per-system and per-installation + options. + +| (Unix) ``/etc/mercurial/hgrc`` +| (Unix) ``/etc/mercurial/hgrc.d/*.rc`` + + Per-system configuration files, for the system on which Mercurial + is running. Options in these files apply to all Mercurial commands + executed by any user in any directory. Options in these files + override per-installation options. + +| (Unix) ``<install-root>/etc/mercurial/hgrc`` +| (Unix) ``<install-root>/etc/mercurial/hgrc.d/*.rc`` + + Per-installation configuration files, searched for in the + directory where Mercurial is installed. ``<install-root>`` is the + parent directory of the **hg** executable (or symlink) being run. For + example, if installed in ``/shared/tools/bin/hg``, Mercurial will look + in ``/shared/tools/etc/mercurial/hgrc``. Options in these files apply + to all Mercurial commands executed by any user in any directory. + +| (Windows) ``C:\Mercurial\Mercurial.ini`` +| (Windows) ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` +| (Windows) ``<install-dir>\Mercurial.ini`` + + Per-installation/system configuration files, for the system on + which Mercurial is running. Options in these files apply to all + Mercurial commands executed by any user in any directory. Registry + keys contain PATH-like strings, every part of which must reference + a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will + be read. SYNTAX ------ @@ -97,12 +97,9 @@ eggs Each line contains one entry. If the lines that follow are indented, -they are treated as continuations of that entry. - -Leading whitespace is removed from values. Empty lines are skipped. - -Lines beginning with ``#`` or ``;`` are ignored and may be used to provide -comments. +they are treated as continuations of that entry. Leading whitespace is +removed from values. Empty lines are skipped. Lines beginning with +``#`` or ``;`` are ignored and may be used to provide comments. A line of the form ``%include file`` will include ``file`` into the current configuration file. The inclusion is recursive, which means @@ -139,9 +136,9 @@ stable5 = latest -b stable -NOTE: It is possible to create aliases with the same names as existing -commands, which will then override the original definitions. This is -almost always a bad idea! +.. note:: It is possible to create aliases with the same names as + existing commands, which will then override the original + definitions. This is almost always a bad idea! ``auth`` @@ -232,9 +229,9 @@ of an empty temporary file, where the filtered data must be written by the command. -NOTE: the tempfile mechanism is recommended for Windows systems, where -the standard shell I/O redirection operators often have strange -effects and may corrupt the contents of your files. +.. note:: The tempfile mechanism is recommended for Windows systems, + where the standard shell I/O redirection operators often have + strange effects and may corrupt the contents of your files. The most common usage is for LF <-> CRLF translation on Windows. For this, use the "smart" converters which check for binary files:: @@ -264,8 +261,8 @@ Use the [defaults] section to define command defaults, i.e. the default options/arguments to pass to the specified commands. -The following example makes 'hg log' run in verbose mode, and 'hg -status' show only the modified files, by default:: +The following example makes ``hg log`` run in verbose mode, and ``hg +status`` show only the modified files, by default:: [defaults] log = -v @@ -312,7 +309,7 @@ email addresses. Cannot be set interactively. ``method`` Optional. Method to use to send email messages. If value is "smtp" - (default), use SMTP (see section "[smtp]" for configuration). + (default), use SMTP (see the SMTP_ section for configuration). Otherwise, use as name of program to run that acts like sendmail (takes "-f" option for sender, list of recipients on command line, message on stdin). Normally, setting this to "sendmail" or @@ -326,13 +323,13 @@ conversion fails, the text in question is sent as is. Defaults to empty (explicit) list. -Order of outgoing email character sets:: + Order of outgoing email character sets: - us-ascii always first, regardless of settings - email.charsets in order given by user - ui.fallbackencoding if not in email.charsets - $HGENCODING if not in email.charsets - utf-8 always last, regardless of settings + 1. ``us-ascii``: always first, regardless of settings + 2. ``email.charsets``: in order given by user + 3. ``ui.fallbackencoding``: if not in email.charsets + 4. ``$HGENCODING``: if not in email.charsets + 5. ``utf-8``: always last, regardless of settings Email example:: @@ -494,7 +491,7 @@ Most hooks are run with environment variables set that give useful additional information. For each hook below, the environment -variables it is passed are listed with names of the form "$HG_foo". +variables it is passed are listed with names of the form ``$HG_foo``. ``changegroup`` Run after a changegroup has been added via push, pull or unbundle. @@ -575,16 +572,16 @@ in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the update failed (e.g. because conflicts not resolved), ``$HG_ERROR=1``. -NOTE: it is generally better to use standard hooks rather than the -generic pre- and post- command hooks as they are guaranteed to be -called in the appropriate contexts for influencing transactions. -Also, hooks like "commit" will be called in all contexts that -generate a commit (e.g. tag) and not just the commit command. +.. note:: It is generally better to use standard hooks rather than the + generic pre- and post- command hooks as they are guaranteed to be + called in the appropriate contexts for influencing transactions. + Also, hooks like "commit" will be called in all contexts that + generate a commit (e.g. tag) and not just the commit command. -NOTE: Environment variables with empty values may not be passed to -hooks on platforms such as Windows. As an example, ``$HG_PARENT2`` will -have an empty value under Unix-like platforms for non-merge -changesets, while it will not be available at all under Windows. +.. note:: Environment variables with empty values may not be passed to + hooks on platforms such as Windows. As an example, ``$HG_PARENT2`` + will have an empty value under Unix-like platforms for non-merge + changesets, while it will not be available at all under Windows. The syntax for Python hooks is as follows:: @@ -649,7 +646,7 @@ ``eol`` When set to 'strict' patch content and patched files end of lines - are preserved. When set to 'lf' or 'crlf', both files end of lines + are preserved. When set to ``lf`` or ``crlf``, both files end of lines are ignored when patching and the result line endings are normalized to either LF (Unix) or CRLF (Windows). Default: strict. @@ -738,17 +735,17 @@ Whether to include the .hg_archival.txt file containing meta data (hashes for the repository base and for tip) in archives created by the hg archive command or downloaded via hgweb. - Default is true. + Default is True. ``askusername`` Whether to prompt for a username when committing. If True, and neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will be prompted to enter a username. If no username is entered, the - default USER@HOST is used instead. + default ``USER@HOST`` is used instead. Default is False. ``debug`` Print debugging information. True or False. Default is False. ``editor`` - The editor to use during a commit. Default is ``$EDITOR`` or "vi". + The editor to use during a commit. Default is ``$EDITOR`` or ``vi``. ``fallbackencoding`` Encoding to try if it's not possible to decode the changelog using UTF-8. Default is ISO-8859-1. @@ -777,15 +774,15 @@ fail to merge For more information on configuring merge tools see the -merge-tools section. +merge-tools_ section. ``patch`` - command to use to apply patches. Look for 'gpatch' or 'patch' in + command to use to apply patches. Look for ``gpatch`` or ``patch`` in PATH if unset. ``quiet`` Reduce the amount of output printed. True or False. Default is False. ``remotecmd`` - remote command to use for clone/push/pull operations. Default is 'hg'. + remote command to use for clone/push/pull operations. Default is ``hg``. ``report_untrusted`` Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a trusted user or group. True or False. Default is True. @@ -796,7 +793,7 @@ backslash character (``\``)). Default is False. ``ssh`` - command to use for SSH connections. Default is 'ssh'. + command to use for SSH connections. Default is ``ssh``. ``strict`` Require exact command names, instead of allowing unambiguous abbreviations. True or False. Default is False. @@ -805,13 +802,18 @@ ``timeout`` The timeout used when a lock is held (in seconds), a negative value means no timeout. Default is 600. +``traceback`` + Mercurial always prints a traceback when an unknown exception + occurs. Setting this to True will make Mercurial print a traceback + on all exceptions, even those recognized by Mercurial (such as + IOError or MemoryError). Default is False. ``username`` The committer of a changeset created when running "commit". - Typically a person's name and email address, e.g. "Fred Widget - <fred@example.com>". Default is ``$EMAIL`` or username@hostname. If + Typically a person's name and email address, e.g. ``Fred Widget + <fred@example.com>``. Default is ``$EMAIL`` or ``username@hostname``. If the username in hgrc is empty, it has to be specified manually or in a different hgrc file (e.g. ``$HOME/.hgrc``, if the admin set - "username =" in the system hgrc). + ``username =`` in the system hgrc). ``verbose`` Increase the amount of output printed. True or False. Default is False. @@ -830,19 +832,19 @@ ``allowbz2`` (DEPRECATED) Whether to allow .tar.bz2 downloading of repository revisions. - Default is false. + Default is False. ``allowgz`` (DEPRECATED) Whether to allow .tar.gz downloading of repository revisions. - Default is false. + Default is False. ``allowpull`` - Whether to allow pulling from the repository. Default is true. + Whether to allow pulling from the repository. Default is True. ``allow_push`` Whether to allow pushing to the repository. If empty or not set, push is not allowed. If the special value ``*``, any remote user can push, including unauthenticated users. Otherwise, the remote user must have been authenticated, and the authenticated user name must - be present in this list (separated by whitespace or ","). The + be present in this list (separated by whitespace or ``,``). The contents of the allow_push list are examined after the deny_push list. ``allow_read`` @@ -850,7 +852,7 @@ the contents of deny_read, this list determines whether to grant repository access to the user. If this list is not empty, and the user is unauthenticated or not present in the list (separated by - whitespace or ","), then access is denied for the user. If the + whitespace or ``,``), then access is denied for the user. If the list is empty or not set, then access is permitted to all users by default. Setting allow_read to the special value ``*`` is equivalent to it not being set (i.e. access is permitted to all users). The @@ -858,11 +860,11 @@ list. ``allowzip`` (DEPRECATED) Whether to allow .zip downloading of repository - revisions. Default is false. This feature creates temporary files. + revisions. Default is False. This feature creates temporary files. ``baseurl`` Base URL to use when publishing URLs in other locations, so third-party tools like email notification hooks can construct - URLs. Example: "http://hgserver/repos/" + URLs. Example: ``http://hgserver/repos/``. ``contact`` Name or email address of the person in charge of the repository. Defaults to ui.username or ``$EMAIL`` or "unknown" if unset or empty. @@ -871,13 +873,13 @@ push is not denied. If the special value ``*``, all remote users are denied push. Otherwise, unauthenticated users are all denied, and any authenticated user name present in this list (separated by - whitespace or ",") is also denied. The contents of the deny_push + whitespace or ``,``) is also denied. The contents of the deny_push list are examined before the allow_push list. ``deny_read`` Whether to deny reading/viewing of the repository. If this list is not empty, unauthenticated users are all denied, and any authenticated user name present in this list (separated by - whitespace or ",") is also denied access to the repository. If set + whitespace or ``,``) is also denied access to the repository. If set to the special value ``*``, all remote users are denied access (rarely needed ;). If deny_read is empty or not set, the determination of repository access depends on the presence and @@ -902,9 +904,9 @@ Where to output the error log. Default is stderr. ``hidden`` Whether to hide the repository in the hgwebdir index. - Default is false. + Default is False. ``ipv6`` - Whether to use IPv6. Default is false. + Whether to use IPv6. Default is False. ``name`` Repository name to use in the web interface. Default is current working directory. @@ -918,12 +920,12 @@ Prefix path to serve from. Default is '' (server root). ``push_ssl`` Whether to require that inbound pushes be transported over SSL to - prevent password sniffing. Default is true. + prevent password sniffing. Default is True. ``staticurl`` Base URL to use for static files. If unset, static files (e.g. the hgicon.png favicon) will be served by the CGI script itself. Use this setting to serve them directly with the HTTP server. - Example: "http://hgserver/static/" + Example: ``http://hgserver/static/``. ``stripes`` How many lines a "zebra stripe" should span in multiline output. Default is 1; set to 0 to disable.
--- a/doc/rst2man.py Wed Nov 04 22:14:26 2009 +0100 +++ b/doc/rst2man.py Sat Nov 07 14:13:15 2009 -0600 @@ -8,7 +8,7 @@ Simple man page writer for reStructuredText. Man pages (short for "manual pages") contain system documentation on unix-like -systems. The pages are grouped in numbered sections: +systems. The pages are grouped in numbered sections: 1 executable programs and shell commands 2 system calls @@ -140,7 +140,7 @@ text.append('|%s|.\n' % ('|'.join(self._coldefs))) for row in self._rows: # row = array of cells. cell = array of lines. - text.append('_\n') # line above + text.append('_\n') # line above text.append('T{\n') for i in range(len(row)): cell = row[i] @@ -184,8 +184,8 @@ "title" : "", "title_upper": "", "subtitle" : "", "manual_section" : "", "manual_group" : "", - "author" : [], - "date" : "", + "author" : [], + "date" : "", "copyright" : "", "version" : "", } @@ -216,7 +216,7 @@ 'literal_block' : ('.sp\n.nf\n.ft C\n', '\n.ft P\n.fi\n'), 'option_list_item' : ('.TP\n', ''), - + 'reference' : (r'\%', r'\:'), 'emphasis': ('\\fI', '\\fP'), 'strong' : ('\\fB', '\\fP'), @@ -263,7 +263,7 @@ elif (self.body[i-1][:3] == '.B ' and self.body[i-2][:4] == '.TP\n'): self.body[i] = '.\n' - elif (self.body[i-1] == '\n' and + elif (self.body[i-1] == '\n' and self.body[i-2][0] != '.' and (self.body[i-3][:7] == '.TP\n.B ' or self.body[i-3][:4] == '\n.B ') @@ -564,10 +564,10 @@ def depart_document(self, node): if self._docinfo['author']: - self.body.append('.SH AUTHOR\n%s\n' + self.body.append('.SH AUTHOR\n%s\n' % ', '.join(self._docinfo['author'])) skip = ('author', 'copyright', 'date', - 'manual_group', 'manual_section', + 'manual_group', 'manual_section', 'subtitle', 'title', 'title_upper', 'version') for name in self._docinfo_keys: @@ -587,7 +587,7 @@ label = self.language.labels.get(name, name) self.body.append("\n%s: %s\n" % (label, self._docinfo[name]) ) if self._docinfo['copyright']: - self.body.append('.SH COPYRIGHT\n%s\n' + self.body.append('.SH COPYRIGHT\n%s\n' % self._docinfo['copyright']) self.body.append( self.comment( 'Generated by docutils manpage writer.\n' ) ) @@ -896,7 +896,7 @@ def visit_paragraph(self, node): # ``.PP`` : Start standard indented paragraph. # ``.LP`` : Start block paragraph, all except the first. - # ``.P [type]`` : Start paragraph type. + # ``.P [type]`` : Start paragraph type. # NOTE dont use paragraph starts because they reset indentation. # ``.sp`` is only vertical space self.ensure_eol()
--- a/help/environment.txt Wed Nov 04 22:14:26 2009 +0100 +++ b/help/environment.txt Sat Nov 07 14:13:15 2009 -0600 @@ -50,7 +50,7 @@ - hgrc files from the HGRCPATH - EMAIL - interactive prompt - - LOGNAME (with '@hostname' appended) + - LOGNAME (with ``@hostname`` appended) (deprecated, use .hgrc)
--- a/help/templates.txt Wed Nov 04 22:14:26 2009 +0100 +++ b/help/templates.txt Sat Nov 07 14:13:15 2009 -0600 @@ -75,11 +75,11 @@ the timezone: "Mon Sep 04 15:13:13 2006 0700". :domain: Any text. Finds the first string that looks like an email address, and extracts just the domain - component. Example: 'User <user@example.com>' becomes - 'example.com'. + component. Example: ``User <user@example.com>`` becomes + ``example.com``. :email: Any text. Extracts the first string that looks like - an email address. Example: 'User <user@example.com>' - becomes 'user@example.com'. + an email address. Example: ``User <user@example.com>`` + becomes ``user@example.com``. :escape: Any text. Replaces the special XML/XHTML characters "&", "<" and ">" with XML entities. :fill68: Any text. Wraps the text to fit in 68 columns.
--- a/hgext/churn.py Wed Nov 04 22:14:26 2009 +0100 +++ b/hgext/churn.py Sat Nov 07 14:13:15 2009 -0600 @@ -23,14 +23,15 @@ return t def changedlines(ui, repo, ctx1, ctx2, fns): - lines = 0 + added, removed = 0, 0 fmatch = cmdutil.matchfiles(repo, fns) diff = ''.join(patch.diff(repo, ctx1.node(), ctx2.node(), fmatch)) for l in diff.split('\n'): - if (l.startswith("+") and not l.startswith("+++ ") or - l.startswith("-") and not l.startswith("--- ")): - lines += 1 - return lines + if l.startswith("+") and not l.startswith("+++ "): + added += 1 + elif l.startswith("-") and not l.startswith("--- "): + removed += 1 + return (added, removed) def countrate(ui, repo, amap, *pats, **opts): """Calculate stats""" @@ -47,43 +48,43 @@ tmpl.show(ctx) return ui.popbuffer() - count = pct = 0 + state = {'count': 0, 'pct': 0} rate = {} df = False if opts.get('date'): df = util.matchdate(opts['date']) m = cmdutil.match(repo, pats, opts) - for st, ctx, fns in cmdutil.walkchangerevs(ui, repo, m, opts): - if not st == 'add': - continue - + def prep(ctx, fns): rev = ctx.rev() if df and not df(ctx.date()[0]): # doesn't match date format - continue + return key = getkey(ctx) key = amap.get(key, key) # alias remap if opts.get('changesets'): - rate[key] = rate.get(key, 0) + 1 + rate[key] = (rate.get(key, (0,))[0] + 1, 0) else: parents = ctx.parents() if len(parents) > 1: ui.note(_('Revision %d is a merge, ignoring...\n') % (rev,)) - continue + return ctx1 = parents[0] lines = changedlines(ui, repo, ctx1, ctx, fns) - rate[key] = rate.get(key, 0) + lines + rate[key] = [r + l for r, l in zip(rate.get(key, (0, 0)), lines)] if opts.get('progress'): - count += 1 - newpct = int(100.0 * count / max(len(repo), 1)) - if pct < newpct: - pct = newpct - ui.write("\r" + _("generating stats: %d%%") % pct) + state['count'] += 1 + newpct = int(100.0 * state['count'] / max(len(repo), 1)) + if state['pct'] < newpct: + state['pct'] = newpct + ui.write("\r" + _("generating stats: %d%%") % state['pct']) sys.stdout.flush() + for ctx in cmdutil.walkchangerevs(repo, m, opts, prep): + continue + if opts.get('progress'): ui.write("\r") sys.stdout.flush() @@ -143,20 +144,35 @@ if not rate: return - sortkey = ((not opts.get('sort')) and (lambda x: -x[1]) or None) + sortkey = ((not opts.get('sort')) and (lambda x: -sum(x[1])) or None) rate.sort(key=sortkey) # Be careful not to have a zero maxcount (issue833) - maxcount = float(max(v for k, v in rate)) or 1.0 + maxcount = float(max(sum(v) for k, v in rate)) or 1.0 maxname = max(len(k) for k, v in rate) ttywidth = util.termwidth() ui.debug("assuming %i character terminal\n" % ttywidth) - width = ttywidth - maxname - 2 - 6 - 2 - 2 + width = ttywidth - maxname - 2 - 2 - 2 - for date, count in rate: - print "%s %6d %s" % (pad(date, maxname), count, - "*" * int(count * width / maxcount)) + if opts.get('diffstat'): + width -= 15 + def format(name, (added, removed)): + return "%s %15s %s%s\n" % (pad(name, maxname), + '+%d/-%d' % (added, removed), + '+' * charnum(added), + '-' * charnum(removed)) + else: + width -= 6 + def format(name, count): + return "%s %6d %s\n" % (pad(name, maxname), sum(count), + '*' * charnum(sum(count))) + + def charnum(count): + return int(round(count*width/maxcount)) + + for name, count in rate: + ui.write(format(name, count)) cmdtable = { @@ -169,6 +185,7 @@ _('strftime-compatible format for grouping by date')), ('c', 'changesets', False, _('count rate by number of changesets')), ('s', 'sort', False, _('sort by key (default: sort by count)')), + ('', 'diffstat', False, _('display added/removed lines separately')), ('', 'aliases', '', _('file with email aliases')), ('', 'progress', None, _('show progress'))], _("hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]")),
--- a/hgext/color.py Wed Nov 04 22:14:26 2009 +0100 +++ b/hgext/color.py Sat Nov 07 14:13:15 2009 -0600 @@ -235,7 +235,7 @@ 'changed': ['white'], 'trailingwhitespace': ['bold', 'red_background']} -def uisetup(ui): +def extsetup(ui): '''Initialize the extension.''' _setupcmd(ui, 'diff', commands.table, colordiff, _diff_effects) _setupcmd(ui, 'incoming', commands.table, None, _diff_effects) @@ -249,15 +249,17 @@ _setupcmd(ui, 'qdiff', mq.cmdtable, colordiff, _diff_effects) _setupcmd(ui, 'qseries', mq.cmdtable, colorqseries, _patch_effects) except KeyError: - # The mq extension is not enabled - pass + mq = None try: rec = extensions.find('record') _setupcmd(ui, 'record', rec.cmdtable, colordiff, _diff_effects) except KeyError: - # The record extension is not enabled - pass + rec = None + + if mq and rec: + _setupcmd(ui, 'qrecord', rec.cmdtable, colordiff, _diff_effects) + def _setupcmd(ui, cmd, table, func, effectsmap): '''patch in command to command table and load effect map'''
--- a/hgext/convert/darcs.py Wed Nov 04 22:14:26 2009 +0100 +++ b/hgext/convert/darcs.py Sat Nov 07 14:13:15 2009 -0600 @@ -118,7 +118,7 @@ output, status = self.run('revert', all=True, repodir=self.tmppath) self.checkexit(status, output) - def getchanges(self, rev): + def getchanges(self, rev): copies = {} changes = [] man = None
--- a/hgext/mq.py Wed Nov 04 22:14:26 2009 +0100 +++ b/hgext/mq.py Sat Nov 07 14:13:15 2009 -0600 @@ -1129,8 +1129,12 @@ self.ui.write(_("no patches applied\n")) return qp = self.qparents(repo, top) + if opts.get('inverse'): + node1, node2 = None, qp + else: + node1, node2 = qp, None self._diffopts = patch.diffopts(self.ui, opts) - self.printdiff(repo, qp, files=pats, opts=opts) + self.printdiff(repo, node1, node2, files=pats, opts=opts) def refresh(self, repo, pats=None, **opts): if len(self.applied) == 0: @@ -1910,11 +1914,10 @@ summary=opts.get('summary')) def setupheaderopts(ui, opts): - def do(opt, val): - if not opts[opt] and opts['current' + opt]: - opts[opt] = val - do('user', ui.username()) - do('date', "%d %d" % util.makedate()) + if not opts.get('user') and opts.get('currentuser'): + opts['user'] = ui.username() + if not opts.get('date') and opts.get('currentdate'): + opts['date'] = "%d %d" % util.makedate() def new(ui, repo, patch, *args, **opts): """create a new patch
--- a/hgext/record.py Wed Nov 04 22:14:26 2009 +0100 +++ b/hgext/record.py Sat Nov 07 14:13:15 2009 -0600 @@ -315,6 +315,7 @@ return ret pos, total = 0, len(chunks) - 1 while chunks: + pos = total - len(chunks) + 1 chunk = chunks.pop() if isinstance(chunk, header): # new-file mark @@ -350,7 +351,6 @@ applied[chunk.filename()].append(chunk) else: fixoffset += chunk.removed - chunk.added - pos = pos + 1 return reduce(operator.add, [h for h in applied.itervalues() if h[0].special() or len(h) > 1], []) @@ -531,7 +531,7 @@ } -def extsetup(): +def uisetup(ui): try: mq = extensions.find('mq') except KeyError:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hgext/relink.py Sat Nov 07 14:13:15 2009 -0600 @@ -0,0 +1,149 @@ +# Mercurial extension to provide 'hg relink' command +# +# Copyright (C) 2007 Brendan Cully <brendan@kublai.com> +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2, incorporated herein by reference. + +"""recreates hardlinks between repository clones""" + +from mercurial import cmdutil, hg, util +from mercurial.i18n import _ +import os, stat + +def relink(ui, repo, origin=None, **opts): + """recreate hardlinks between two repositories + + When repositories are cloned locally, their data files will be hardlinked + so that they only use the space of a single repository. + + Unfortunately, subsequent pulls into either repository will break hardlinks + for any files touched by the new changesets, even if both repositories end + up pulling the same changes. + + Similarly, passing --rev to "hg clone" will fail to use + any hardlinks, falling back to a complete copy of the source repository. + + This command lets you recreate those hardlinks and reclaim that wasted + space. + + This repository will be relinked to share space with ORIGIN, which must be + on the same local disk. If ORIGIN is omitted, looks for "default-relink", + then "default", in [paths]. + + Do not attempt any read operations on this repository while the command is + running. (Both repositories will be locked against writes.) + """ + src = hg.repository( + cmdutil.remoteui(repo, opts), + ui.expandpath(origin or 'default-relink', origin or 'default')) + if not src.local(): + raise util.Abort('must specify local origin repository') + ui.status(_('relinking %s to %s\n') % (src.store.path, repo.store.path)) + locallock = repo.lock() + try: + remotelock = src.lock() + try: + candidates = collect(src.store.path, ui) + targets = prune(candidates, repo.store.path, ui) + do_relink(src.store.path, repo.store.path, targets, ui) + finally: + remotelock.release() + finally: + locallock.release() + +def collect(src, ui): + seplen = len(os.path.sep) + candidates = [] + for dirpath, dirnames, filenames in os.walk(src): + relpath = dirpath[len(src) + seplen:] + for filename in filenames: + if not filename[-2:] in ('.d', '.i'): + continue + st = os.stat(os.path.join(dirpath, filename)) + if not stat.S_ISREG(st.st_mode): + continue + candidates.append((os.path.join(relpath, filename), st)) + + ui.status(_('collected %d candidate storage files\n') % len(candidates)) + return candidates + +def prune(candidates, dst, ui): + def linkfilter(dst, st): + try: + ts = os.stat(dst) + except OSError: + # Destination doesn't have this file? + return False + if st.st_ino == ts.st_ino: + return False + if st.st_dev != ts.st_dev: + # No point in continuing + raise util.Abort( + _('source and destination are on different devices')) + if st.st_size != ts.st_size: + return False + return st + + targets = [] + for fn, st in candidates: + tgt = os.path.join(dst, fn) + ts = linkfilter(tgt, st) + if not ts: + ui.debug(_('not linkable: %s\n') % fn) + continue + targets.append((fn, ts.st_size)) + + ui.status(_('pruned down to %d probably relinkable files\n') % len(targets)) + return targets + +def do_relink(src, dst, files, ui): + def relinkfile(src, dst): + bak = dst + '.bak' + os.rename(dst, bak) + try: + os.link(src, dst) + except OSError: + os.rename(bak, dst) + raise + os.remove(bak) + + CHUNKLEN = 65536 + relinked = 0 + savedbytes = 0 + + pos = 0 + total = len(files) + for f, sz in files: + pos += 1 + source = os.path.join(src, f) + tgt = os.path.join(dst, f) + sfp = file(source) + dfp = file(tgt) + sin = sfp.read(CHUNKLEN) + while sin: + din = dfp.read(CHUNKLEN) + if sin != din: + break + sin = sfp.read(CHUNKLEN) + if sin: + ui.debug(_('not linkable: %s\n') % f) + continue + try: + relinkfile(source, tgt) + ui.progress(_('relink'), pos, f, _(' files'), total) + relinked += 1 + savedbytes += sz + except OSError, inst: + ui.warn(_('%s: %s\n') % (tgt, str(inst))) + + ui.status(_('relinked %d files (%d bytes reclaimed)\n') % + (relinked, savedbytes)) + +cmdtable = { + 'relink': ( + relink, + [], + _('[ORIGIN]') + ) +}
--- a/mercurial/bundlerepo.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/bundlerepo.py Sat Nov 07 14:13:15 2009 -0600 @@ -74,12 +74,12 @@ return False return rev in self.basemap def bundlebase(self, rev): return self.basemap[rev] - def chunk(self, rev, df=None, cachelen=4096): + def _chunk(self, rev): # Warning: in case of bundle, the diff is against bundlebase, # not against rev - 1 # XXX: could use some caching if not self.bundle(rev): - return revlog.revlog.chunk(self, rev, df) + return revlog.revlog._chunk(self, rev) self.bundlefile.seek(self.start(rev)) return self.bundlefile.read(self.length(rev)) @@ -89,7 +89,7 @@ # hot path for bundle revb = self.rev(self.bundlebase(rev2)) if revb == rev1: - return self.chunk(rev2) + return self._chunk(rev2) elif not self.bundle(rev1) and not self.bundle(rev2): return revlog.revlog.revdiff(self, rev1, rev2) @@ -116,7 +116,7 @@ text = revlog.revlog.revision(self, iter_node) while chain: - delta = self.chunk(chain.pop()) + delta = self._chunk(chain.pop()) text = mdiff.patches(text, [delta]) p1, p2 = self.parents(node)
--- a/mercurial/byterange.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/byterange.py Sat Nov 07 14:13:15 2009 -0600 @@ -261,6 +261,8 @@ host, port = splitport(host) if port is None: port = ftplib.FTP_PORT + else: + port = int(port) # username/password handling user, host = splituser(host)
--- a/mercurial/changelog.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/changelog.py Sat Nov 07 14:13:15 2009 -0600 @@ -198,7 +198,7 @@ return (manifest, user, (time, timezone), files, desc, extra) def add(self, manifest, files, desc, transaction, p1, p2, - user, date=None, extra={}): + user, date=None, extra=None): user = user.strip() # An empty username or a username with a "\n" will make the # revision text contain two "\n\n" sequences -> corrupt
--- a/mercurial/cmdutil.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/cmdutil.py Sat Nov 07 14:13:15 2009 -0600 @@ -1022,24 +1022,26 @@ def finddate(ui, repo, date): """Find the tipmost changeset that matches the given date spec""" + df = util.matchdate(date) - get = util.cachefunc(lambda r: repo[r]) m = matchall(repo) results = {} - for st, rev, fns in walkchangerevs(ui, repo, m, get, {'rev':None}): - if st == 'add': - d = get(rev).date() - if df(d[0]): - results[rev] = d - elif st == 'iter': - if rev in results: - ui.status(_("Found revision %s from %s\n") % - (rev, util.datestr(results[rev]))) - return str(rev) + + def prep(ctx, fns): + d = ctx.date() + if df(d[0]): + results[ctx.rev()] = d + + for ctx in walkchangerevs(repo, m, {'rev': None}, prep): + rev = ctx.rev() + if rev in results: + ui.status(_("Found revision %s from %s\n") % + (rev, util.datestr(results[rev]))) + return str(rev) raise util.Abort(_("revision matching date not found")) -def walkchangerevs(ui, repo, match, opts): +def walkchangerevs(repo, match, opts, prepare): '''Iterate over files and the revs in which they changed. Callers most commonly need to iterate backwards over the history @@ -1050,15 +1052,9 @@ window, we first walk forwards to gather data, then in the desired order (usually backwards) to display it. - This function returns an iterator. The iterator yields 3-tuples. - They will be of one of the following forms: - - "add", rev, fns: out-of-order traversal of the given filenames - fns, which changed during revision rev - use to gather data for - possible display - - "iter", rev, None: in-order traversal of the revs earlier iterated - over with "add" - use to display data''' + This function returns an iterator yielding contexts. Before + yielding each context, the iterator will first call the prepare + function on each context in the window in forward order.''' def increasing_windows(start, end, windowsize=8, sizelimit=512): if start < end: @@ -1093,6 +1089,7 @@ # No files, no patterns. Display all revs. wanted = set(revs) copies = [] + if not slowpath: # Only files, no patterns. Check the history of each file. def filerevgen(filelog, node): @@ -1129,8 +1126,6 @@ slowpath = True break else: - ui.warn(_('%s:%s copy source revision cannot be found!\n') - % (file_, short(node))) continue for rev, copied in filerevgen(filelog, node): if rev <= maxrev: @@ -1215,6 +1210,7 @@ return rev in wanted for i, window in increasing_windows(0, len(revs)): + change = util.cachefunc(repo.changectx) nrevs = [rev for rev in revs[i:i+window] if want(rev)] for rev in sorted(nrevs): fns = fncache.get(rev) @@ -1225,9 +1221,9 @@ if match(f): yield f fns = fns_generator() - yield 'add', ctx, fns + prepare(ctx, fns) for rev in nrevs: - yield 'iter', change(rev), None + yield change(rev) return iterate() def commit(ui, repo, commitfunc, pats, opts):
--- a/mercurial/commands.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/commands.py Sat Nov 07 14:13:15 2009 -0600 @@ -8,8 +8,8 @@ from node import hex, nullid, nullrev, short from lock import release from i18n import _, gettext -import os, re, sys, subprocess, difflib, time, tempfile -import hg, util, revlog, bundlerepo, extensions, copies, context, error +import os, re, sys, difflib, time, tempfile +import hg, util, revlog, bundlerepo, extensions, copies, error import patch, help, mdiff, url, encoding import archival, changegroup, cmdutil, sshserver, hbisect from hgweb import server @@ -31,7 +31,6 @@ """ bad = [] - exacts = {} names = [] m = cmdutil.match(repo, pats, opts) oldbad = m.bad @@ -371,14 +370,14 @@ # update state node = repo.lookup(rev or '.') - if good: - state['good'].append(node) - elif bad: - state['bad'].append(node) - elif skip: - state['skip'].append(node) - - hbisect.save_state(repo, state) + if good or bad or skip: + if good: + state['good'].append(node) + elif bad: + state['bad'].append(node) + elif skip: + state['skip'].append(node) + hbisect.save_state(repo, state) if not check_state(state): return @@ -450,8 +449,7 @@ """ hexfunc = ui.debugflag and hex or short - activebranches = [encoding.tolocal(repo[n].branch()) - for n in repo.heads()] + activebranches = [repo[n].branch() for n in repo.heads()] def testactive(tag, node): realhead = tag in activebranches open = node in repo.branchheads(tag, closed=False) @@ -462,8 +460,9 @@ for isactive, node, tag in branches: if (not active) or isactive: + encodedtag = encoding.tolocal(tag) if ui.quiet: - ui.write("%s\n" % tag) + ui.write("%s\n" % encodedtag) else: hn = repo.lookup(node) if isactive: @@ -474,8 +473,8 @@ notice = ' (closed)' else: notice = ' (inactive)' - rev = str(node).rjust(31 - encoding.colwidth(tag)) - data = tag, rev, hexfunc(hn), notice + rev = str(node).rjust(31 - encoding.colwidth(encodedtag)) + data = encodedtag, rev, hexfunc(hn), notice ui.write("%s %s:%s%s\n" % data) def bundle(ui, repo, fname, dest=None, **opts): @@ -591,22 +590,36 @@ The location of the source is added to the new repository's .hg/hgrc file, as the default to be used for future pulls. - If you use the -r/--rev option to clone up to a specific revision, - no subsequent revisions (including subsequent tags) will be - present in the cloned repository. This option implies --pull, even - on local repositories. - - By default, clone will check out the head of the 'default' branch. - If the -U/--noupdate option is used, the new clone will contain - only a repository (.hg) and no working copy (the working copy - parent is the null revision). - See 'hg help urls' for valid source format details. It is possible to specify an ssh:// URL as the destination, but no .hg/hgrc and working directory will be created on the remote side. Please see 'hg help urls' for important details about ssh:// URLs. + If the -U/--noupdate option is specified, the new clone will contain + only a repository (.hg) and no working copy (the working copy parent + will be the null changeset). Otherwise, clone will initially check + out (in order of precedence): + + a) the changeset, tag or branch specified with -u/--updaterev + b) the changeset, tag or branch given with the first -r/--rev + c) the head of the default branch + + Use 'hg clone -u . src dst' to checkout the source repository's + parent changeset (applicable for local source repositories only). + + A set of changesets (tags, or branch names) to pull may be specified + by listing each changeset (tag, or branch name) with -r/--rev. + If -r/--rev is used, the cloned repository will contain only a subset + of the changesets of the source repository. Only the set of changesets + defined by all -r/--rev options (including their direct and indirect + parent changesets) will be pulled into the destination repository. + No subsequent changesets (including subsequent tags) will be present + in the destination. + + Using -r/--rev (or 'clone src#rev dest') implies --pull, even for + local source repositories. + For efficiency, hardlinks are used for cloning whenever the source and destination are on the same filesystem (note this applies only to the repository data, not to the checked out files). Some @@ -626,11 +639,14 @@ this is not compatible with certain extensions that place their metadata under the .hg directory, such as mq. """ + if opts.get('noupdate') and opts.get('updaterev'): + raise util.Abort(_("cannot specify both --noupdate and --updaterev")) + hg.clone(cmdutil.remoteui(ui, opts), source, dest, pull=opts.get('pull'), stream=opts.get('uncompressed'), rev=opts.get('rev'), - update=not opts.get('noupdate')) + update=opts.get('updaterev') or not opts.get('noupdate')) def commit(ui, repo, *pats, **opts): """commit the specified files or all outstanding changes @@ -1013,15 +1029,12 @@ # check username ui.status(_("Checking username...\n")) - user = os.environ.get("HGUSER") - if user is None: - user = ui.config("ui", "username") - if user is None: - user = os.environ.get("EMAIL") - if not user: - ui.warn(" ") - ui.username() + try: + user = ui.username() + except util.Abort, e: + ui.write(" %s\n" % e) ui.write(_(" (specify a username in your .hgrc file)\n")) + problems += 1 if not problems: ui.status(_("No problems detected\n")) @@ -1086,6 +1099,7 @@ revs = opts.get('rev') change = opts.get('change') stat = opts.get('stat') + inv = opts.get('inverse') if revs and change: msg = _('cannot specify --rev and --change at the same time') @@ -1096,6 +1110,9 @@ else: node1, node2 = cmdutil.revpair(repo, revs) + if inv: + node1, node2 = node2, node1 + if stat: opts['unified'] = '0' diffopts = patch.diffopts(ui, opts) @@ -1302,61 +1319,62 @@ matchfn = cmdutil.match(repo, pats, opts) found = False follow = opts.get('follow') - for st, ctx, fns in cmdutil.walkchangerevs(ui, repo, matchfn, opts): - if st == 'add': - rev = ctx.rev() - pctx = ctx.parents()[0] - parent = pctx.rev() - matches.setdefault(rev, {}) - matches.setdefault(parent, {}) - files = revfiles.setdefault(rev, []) - for fn in fns: - flog = getfile(fn) + + def prep(ctx, fns): + rev = ctx.rev() + pctx = ctx.parents()[0] + parent = pctx.rev() + matches.setdefault(rev, {}) + matches.setdefault(parent, {}) + files = revfiles.setdefault(rev, []) + for fn in fns: + flog = getfile(fn) + try: + fnode = ctx.filenode(fn) + except error.LookupError: + continue + + copied = flog.renamed(fnode) + copy = follow and copied and copied[0] + if copy: + copies.setdefault(rev, {})[fn] = copy + if fn in skip: + if copy: + skip[copy] = True + continue + files.append(fn) + + if fn not in matches[rev]: + grepbody(fn, rev, flog.read(fnode)) + + pfn = copy or fn + if pfn not in matches[parent]: try: - fnode = ctx.filenode(fn) + fnode = pctx.filenode(pfn) + grepbody(pfn, parent, flog.read(fnode)) except error.LookupError: - continue - - copied = flog.renamed(fnode) - copy = follow and copied and copied[0] + pass + + for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep): + rev = ctx.rev() + parent = ctx.parents()[0].rev() + for fn in sorted(revfiles.get(rev, [])): + states = matches[rev][fn] + copy = copies.get(rev, {}).get(fn) + if fn in skip: if copy: - copies.setdefault(rev, {})[fn] = copy - if fn in skip: + skip[copy] = True + continue + pstates = matches.get(parent, {}).get(copy or fn, []) + if pstates or states: + r = display(fn, ctx, pstates, states) + found = found or r + if r and not opts.get('all'): + skip[fn] = True if copy: skip[copy] = True - continue - files.append(fn) - - if fn not in matches[rev]: - grepbody(fn, rev, flog.read(fnode)) - - pfn = copy or fn - if pfn not in matches[parent]: - try: - fnode = pctx.filenode(pfn) - grepbody(pfn, parent, flog.read(fnode)) - except error.LookupError: - pass - elif st == 'iter': - rev = ctx.rev() - parent = ctx.parents()[0].rev() - for fn in sorted(revfiles.get(rev, [])): - states = matches[rev][fn] - copy = copies.get(rev, {}).get(fn) - if fn in skip: - if copy: - skip[copy] = True - continue - pstates = matches.get(parent, {}).get(copy or fn, []) - if pstates or states: - r = display(fn, ctx, pstates, states) - found = found or r - if r and not opts.get('all'): - skip[fn] = True - if copy: - skip[copy] = True - del matches[rev] - del revfiles[rev] + del matches[rev] + del revfiles[rev] def heads(ui, repo, *branchrevs, **opts): """show current repository heads or show branch heads @@ -1400,21 +1418,22 @@ heads = [] visitedset = set() for branchrev in branchrevs: - branch = repo[branchrev].branch() + branch = repo[encoding.fromlocal(branchrev)].branch() + encodedbranch = encoding.tolocal(branch) if branch in visitedset: continue visitedset.add(branch) bheads = repo.branchheads(branch, start, closed=closed) if not bheads: if not opts.get('rev'): - ui.warn(_("no open branch heads on branch %s\n") % branch) + ui.warn(_("no open branch heads on branch %s\n") % encodedbranch) elif branch != branchrev: ui.warn(_("no changes on branch %s containing %s are " "reachable from %s\n") - % (branch, branchrev, opts.get('rev'))) + % (encodedbranch, branchrev, opts.get('rev'))) else: ui.warn(_("no changes on branch %s are reachable from %s\n") - % (branch, opts.get('rev'))) + % (encodedbranch, opts.get('rev'))) if hideinactive: bheads = [bhead for bhead in bheads if bhead in _heads] heads.extend(bheads) @@ -2034,54 +2053,44 @@ if opts["date"]: df = util.matchdate(opts["date"]) - only_branches = opts.get('only_branch') - displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn) - for st, ctx, fns in cmdutil.walkchangerevs(ui, repo, matchfn, opts): + def prep(ctx, fns): rev = ctx.rev() - if st == 'add': - parents = [p for p in repo.changelog.parentrevs(rev) - if p != nullrev] - if opts.get('no_merges') and len(parents) == 2: - continue - if opts.get('only_merges') and len(parents) != 2: - continue - - if only_branches and ctx.branch() not in only_branches: - continue - - if df and not df(ctx.date()[0]): - continue - - if opts.get('keyword'): - miss = 0 - for k in [kw.lower() for kw in opts['keyword']]: - if not (k in ctx.user().lower() or - k in ctx.description().lower() or - k in " ".join(ctx.files()).lower()): - miss = 1 - break - if miss: - continue - - if opts['user']: - if not [k for k in opts['user'] if k in ctx.user()]: - continue - - copies = [] - if opts.get('copies') and rev: - for fn in ctx.files(): - rename = getrenamed(fn, rev) - if rename: - copies.append((fn, rename[0])) - - displayer.show(ctx, copies=copies) - - elif st == 'iter': - if count == limit: break - - if displayer.flush(rev): - count += 1 + parents = [p for p in repo.changelog.parentrevs(rev) + if p != nullrev] + if opts.get('no_merges') and len(parents) == 2: + return + if opts.get('only_merges') and len(parents) != 2: + return + if opts.get('only_branch') and ctx.branch() not in opts['only_branch']: + return + if df and not df(ctx.date()[0]): + return + if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]: + return + if opts.get('keyword'): + for k in [kw.lower() for kw in opts['keyword']]: + if (k in ctx.user().lower() or + k in ctx.description().lower() or + k in " ".join(ctx.files()).lower()): + break + else: + return + + copies = [] + if opts.get('copies') and rev: + for fn in ctx.files(): + rename = getrenamed(fn, rev) + if rename: + copies.append((fn, rename[0])) + + displayer.show(ctx, copies=copies) + + for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep): + if count == limit: + break + if displayer.flush(ctx.rev()): + count += 1 def manifest(ui, repo, node=None, rev=None): """output the current or given revision of the project manifest @@ -2446,13 +2455,15 @@ """retry file merges from a merge or update This command can cleanly retry unresolved file merges using file - revisions preserved from the last update or merge. To attempt to - resolve all unresolved files, use the -a/--all switch. + revisions preserved from the last update or merge. If a conflict is resolved manually, please note that the changes will be overwritten if the merge is retried with resolve. The -m/--mark switch should be used to mark the file as resolved. + You can specify a set of files to operate on, or use the -a/-all + switch to select all unresolved files. + This command also allows listing resolved files and manually indicating whether or not files are resolved. All files must be marked as resolved before a commit is permitted. @@ -3129,30 +3140,32 @@ """update working directory Update the repository's working directory to the specified - revision, or the tip of the current branch if none is specified. - Use null as the revision to remove the working copy (like 'hg + changeset. + + If no changeset is specified, attempt to update to the head of the + current branch. If this head is a descendant of the working + directory's parent, update to it, otherwise abort. + + The following rules apply when the working directory contains + uncommitted changes: + + 1. If neither -c/--check nor -C/--clean is specified, uncommitted + changes are merged into the requested changeset, and the merged result + is left uncommitted. Updating and merging will occur only if the + requested changeset is an ancestor or descendant of the parent + changeset. Otherwise, the update is aborted and the uncommitted changes + are preserved. + + 2. With the -c/--check option, the update is aborted and the + uncommitted changes are preserved. + + 3. With the -C/--clean option, uncommitted changes are discarded and + the working directory is updated to the requested changeset. + + Use null as the changeset to remove the working directory (like 'hg clone -U'). - When the working directory contains no uncommitted changes, it - will be replaced by the state of the requested revision from the - repository. When the requested revision is on a different branch, - the working directory will additionally be switched to that - branch. - - When there are uncommitted changes, use option -C/--clean to - discard them, forcibly replacing the state of the working - directory with the requested revision. Alternately, use -c/--check - to abort. - - When there are uncommitted changes and option -C/--clean is not - used, and the parent revision and requested revision are on the - same branch, and one of them is an ancestor of the other, then the - new working directory will contain the requested revision merged - with the uncommitted changes. Otherwise, the update will fail with - a suggestion to use 'merge' or 'update -C' instead. - - If you want to update just one file to an older revision, use - revert. + If you want to update just one file to an older changeset, use 'hg revert'. See 'hg help dates' for a list of formats valid for -d/--date. """ @@ -3220,7 +3233,7 @@ ('', 'encoding', encoding.encoding, _('set the charset encoding')), ('', 'encodingmode', encoding.encodingmode, _('set the charset encoding mode')), - ('', 'traceback', None, _('print traceback on exception')), + ('', 'traceback', None, _('always print a traceback on exception')), ('', 'time', None, _('time how long the command takes')), ('', 'profile', None, _('print command execution profile')), ('', 'version', None, _('output version information and exit')), @@ -3270,6 +3283,7 @@ diffopts2 = [ ('p', 'show-function', None, _('show which function each change is in')), + ('', 'inverse', None, _('produce a diff that undoes the changes')), ('w', 'ignore-all-space', None, _('ignore white space when comparing lines')), ('b', 'ignore-space-change', None, @@ -3364,6 +3378,8 @@ (clone, [('U', 'noupdate', None, _('the clone will only contain a repository (no working copy)')), + ('u', 'updaterev', '', + _('revision, tag or branch to check out')), ('r', 'rev', [], _('a changeset you would like to have after cloning')), ('', 'pull', None, _('use pull protocol to copy metadata')), @@ -3587,7 +3603,7 @@ _('[OPTION]... SOURCE... DEST')), "resolve": (resolve, - [('a', 'all', None, _('remerge all unresolved files')), + [('a', 'all', None, _('select all unresolved files')), ('l', 'list', None, _('list state of files needing merge')), ('m', 'mark', None, _('mark files as resolved')), ('u', 'unmark', None, _('unmark files as resolved')), @@ -3672,11 +3688,11 @@ _('[-u] FILE...')), "^update|up|checkout|co": (update, - [('C', 'clean', None, _('overwrite locally modified files (no backup)')), + [('C', 'clean', None, _('discard uncommitted changes (no backup)')), ('c', 'check', None, _('check for uncommitted changes')), ('d', 'date', '', _('tipmost revision matching date')), ('r', 'rev', '', _('revision'))], - _('[-C] [-d DATE] [[-r] REV]')), + _('[-c] [-C] [-d DATE] [[-r] REV]')), "verify": (verify, []), "version": (version_, []), }
--- a/mercurial/context.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/context.py Sat Nov 07 14:13:15 2009 -0600 @@ -451,6 +451,15 @@ find the common ancestor file context, if any, of self, and fc2 """ + actx = self.changectx().ancestor(fc2.changectx()) + + # the trivial case: changesets are unrelated, files must be too + if not actx: + return None + + # the easy case: no (relevant) renames + if fc2.path() == self.path() and self.path() in actx: + return actx[self.path()] acache = {} # prime the ancestor cache for the working directory
--- a/mercurial/dirstate.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/dirstate.py Sat Nov 07 14:13:15 2009 -0600 @@ -9,7 +9,7 @@ from i18n import _ import util, ignore, osutil, parsers import struct, os, stat, errno -import cStringIO, sys +import cStringIO _unknown = ('?', 0, 0, 0) _format = ">cllll"
--- a/mercurial/dispatch.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/dispatch.py Sat Nov 07 14:13:15 2009 -0600 @@ -194,8 +194,6 @@ args = shlex.split(self.definition) cmd = args.pop(0) - opts = [] - help = '' try: self.fn, self.opts, self.help = cmdutil.findcmd(cmd, cmdtable, False)[1] @@ -358,17 +356,7 @@ extensions.loadall(lui) exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded] - # (uisetup is handled in extensions.loadall) - - for name, module in exts: - extsetup = getattr(module, 'extsetup', None) - if extsetup: - try: - extsetup(ui) - except TypeError: - if extsetup.func_code.co_argcount != 0: - raise - extsetup() # old extsetup with no ui argument + # (uisetup and extsetup are handled in extensions.loadall) for name, module in exts: cmdtable = getattr(module, 'cmdtable', {})
--- a/mercurial/extensions.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/extensions.py Sat Nov 07 14:13:15 2009 -0600 @@ -93,6 +93,16 @@ if uisetup: uisetup(ui) + for name in _order[newindex:]: + extsetup = getattr(_extensions[name], 'extsetup', None) + if extsetup: + try: + extsetup(ui) + except TypeError: + if extsetup.func_code.co_argcount != 0: + raise + extsetup() # old extsetup with no ui argument + def wrapcommand(table, command, wrapper): aliases, entry = cmdutil.findcmd(command, table) for alias, e in table.iteritems(): @@ -171,7 +181,6 @@ '''return a dict of {name: desc} of extensions, and the max name length''' exts = {} maxlength = 0 - exthelps = [] for ename, ext in extensions(): doc = (gettext(ext.__doc__) or _('(no help text available)')) ename = ename.split('.')[-1]
--- a/mercurial/filemerge.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/filemerge.py Sat Nov 07 14:13:15 2009 -0600 @@ -186,6 +186,7 @@ env = dict(HG_FILE=fd, HG_MY_NODE=short(mynode), HG_OTHER_NODE=str(fco.changectx()), + HG_BASE_NODE=str(fca.changectx()), HG_MY_ISLINK='l' in fcd.flags(), HG_OTHER_ISLINK='l' in fco.flags(), HG_BASE_ISLINK='l' in fca.flags())
--- a/mercurial/graphmod.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/graphmod.py Sat Nov 07 14:13:15 2009 -0600 @@ -48,7 +48,7 @@ parents = [f.linkrev() for f in fctx.parents() if f.path() == path] rev = fctx.rev() if rev <= start: - yield (rev, CHANGESET, fctx, sorted(parents)) + yield (rev, CHANGESET, fctx.changectx(), sorted(parents)) if rev <= stop: break filerev -= 1
--- a/mercurial/help.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/help.py Sat Nov 07 14:13:15 2009 -0600 @@ -7,7 +7,7 @@ from i18n import gettext, _ import sys, os -import extensions, util +import extensions def moduledoc(file):
--- a/mercurial/hg.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/hg.py Sat Nov 07 14:13:15 2009 -0600 @@ -309,6 +309,8 @@ if update: if update is not True: checkout = update + if src_repo.local(): + checkout = src_repo.lookup(update) for test in (checkout, 'default', 'tip'): if test is None: continue
--- a/mercurial/hgweb/common.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/hgweb/common.py Sat Nov 07 14:13:15 2009 -0600 @@ -31,8 +31,8 @@ responses = BaseHTTPRequestHandler.responses return responses.get(code, ('Error', 'Unknown error'))[0] -def statusmessage(code): - return '%d %s' % (code, _statusmessage(code)) +def statusmessage(code, message=None): + return '%d %s' % (code, message or _statusmessage(code)) def get_mtime(repo_path): store_path = os.path.join(repo_path, ".hg")
--- a/mercurial/hgweb/hgweb_mod.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/hgweb/hgweb_mod.py Sat Nov 07 14:13:15 2009 -0600 @@ -151,6 +151,10 @@ if args: req.form['file'] = args + ua = req.env.get('HTTP_USER_AGENT', '') + if cmd == 'rev' and 'mercurial' in ua: + req.form['style'] = ['raw'] + if cmd == 'archive': fn = req.form['node'][0] for type_, spec in self.archive_specs.iteritems():
--- a/mercurial/hgweb/hgwebdir_mod.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/hgweb/hgwebdir_mod.py Sat Nov 07 14:13:15 2009 -0600 @@ -20,7 +20,7 @@ return [(util.pconvert(name).strip('/'), path) for name, path in items] def findrepos(paths): - repos = {} + repos = [] for prefix, root in cleannames(paths): roothead, roottail = os.path.split(root) # "foo = /bar/*" makes every subrepo of /bar/ to be @@ -30,7 +30,7 @@ try: recurse = {'*': False, '**': True}[roottail] except KeyError: - repos[prefix] = root + repos.append((prefix, root)) continue roothead = os.path.normpath(roothead) for path in util.walkrepos(roothead, followsym=True, recurse=recurse): @@ -38,8 +38,8 @@ name = util.pconvert(path[len(roothead):]).strip('/') if prefix: name = prefix + '/' + name - repos[name] = path - return repos.items() + repos.append((name, path)) + return repos class hgwebdir(object): refreshinterval = 20 @@ -89,7 +89,6 @@ name = name[len(prefix):] self.repos.append((name.lstrip('/'), repo)) - self.repos.sort() self.lastrefresh = time.time() def run(self): @@ -196,7 +195,7 @@ yield {"type" : i[0], "extension": i[1], "node": nodeid, "url": url} - sortdefault = 'name', False + sortdefault = None, False def entries(sortcolumn="", descending=False, subdir="", **map): rows = []
--- a/mercurial/hgweb/protocol.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/hgweb/protocol.py Sat Nov 07 14:13:15 2009 -0600 @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2, incorporated herein by reference. -import cStringIO, zlib, tempfile, errno, os, sys, urllib +import cStringIO, zlib, tempfile, errno, os, sys, urllib, copy from mercurial import util, streamclone from mercurial.node import bin, hex from mercurial import changegroup as changegroupmod @@ -21,6 +21,7 @@ ] HGTYPE = 'application/mercurial-0.1' +basecaps = 'lookup changegroupsubset branchmap'.split() def lookup(repo, req): try: @@ -109,7 +110,7 @@ yield z.flush() def capabilities(repo, req): - caps = ['lookup', 'changegroupsubset', 'branchmap'] + caps = copy.copy(basecaps) if repo.ui.configbool('server', 'uncompressed', untrusted=True): caps.append('stream=%d' % repo.changelog.version) if changegroupmod.bundlepriority: @@ -181,18 +182,19 @@ except ValueError, inst: raise ErrorResponse(HTTP_OK, inst) except (OSError, IOError), inst: - filename = getattr(inst, 'filename', '') - # Don't send our filesystem layout to the client - if filename.startswith(repo.root): - filename = filename[len(repo.root)+1:] - else: - filename = '' error = getattr(inst, 'strerror', 'Unknown error') if inst.errno == errno.ENOENT: code = HTTP_NOT_FOUND else: code = HTTP_SERVER_ERROR - raise ErrorResponse(code, '%s: %s' % (error, filename)) + filename = getattr(inst, 'filename', '') + # Don't send our filesystem layout to the client + if filename and filename.startswith(repo.root): + filename = filename[len(repo.root)+1:] + text = '%s: %s' % (error, filename) + else: + text = error.replace(repo.root + os.path.sep, '') + raise ErrorResponse(code, text) finally: fp.close() os.unlink(tempname)
--- a/mercurial/hgweb/request.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/hgweb/request.py Sat Nov 07 14:13:15 2009 -0600 @@ -77,7 +77,7 @@ if isinstance(status, ErrorResponse): self.header(status.headers) - status = statusmessage(status.code) + status = statusmessage(status.code, status.message) elif status == 200: status = '200 Script output follows' elif isinstance(status, int):
--- a/mercurial/hook.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/hook.py Sat Nov 07 14:13:15 2009 -0600 @@ -106,10 +106,14 @@ def hook(ui, repo, name, throw=False, **args): r = False + oldstdout = -1 if _redirect: - # temporarily redirect stdout to stderr - oldstdout = os.dup(sys.__stdout__.fileno()) - os.dup2(sys.__stderr__.fileno(), sys.__stdout__.fileno()) + stdoutno = sys.__stdout__.fileno() + stderrno = sys.__stderr__.fileno() + # temporarily redirect stdout to stderr, if possible + if stdoutno >= 0 and stderrno >= 0: + oldstdout = os.dup(stdoutno) + os.dup2(stderrno, stdoutno) try: for hname, cmd in ui.configitems('hooks'): @@ -128,8 +132,8 @@ else: r = _exthook(ui, repo, hname, cmd, args, throw) or r finally: - if _redirect: - os.dup2(oldstdout, sys.__stdout__.fileno()) + if _redirect and oldstdout >= 0: + os.dup2(oldstdout, stdoutno) os.close(oldstdout) return r
--- a/mercurial/httprepo.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/httprepo.py Sat Nov 07 14:13:15 2009 -0600 @@ -106,8 +106,9 @@ proto.startswith('text/plain') or proto.startswith('application/hg-changegroup')): self.ui.debug("requested URL: '%s'\n" % url.hidepassword(cu)) - raise error.RepoError(_("'%s' does not appear to be an hg repository") - % safeurl) + raise error.RepoError(_("'%s' does not appear to be an hg repository:\n" + "---%%<--- (%s)\n%s\n---%%<---\n") + % (safeurl, proto, resp.read())) if proto.startswith('application/mercurial-'): try:
--- a/mercurial/keepalive.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/keepalive.py Sat Nov 07 14:13:15 2009 -0600 @@ -23,6 +23,9 @@ # - import md5 function from a local util module # Modified by Martin Geisler: # - moved md5 function from local util module to this module +# Modified by Augie Fackler: +# - add safesend method and use it to prevent broken pipe errors +# on large POST requests """An HTTP handler for urllib2 that supports HTTP 1.1 and keepalive. @@ -108,10 +111,11 @@ # $Id: keepalive.py,v 1.14 2006/04/04 21:00:32 mstenner Exp $ -import urllib2 +import errno import httplib import socket import thread +import urllib2 DEBUG = None @@ -495,10 +499,76 @@ break return list +def safesend(self, str): + """Send `str' to the server. + + Shamelessly ripped off from httplib to patch a bad behavior. + """ + # _broken_pipe_resp is an attribute we set in this function + # if the socket is closed while we're sending data but + # the server sent us a response before hanging up. + # In that case, we want to pretend to send the rest of the + # outgoing data, and then let the user use getresponse() + # (which we wrap) to get this last response before + # opening a new socket. + if getattr(self, '_broken_pipe_resp', None) is not None: + return + + if self.sock is None: + if self.auto_open: + self.connect() + else: + raise httplib.NotConnected() + + # send the data to the server. if we get a broken pipe, then close + # the socket. we want to reconnect when somebody tries to send again. + # + # NOTE: we DO propagate the error, though, because we cannot simply + # ignore the error... the caller will know if they can retry. + if self.debuglevel > 0: + print "send:", repr(str) + try: + blocksize=8192 + if hasattr(str,'read') : + if self.debuglevel > 0: print "sendIng a read()able" + data=str.read(blocksize) + while data: + self.sock.sendall(data) + data=str.read(blocksize) + else: + self.sock.sendall(str) + except socket.error, v: + reraise = True + if v[0] == errno.EPIPE: # Broken pipe + if self._HTTPConnection__state == httplib._CS_REQ_SENT: + self._broken_pipe_resp = None + self._broken_pipe_resp = self.getresponse() + reraise = False + self.close() + if reraise: + raise + +def wrapgetresponse(cls): + """Wraps getresponse in cls with a broken-pipe sane version. + """ + def safegetresponse(self): + # In safesend() we might set the _broken_pipe_resp + # attribute, in which case the socket has already + # been closed and we just need to give them the response + # back. Otherwise, we use the normal response path. + r = getattr(self, '_broken_pipe_resp', None) + if r is not None: + return r + return cls.getresponse(self) + safegetresponse.__doc__ = cls.getresponse.__doc__ + return safegetresponse class HTTPConnection(httplib.HTTPConnection): # use the modified response class response_class = HTTPResponse + send = safesend + getresponse = wrapgetresponse(httplib.HTTPConnection) + ######################################################################### ##### TEST FUNCTIONS
--- a/mercurial/localrepo.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/localrepo.py Sat Nov 07 14:13:15 2009 -0600 @@ -98,8 +98,7 @@ self._tags = None self._tagtypes = None - self.branchcache = None - self._ubranchcache = None # UTF-8 version of branchcache + self._branchcache = None # in UTF-8 self._branchcachetip = None self.nodetagscache = None self.filterpats = {} @@ -321,31 +320,22 @@ def branchmap(self): tip = self.changelog.tip() - if self.branchcache is not None and self._branchcachetip == tip: - return self.branchcache + if self._branchcache is not None and self._branchcachetip == tip: + return self._branchcache oldtip = self._branchcachetip self._branchcachetip = tip - if self.branchcache is None: - self.branchcache = {} # avoid recursion in changectx - else: - self.branchcache.clear() # keep using the same dict if oldtip is None or oldtip not in self.changelog.nodemap: partial, last, lrev = self._readbranchcache() else: lrev = self.changelog.rev(oldtip) - partial = self._ubranchcache + partial = self._branchcache self._branchtags(partial, lrev) # this private cache holds all heads (not just tips) - self._ubranchcache = partial + self._branchcache = partial - # the branch cache is stored on disk as UTF-8, but in the local - # charset internally - for k, v in partial.iteritems(): - self.branchcache[encoding.tolocal(k)] = v - return self.branchcache - + return self._branchcache def branchtags(self): '''return a dict where branch names map to the tipmost head of @@ -566,7 +556,7 @@ # abort here if the journal already exists if os.path.exists(self.sjoin("journal")): - raise error.RepoError(_("journal already exists - run hg recover")) + raise error.RepoError(_("abandoned transaction found - run hg recover")) # save dirstate for rollback try: @@ -631,8 +621,7 @@ self._tags = None self._tagtypes = None self.nodetagscache = None - self.branchcache = None - self._ubranchcache = None + self._branchcache = None # in UTF-8 self._branchcachetip = None def _lock(self, lockname, wait, releasefn, acquirefn, desc): @@ -914,7 +903,7 @@ self.changelog.finalize(trp) tr.close() - if self.branchcache: + if self._branchcache: self.branchtags() self.hook("commit", node=hex(n), parent1=xp1, parent2=xp2)
--- a/mercurial/lock.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/lock.py Sat Nov 07 14:13:15 2009 -0600 @@ -105,7 +105,7 @@ return locker try: pid = int(pid) - except: + except ValueError: return locker if util.testpid(pid): return locker @@ -122,13 +122,14 @@ def release(self): if self.held > 1: self.held -= 1 - elif self.held is 1: + elif self.held == 1: self.held = 0 if self.releasefn: self.releasefn() try: os.unlink(self.f) - except: pass + except OSError: + pass def release(*locks): for lock in locks:
--- a/mercurial/mail.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/mail.py Sat Nov 07 14:13:15 2009 -0600 @@ -169,7 +169,7 @@ try: acc, dom = addr.split('@') acc = acc.encode('ascii') - dom = dom.encode('idna') + dom = dom.decode(encoding.encoding).encode('idna') addr = '%s@%s' % (acc, dom) except UnicodeDecodeError: raise util.Abort(_('invalid email address: %s') % addr)
--- a/mercurial/merge.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/merge.py Sat Nov 07 14:13:15 2009 -0600 @@ -397,11 +397,38 @@ """ Perform a merge between the working directory and the given node + node = the node to update to, or None if unspecified branchmerge = whether to merge between branches force = whether to force branch merging or file overwriting partial = a function to filter file lists (dirstate not updated) + + The table below shows all the behaviors of the update command + given the -c and -C or no options, whether the working directory + is dirty, whether a revision is specified, and the relationship of + the parent rev to the target rev (linear, on the same named + branch, or on another named branch). + + This logic is tested by test-update-branches. + + -c -C dirty rev | linear same cross + n n n n | ok (1) x + n n n y | ok ok ok + n n y * | merge (2) (2) + n y * * | --- discard --- + y n y * | --- (3) --- + y n n * | --- ok --- + y y * * | --- (4) --- + + x = can't happen + * = don't-care + 1 = abort: crosses branches (use 'hg merge' or 'hg update -c') + 2 = abort: crosses branches (use 'hg merge' to merge or + use 'hg update -C' to discard changes) + 3 = abort: uncommitted local changes + 4 = incompatible options (checked in commands.py) """ + onode = node wlock = repo.wlock() try: wc = repo[None] @@ -439,17 +466,14 @@ elif not overwrite: if pa == p1 or pa == p2: # linear pass # all good - elif p1.branch() == p2.branch(): - if wc.files() or wc.deleted(): - raise util.Abort(_("crosses branches (use 'hg merge' or " - "'hg update -C' to discard changes)")) - raise util.Abort(_("crosses branches (use 'hg merge' " - "or 'hg update -C')")) elif wc.files() or wc.deleted(): - raise util.Abort(_("crosses named branches (use " - "'hg update -C' to discard changes)")) + raise util.Abort(_("crosses branches (use 'hg merge' to merge " + "or use 'hg update -C' to discard changes)")) + elif onode is None: + raise util.Abort(_("crosses branches (use 'hg merge' or use " + "'hg update -c')")) else: - # Allow jumping branches if there are no changes + # Allow jumping branches if clean and specific rev given overwrite = True ### calculate phase
--- a/mercurial/minirst.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/minirst.py Sat Nov 07 14:13:15 2009 -0600 @@ -16,19 +16,23 @@ It only supports a small subset of reStructuredText: +- sections + - paragraphs -- definition lists (must use ' ' to indent definitions) +- literal blocks + +- definition lists -- lists (items must start with '-') +- bullet lists (items must start with '-') + +- enumerated lists (no autonumbering) - field lists (colons cannot be escaped) -- literal blocks - - option lists (supports only long options without arguments) -- inline markup is not recognized at all. +- inline literals (no other inline markup is not recognized) """ import re, sys, textwrap @@ -94,9 +98,10 @@ # correct for this here while we still have the original # information on the indentation of the subsequent literal # blocks available. - if blocks[i]['lines'][0].startswith('- '): - indent += 2 - adjustment -= 2 + m = _bulletre.match(blocks[i]['lines'][0]) + if m: + indent += m.end() + adjustment -= m.end() # Mark the following indented blocks. while i+1 < len(blocks) and blocks[i+1]['indent'] > indent: @@ -106,6 +111,53 @@ i += 1 return blocks +_bulletre = re.compile(r'(-|[0-9A-Za-z]+\.|\(?[0-9A-Za-z]+\)) ') +_optionre = re.compile(r'^(--[a-z-]+)((?:[ =][a-zA-Z][\w-]*)? +)(.*)$') +_fieldre = re.compile(r':(?![: ])([^:]*)(?<! ):( +)(.*)') +_definitionre = re.compile(r'[^ ]') + +def splitparagraphs(blocks): + """Split paragraphs into lists.""" + # Tuples with (list type, item regexp, single line items?). Order + # matters: definition lists has the least specific regexp and must + # come last. + listtypes = [('bullet', _bulletre, True), + ('option', _optionre, True), + ('field', _fieldre, True), + ('definition', _definitionre, False)] + + def match(lines, i, itemre, singleline): + """Does itemre match an item at line i? + + A list item can be followed by an idented line or another list + item (but only if singleline is True). + """ + line1 = lines[i] + line2 = i+1 < len(lines) and lines[i+1] or '' + if not itemre.match(line1): + return False + if singleline: + return line2 == '' or line2[0] == ' ' or itemre.match(line2) + else: + return line2.startswith(' ') + + i = 0 + while i < len(blocks): + if blocks[i]['type'] == 'paragraph': + lines = blocks[i]['lines'] + for type, itemre, singleline in listtypes: + if match(lines, 0, itemre, singleline): + items = [] + for j, line in enumerate(lines): + if match(lines, j, itemre, singleline): + items.append(dict(type=type, lines=[], + indent=blocks[i]['indent'])) + items[-1]['lines'].append(line) + blocks[i:i+1] = items + break + i += 1 + return blocks + def findsections(blocks): """Finds sections. @@ -127,139 +179,6 @@ return blocks -def findbulletlists(blocks): - """Finds bullet lists. - - The blocks must have a 'type' field, i.e., they should have been - run through findliteralblocks first. - """ - i = 0 - while i < len(blocks): - # Searching for a paragraph that looks like this: - # - # +------+-----------------------+ - # | "- " | list item | - # +------| (body elements)+ | - # +-----------------------+ - if (blocks[i]['type'] == 'paragraph' and - blocks[i]['lines'][0].startswith('- ')): - items = [] - for line in blocks[i]['lines']: - if line.startswith('- '): - items.append(dict(type='bullet', lines=[], - indent=blocks[i]['indent'])) - line = line[2:] - items[-1]['lines'].append(line) - blocks[i:i+1] = items - i += len(items) - 1 - i += 1 - return blocks - - -_optionre = re.compile(r'^(--[a-z-]+)((?:[ =][a-zA-Z][\w-]*)? +)(.*)$') -def findoptionlists(blocks): - """Finds option lists. - - The blocks must have a 'type' field, i.e., they should have been - run through findliteralblocks first. - """ - i = 0 - while i < len(blocks): - # Searching for a paragraph that looks like this: - # - # +----------------------------+-------------+ - # | "--" option " " | description | - # +-------+--------------------+ | - # | (body elements)+ | - # +----------------------------------+ - if (blocks[i]['type'] == 'paragraph' and - _optionre.match(blocks[i]['lines'][0])): - options = [] - for line in blocks[i]['lines']: - m = _optionre.match(line) - if m: - option, arg, rest = m.groups() - width = len(option) + len(arg) - options.append(dict(type='option', lines=[], - indent=blocks[i]['indent'], - width=width)) - options[-1]['lines'].append(line) - blocks[i:i+1] = options - i += len(options) - 1 - i += 1 - return blocks - - -_fieldre = re.compile(r':(?![: ])([^:]*)(?<! ):( +)(.*)') -def findfieldlists(blocks): - """Finds fields lists. - - The blocks must have a 'type' field, i.e., they should have been - run through findliteralblocks first. - """ - i = 0 - while i < len(blocks): - # Searching for a paragraph that looks like this: - # - # - # +--------------------+----------------------+ - # | ":" field name ":" | field body | - # +-------+------------+ | - # | (body elements)+ | - # +-----------------------------------+ - if (blocks[i]['type'] == 'paragraph' and - _fieldre.match(blocks[i]['lines'][0])): - indent = blocks[i]['indent'] - fields = [] - for line in blocks[i]['lines']: - m = _fieldre.match(line) - if m: - key, spaces, rest = m.groups() - width = 2 + len(key) + len(spaces) - fields.append(dict(type='field', lines=[], - indent=indent, width=width)) - # Turn ":foo: bar" into "foo bar". - line = '%s %s%s' % (key, spaces, rest) - fields[-1]['lines'].append(line) - blocks[i:i+1] = fields - i += len(fields) - 1 - i += 1 - return blocks - - -def finddefinitionlists(blocks): - """Finds definition lists. - - The blocks must have a 'type' field, i.e., they should have been - run through findliteralblocks first. - """ - i = 0 - while i < len(blocks): - # Searching for a paragraph that looks like this: - # - # +----------------------------+ - # | term | - # +--+-------------------------+--+ - # | definition | - # | (body elements)+ | - # +----------------------------+ - if (blocks[i]['type'] == 'paragraph' and - len(blocks[i]['lines']) > 1 and - not blocks[i]['lines'][0].startswith(' ') and - blocks[i]['lines'][1].startswith(' ')): - definitions = [] - for line in blocks[i]['lines']: - if not line.startswith(' '): - definitions.append(dict(type='definition', lines=[], - indent=blocks[i]['indent'])) - definitions[-1]['lines'].append(line) - definitions[-1]['hang'] = len(line) - len(line.lstrip()) - blocks[i:i+1] = definitions - i += len(definitions) - 1 - i += 1 - return blocks - - def inlineliterals(blocks): for b in blocks: if b['type'] == 'paragraph': @@ -291,30 +210,41 @@ indent = ' ' * block['indent'] if block['type'] == 'margin': return '' - elif block['type'] == 'literal': + if block['type'] == 'literal': indent += ' ' return indent + ('\n' + indent).join(block['lines']) - elif block['type'] == 'section': + if block['type'] == 'section': return indent + ('\n' + indent).join(block['lines']) - elif block['type'] == 'definition': + if block['type'] == 'definition': term = indent + block['lines'][0] - defindent = indent + block['hang'] * ' ' + hang = len(block['lines'][-1]) - len(block['lines'][-1].lstrip()) + defindent = indent + hang * ' ' text = ' '.join(map(str.strip, block['lines'][1:])) return "%s\n%s" % (term, textwrap.fill(text, width=width, initial_indent=defindent, subsequent_indent=defindent)) - else: - initindent = subindent = indent - text = ' '.join(map(str.strip, block['lines'])) - if block['type'] == 'bullet': - initindent = indent + '- ' - subindent = indent + ' ' - elif block['type'] in ('option', 'field'): - subindent = indent + block['width'] * ' ' + initindent = subindent = indent + if block['type'] == 'bullet': + m = _bulletre.match(block['lines'][0]) + if m: + subindent = indent + m.end() * ' ' + elif block['type'] == 'field': + m = _fieldre.match(block['lines'][0]) + if m: + key, spaces, rest = m.groups() + # Turn ":foo: bar" into "foo bar". + block['lines'][0] = '%s %s%s' % (key, spaces, rest) + subindent = indent + (2 + len(key) + len(spaces)) * ' ' + elif block['type'] == 'option': + m = _optionre.match(block['lines'][0]) + if m: + option, arg, rest = m.groups() + subindent = indent + (len(option) + len(arg)) * ' ' - return textwrap.fill(text, width=width, - initial_indent=initindent, - subsequent_indent=subindent) + text = ' '.join(map(str.strip, block['lines'])) + return textwrap.fill(text, width=width, + initial_indent=initindent, + subsequent_indent=subindent) def format(text, width, indent=0): @@ -324,11 +254,8 @@ b['indent'] += indent blocks = findliteralblocks(blocks) blocks = inlineliterals(blocks) + blocks = splitparagraphs(blocks) blocks = findsections(blocks) - blocks = findbulletlists(blocks) - blocks = findoptionlists(blocks) - blocks = findfieldlists(blocks) - blocks = finddefinitionlists(blocks) blocks = addmargins(blocks) return '\n'.join(formatblock(b, width) for b in blocks) @@ -346,10 +273,7 @@ text = open(sys.argv[1]).read() blocks = debug(findblocks, text) blocks = debug(findliteralblocks, blocks) + blocks = debug(splitparagraphs, blocks) blocks = debug(findsections, blocks) - blocks = debug(findbulletlists, blocks) - blocks = debug(findoptionlists, blocks) - blocks = debug(findfieldlists, blocks) - blocks = debug(finddefinitionlists, blocks) blocks = debug(addmargins, blocks) print '\n'.join(formatblock(b, 30) for b in blocks)
--- a/mercurial/patch.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/patch.py Sat Nov 07 14:13:15 2009 -0600 @@ -300,7 +300,7 @@ finally: fp.close() - def writelines(self, fname, lines): + def writelines(self, fname, lines): # Ensure supplied data ends in fname, being a regular file or # a symlink. updatedir() will -too magically- take care of # setting it to the proper type afterwards. @@ -342,11 +342,7 @@ # result is a list of line numbers sorted based on distance # from linenum - try: - cand = self.hash[l] - except: - return [] - + cand = self.hash.get(l, []) if len(cand) > 1: # resort our list of potentials forward then back. cand.sort(key=lambda x: abs(x - linenum)) @@ -484,6 +480,8 @@ self.hunk = [ desc ] self.a = [] self.b = [] + self.starta = self.lena = None + self.startb = self.lenb = None if context: self.read_context_hunk(lr) else: @@ -1007,12 +1005,12 @@ return -1 return err -def diffopts(ui, opts={}, untrusted=False): +def diffopts(ui, opts=None, untrusted=False): def get(key, name=None, getter=ui.configbool): - return (opts.get(key) or + return ((opts and opts.get(key)) or getter('diff', name or key, None, untrusted=untrusted)) return mdiff.diffopts( - text=opts.get('text'), + text=opts and opts.get('text'), git=get('git'), nodates=get('nodates'), showfunc=get('show_function', 'showfunc'), @@ -1098,10 +1096,12 @@ util.explain_exit(code)[0]) return fuzz -def internalpatch(patchobj, ui, strip, cwd, files={}, eolmode='strict'): +def internalpatch(patchobj, ui, strip, cwd, files=None, eolmode='strict'): """use builtin patch to apply <patchobj> to the working directory. returns whether patch was applied with fuzz factor.""" + if files is None: + files = {} if eolmode is None: eolmode = ui.config('patch', 'eol', 'strict') try: @@ -1125,7 +1125,7 @@ raise PatchError return ret > 0 -def patch(patchname, ui, strip=1, cwd=None, files={}, eolmode='strict'): +def patch(patchname, ui, strip=1, cwd=None, files=None, eolmode='strict'): """Apply <patchname> to the working directory. 'eolmode' specifies how end of lines should be handled. It can be: @@ -1139,6 +1139,8 @@ """ patcher = ui.config('ui', 'patch') args = [] + if files is None: + files = {} try: if patcher: return externalpatch(patcher, args, patchname, ui, strip, cwd, @@ -1214,7 +1216,7 @@ if opts is None: opts = mdiff.defaultopts - if not node1: + if not node1 and not node2: node1 = repo.dirstate.parents()[0] def lrugetfilectx(): @@ -1225,7 +1227,7 @@ if f not in cache: if len(cache) > 20: del cache[order.pop(0)] - cache[f] = fctx._filelog + cache[f] = fctx.filelog() else: order.remove(f) order.append(f)
--- a/mercurial/revlog.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/revlog.py Sat Nov 07 14:13:15 2009 -0600 @@ -466,7 +466,7 @@ if i: try: d = self._io.parseindex(f, i, self._inline) - except (ValueError, IndexError), e: + except (ValueError, IndexError): raise RevlogError(_("index %s is corrupted") % (self.indexfile)) self.index, self.nodemap, self._chunkcache = d if not self._chunkcache:
--- a/mercurial/sshserver.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/sshserver.py Sat Nov 07 14:13:15 2009 -0600 @@ -9,9 +9,12 @@ from i18n import _ from node import bin, hex import streamclone, util, hook -import os, sys, tempfile, urllib +import os, sys, tempfile, urllib, copy class sshserver(object): + + caps = 'unbundle lookup changegroupsubset branchmap'.split() + def __init__(self, ui, repo): self.ui = ui self.repo = repo @@ -85,8 +88,7 @@ capabilities: space separated list of tokens ''' - - caps = ['unbundle', 'lookup', 'changegroupsubset', 'branchmap'] + caps = copy.copy(self.caps) if self.ui.configbool('server', 'uncompressed'): caps.append('stream=%d' % self.repo.changelog.version) self.respond("capabilities: %s\n" % (' '.join(caps),)) @@ -179,11 +181,9 @@ self.respond('') # write bundle data to temporary file because it can be big - tempname = fp = None + fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') + fp = os.fdopen(fd, 'wb+') try: - fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') - fp = os.fdopen(fd, 'wb+') - count = int(self.fin.readline()) while count: fp.write(self.fin.read(count)) @@ -210,10 +210,8 @@ self.lock.release() self.lock = None finally: - if fp is not None: - fp.close() - if tempname is not None: - os.unlink(tempname) + fp.close() + os.unlink(tempname) def do_stream_out(self): try:
--- a/mercurial/subrepo.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/subrepo.py Sat Nov 07 14:13:15 2009 -0600 @@ -27,7 +27,7 @@ if '.hgsubstate' in ctx: try: for l in ctx['.hgsubstate'].data().splitlines(): - revision, path = l.split() + revision, path = l.split(" ", 1) rev[path] = revision except IOError, err: if err.errno != errno.ENOENT:
--- a/mercurial/tags.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/tags.py Sat Nov 07 14:13:15 2009 -0600 @@ -10,7 +10,6 @@ # Eventually, it could take care of updating (adding/removing/moving) # tags too. -import os from node import nullid, bin, hex, short from i18n import _ import encoding
--- a/mercurial/templatefilters.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/templatefilters.py Sat Nov 07 14:13:15 2009 -0600 @@ -40,10 +40,13 @@ return 'in the future' delta = max(1, int(now - then)) + if delta > agescales[0][1] * 2: + return util.shortdate(date) + for t, s in agescales: n = delta // s if n >= 2 or s == 1: - return fmt(t, n) + return '%s ago' % fmt(t, n) para_re = None space_re = None
--- a/mercurial/transaction.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/transaction.py Sat Nov 07 14:13:15 2009 -0600 @@ -28,14 +28,14 @@ if o or not unlink: try: opener(f, 'a').truncate(o) - except: + except IOError: report(_("failed to truncate %s\n") % f) raise else: try: fn = opener(f).name os.unlink(fn) - except IOError, inst: + except (IOError, OSError), inst: if inst.errno != errno.ENOENT: raise os.unlink(journal) @@ -59,8 +59,7 @@ def __del__(self): if self.journal: - if self.entries: self._abort() - self.file.close() + self._abort() @active def startgroup(self): @@ -126,7 +125,7 @@ self.entries = [] if self.after: self.after() - else: + if os.path.isfile(self.journal): os.unlink(self.journal) self.journal = None @@ -141,7 +140,10 @@ self.count = 0 self.file.close() - if not self.entries: return + if not self.entries: + if self.journal: + os.unlink(self.journal) + return self.report(_("transaction abort!\n"))
--- a/mercurial/ui.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/ui.py Sat Nov 07 14:13:15 2009 -0600 @@ -377,7 +377,7 @@ if total: pct = 100.0 * pos / total - ui.debug('%s:%s %s/%s%s (%4.2g%%)\n' + self.debug('%s:%s %s/%s%s (%4.2g%%)\n' % (topic, item, pos, total, unit, pct)) else: - ui.debug('%s:%s %s%s\n' % (topic, item, pos, unit)) + self.debug('%s:%s %s%s\n' % (topic, item, pos, unit))
--- a/mercurial/url.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/url.py Sat Nov 07 14:13:15 2009 -0600 @@ -408,10 +408,14 @@ self.close_all() if has_https: - class httpsconnection(httplib.HTTPSConnection): + class BetterHTTPS(httplib.HTTPSConnection): + send = keepalive.safesend + + class httpsconnection(BetterHTTPS): response_class = keepalive.HTTPResponse # must be able to send big bundle as stream. - send = _gen_sendfile(httplib.HTTPSConnection) + send = _gen_sendfile(BetterHTTPS) + getresponse = keepalive.wrapgetresponse(httplib.HTTPSConnection) class httpshandler(keepalive.KeepAliveHandler, urllib2.HTTPSHandler): def __init__(self, ui):
--- a/mercurial/util.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/util.py Sat Nov 07 14:13:15 2009 -0600 @@ -1116,6 +1116,7 @@ seen_dirs = [] _add_dir_if_not_there(seen_dirs, path) for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler): + dirs.sort() if '.hg' in dirs: yield root # found a repository qroot = os.path.join(root, '.hg', 'patches') @@ -1223,11 +1224,11 @@ return array.array('h', arri)[1] except ValueError: pass - except IOError, e: - if e[0] == errno.EINVAL: - pass - else: - raise + except IOError, e: + if e[0] == errno.EINVAL: + pass + else: + raise except ImportError: pass return 80
--- a/mercurial/verify.py Wed Nov 04 22:14:26 2009 +0100 +++ b/mercurial/verify.py Sat Nov 07 14:13:15 2009 -0600 @@ -7,6 +7,7 @@ from node import nullid, short from i18n import _ +import os import revlog, util, error def verify(repo): @@ -105,6 +106,9 @@ seen[n] = i return lr + if os.path.exists(repo.sjoin("journal")): + ui.warn(_("abandoned transaction found - run hg recover\n")) + revlogv1 = cl.version != revlog.REVLOGV0 if ui.verbose or not revlogv1: ui.status(_("repository uses revlog format %d\n") %
--- a/templates/gitweb/changelogentry.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/gitweb/changelogentry.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -1,5 +1,5 @@ <div> -<a class="title" href="{url}rev/{node|short}{sessionvars%urlparameter}"><span class="age">{date|age} ago</span>{desc|strip|firstline|escape|nonempty}<span class="logtags"> {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a> +<a class="title" href="{url}rev/{node|short}{sessionvars%urlparameter}"><span class="age">{date|age}</span>{desc|strip|firstline|escape|nonempty}<span class="logtags"> {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a> </div> <div class="title_text"> <div class="log_link">
--- a/templates/gitweb/changeset.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/gitweb/changeset.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -29,7 +29,7 @@ <div class="title_text"> <table cellspacing="0"> <tr><td>author</td><td>{author|obfuscate}</td></tr> -<tr><td></td><td>{date|date} ({date|age} ago)</td></tr> +<tr><td></td><td>{date|date} ({date|age})</td></tr> {branch%changesetbranch} <tr><td>changeset {rev}</td><td style="font-family:monospace">{node|short}</td></tr> {parent%changesetparent}
--- a/templates/gitweb/fileannotate.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/gitweb/fileannotate.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -36,7 +36,7 @@ <td>{author|obfuscate}</td></tr> <tr> <td></td> - <td>{date|date} ({date|age} ago)</td></tr> + <td>{date|date} ({date|age})</td></tr> {branch%filerevbranch} <tr> <td>changeset {rev}</td>
--- a/templates/gitweb/filerevision.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/gitweb/filerevision.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -36,7 +36,7 @@ <td>{author|obfuscate}</td></tr> <tr> <td></td> - <td>{date|date} ({date|age} ago)</td></tr> + <td>{date|date} ({date|age})</td></tr> {branch%filerevbranch} <tr> <td>changeset {rev}</td>
--- a/templates/gitweb/map Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/gitweb/map Sat Nov 07 14:13:15 2009 -0600 @@ -150,7 +150,7 @@ tags = tags.tmpl tagentry = ' <tr class="parity{parity}"> - <td class="age"><i>{date|age} ago</i></td> + <td class="age"><i>{date|age}</i></td> <td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{tag|escape}</b></a></td> <td class="link"> <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> | @@ -161,7 +161,7 @@ branches = branches.tmpl branchentry = ' <tr class="parity{parity}"> - <td class="age"><i>{date|age} ago</i></td> + <td class="age"><i>{date|age}</i></td> <td><a class="list" href="{url}shortlog/{node|short}{sessionvars%urlparameter}"><b>{node|short}</b></a></td> <td class="{status}">{branch|escape}</td> <td class="link"> @@ -204,7 +204,7 @@ inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> ' shortlogentry = ' <tr class="parity{parity}"> - <td class="age"><i>{date|age} ago</i></td> + <td class="age"><i>{date|age}</i></td> <td><i>{author|person}</i></td> <td> <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"> @@ -219,7 +219,7 @@ </tr>' filelogentry = ' <tr class="parity{parity}"> - <td class="age"><i>{date|age} ago</i></td> + <td class="age"><i>{date|age}</i></td> <td> <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"> <b>{desc|strip|firstline|escape|nonempty}</b> @@ -238,7 +238,7 @@ </td> <td>{description}</td> <td>{contact|obfuscate}</td> - <td class="age">{lastchange|age} ago</td> + <td class="age">{lastchange|age}</td> <td class="indexlinks">{archives%indexarchiveentry}</td> <td><div class="rss_logo"><a href="{url}rss-log">RSS</a> <a href="{url}atom-log">Atom</a></div></td> </tr>\n'
--- a/templates/monoblue/changelogentry.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/monoblue/changelogentry.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -1,6 +1,6 @@ <h3 class="changelog"><a class="title" href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}<span class="logtags"> {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a></h3> <ul class="changelog-entry"> - <li class="age">{date|age} ago</li> + <li class="age">{date|age}</li> <li>by <span class="name">{author|obfuscate}</span> <span class="revdate">[{date|rfc822date}] rev {rev}</span></li> <li class="description">{desc|strip|escape|addbreaks|nonempty}</li> </ul>
--- a/templates/monoblue/changeset.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/monoblue/changeset.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -36,7 +36,7 @@ <h2 class="no-link no-border">changeset</h2> <h3 class="changeset"><a href="{url}raw-rev/{node|short}">{desc|strip|escape|firstline|nonempty} <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a></h3> - <p class="changeset-age"><span>{date|age} ago</span></p> + <p class="changeset-age"><span>{date|age}</span></p> <dl class="overview"> <dt>author</dt>
--- a/templates/monoblue/fileannotate.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/monoblue/fileannotate.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -38,7 +38,7 @@ <h2 class="no-link no-border">{file|escape}@{node|short} (annotated)</h2> <h3 class="changeset">{file|escape}</h3> - <p class="changeset-age"><span>{date|age} ago</span></p> + <p class="changeset-age"><span>{date|age}</span></p> <dl class="overview"> <dt>author</dt>
--- a/templates/monoblue/filerevision.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/monoblue/filerevision.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -38,7 +38,7 @@ <h2 class="no-link no-border">{file|escape}@{node|short}</h2> <h3 class="changeset">{file|escape}</h3> - <p class="changeset-age"><span>{date|age} ago</span></p> + <p class="changeset-age"><span>{date|age}</span></p> <dl class="overview"> <dt>author</dt>
--- a/templates/monoblue/map Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/monoblue/map Sat Nov 07 14:13:15 2009 -0600 @@ -127,7 +127,7 @@ tags = tags.tmpl tagentry = ' <tr class="parity{parity}"> - <td class="nowrap">{date|age} ago</td> + <td class="nowrap">{date|age}</td> <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{tag|escape}</a></td> <td class="nowrap"> <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> | @@ -138,7 +138,7 @@ branches = branches.tmpl branchentry = ' <tr class="parity{parity}"> - <td class="nowrap">{date|age} ago</td> + <td class="nowrap">{date|age}</td> <td><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{node|short}</a></td> <td class="{status}">{branch|escape}</td> <td class="nowrap"> @@ -170,7 +170,7 @@ inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> ' shortlogentry = ' <tr class="parity{parity}"> - <td class="nowrap">{date|age} ago</td> + <td class="nowrap">{date|age}</td> <td>{author|person}</td> <td> <a href="{url}rev/{node|short}{sessionvars%urlparameter}"> @@ -185,7 +185,7 @@ </tr>' filelogentry = ' <tr class="parity{parity}"> - <td class="nowrap">{date|age} ago</td> + <td class="nowrap">{date|age}</td> <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></td> <td class="nowrap"> <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> | <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> | <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> @@ -198,7 +198,7 @@ <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td> <td>{description}</td> <td>{contact|obfuscate}</td> - <td>{lastchange|age} ago</td> + <td>{lastchange|age}</td> <td class="indexlinks">{archives%indexarchiveentry}</td> <td> <div class="rss_logo">
--- a/templates/paper/changeset.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/paper/changeset.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -45,7 +45,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date">{date|date} ({date|age} ago)</td></tr> + <td class="date">{date|date} ({date|age})</td></tr> <tr> <th class="author">parents</th> <td class="author">{parent%changesetparent}</td>
--- a/templates/paper/fileannotate.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/paper/fileannotate.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -22,6 +22,7 @@ </ul> <ul> <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li> +<li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li> <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li> <li class="active">annotate</li> <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li> @@ -49,7 +50,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date">{date|date} ({date|age} ago)</td> + <td class="date">{date|date} ({date|age})</td> </tr> <tr> <th class="author">parents</th>
--- a/templates/paper/filediff.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/paper/filediff.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -21,6 +21,7 @@ </ul> <ul> <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li> +<li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li> <li class="active">diff</li> <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li> <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li> @@ -48,7 +49,7 @@ </tr> <tr> <th>date</th> - <td>{date|date} ({date|age} ago)</td> + <td>{date|date} ({date|age})</td> </tr> <tr> <th>parents</th>
--- a/templates/paper/filerevision.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/paper/filerevision.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -21,6 +21,7 @@ </ul> <ul> <li class="active">file</li> +<li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li> <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li> <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li> <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li> @@ -48,7 +49,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date">{date|date} ({date|age} ago)</td> + <td class="date">{date|date} ({date|age})</td> </tr> <tr> <th class="author">parents</th>
--- a/templates/paper/map Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/paper/map Sat Nov 07 14:13:15 2009 -0600 @@ -176,7 +176,7 @@ <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td> <td>{description}</td> <td>{contact|obfuscate}</td> - <td class="age">{lastchange|age} ago</td> + <td class="age">{lastchange|age}</td> <td class="indexlinks">{archives%indexarchiveentry}</td> </tr>\n' indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}"> ↓{type|escape}</a>'
--- a/templates/spartan/changelogentry.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/spartan/changelogentry.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -1,6 +1,6 @@ <table class="logEntry parity{parity}"> <tr> - <th class="age">{date|age} ago:</th> + <th class="age">{date|age}:</th> <th class="firstline">{desc|strip|firstline|escape|nonempty}</th> </tr> <tr>
--- a/templates/spartan/changeset.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/spartan/changeset.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -30,7 +30,7 @@ </tr> <tr> <th class="date">date:</th> - <td class="date">{date|date} ({date|age} ago)</td> + <td class="date">{date|date} ({date|age})</td> </tr> <tr> <th class="files">files:</th>
--- a/templates/spartan/fileannotate.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/spartan/fileannotate.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -29,7 +29,7 @@ <td>{author|obfuscate}</td></tr> <tr> <td class="metatag">date:</td> - <td>{date|date} ({date|age} ago)</td> + <td>{date|date} ({date|age})</td> </tr> <tr> <td class="metatag">permissions:</td>
--- a/templates/spartan/filelogentry.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/spartan/filelogentry.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -1,6 +1,6 @@ <table class="logEntry parity{parity}"> <tr> - <th class="age">{date|age} ago:</th> + <th class="age">{date|age}:</th> <th class="firstline"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></th> </tr> <tr>
--- a/templates/spartan/filerevision.tmpl Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/spartan/filerevision.tmpl Sat Nov 07 14:13:15 2009 -0600 @@ -29,7 +29,7 @@ <td>{author|obfuscate}</td></tr> <tr> <td class="metatag">date:</td> - <td>{date|date} ({date|age} ago)</td></tr> + <td>{date|date} ({date|age})</td></tr> <tr> <td class="metatag">permissions:</td> <td>{permissions|permissions}</td></tr>
--- a/templates/static/style-paper.css Wed Nov 04 22:14:26 2009 +0100 +++ b/templates/static/style-paper.css Sat Nov 07 14:13:15 2009 -0600 @@ -161,7 +161,7 @@ border-bottom: 1px solid #999; } .bigtable tr { border: none; } -.bigtable .age { width: 6em; } +.bigtable .age { width: 7em; } .bigtable .author { width: 12em; } .bigtable .description { } .bigtable .node { width: 5em; font-family: monospace;}
--- a/tests/get-with-headers.py Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/get-with-headers.py Sat Nov 07 14:13:15 2009 -0600 @@ -22,7 +22,6 @@ print "%s: %s" % (h, response.getheader(h)) print data = response.read() -data = re.sub('\d+ years', 'many years', data) sys.stdout.write(data) if 200 <= response.status <= 299:
--- a/tests/hghave Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/hghave Sat Nov 07 14:13:15 2009 -0600 @@ -121,8 +121,8 @@ return matchoutput('git --version 2>&1', r'^git version') def has_rst2html(): - return matchoutput('rst2html --version', r'^rst2html \(Docutils') or \ - matchoutput('rst2html.py --version', r'^rst2html.py \(Docutils') + return matchoutput('rst2html --version 2>&1', r'^rst2html \(Docutils') or \ + matchoutput('rst2html.py --version 2>&1', r'^rst2html.py \(Docutils') def has_svn(): #return matchoutput('svn --version 2>&1', r'^svn, version') and \
--- a/tests/run-tests.py Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/run-tests.py Sat Nov 07 14:13:15 2009 -0600 @@ -93,8 +93,13 @@ parser.add_option("-k", "--keywords", help="run tests matching keywords") parser.add_option("--keep-tmpdir", action="store_true", - help="keep temporary directory after running tests" - " (best used with --tmpdir)") + help="keep temporary directory after running tests") + parser.add_option("--tmpdir", type="string", + help="run tests in the given temporary directory" + " (implies --keep-tmpdir)") + parser.add_option("-d", "--debug", action="store_true", + help="debug mode: write output of test scripts to console" + " rather than capturing and diff'ing it (disables timeout)") parser.add_option("-R", "--restart", action="store_true", help="restart at last error") parser.add_option("-p", "--port", type="int", @@ -109,8 +114,6 @@ parser.add_option("-t", "--timeout", type="int", help="kill errant tests after TIMEOUT seconds" " (default: $%s or %d)" % defaults['timeout']) - parser.add_option("--tmpdir", type="string", - help="run tests in the given temporary directory") parser.add_option("-v", "--verbose", action="store_true", help="output verbose messages") parser.add_option("-n", "--nodiff", action="store_true", @@ -168,22 +171,25 @@ for m in msg: print m, print + sys.stdout.flush() else: vlog = lambda *msg: None if options.tmpdir: options.tmpdir = os.path.expanduser(options.tmpdir) - try: - os.makedirs(options.tmpdir) - except OSError, err: - if err.errno != errno.EEXIST: - raise if options.jobs < 1: parser.error('--jobs must be positive') if options.interactive and options.jobs > 1: print '(--interactive overrides --jobs)' options.jobs = 1 + if options.interactive and options.debug: + parser.error("-i/--interactive and -d/--debug are incompatible") + if options.debug: + if options.timeout != defaults['timeout']: + sys.stderr.write( + 'warning: --timeout option ignored with --debug\n') + options.timeout = 0 if options.py3k_warnings: if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0): parser.error('--py3k-warnings can only be used on Python 2.6+') @@ -379,8 +385,13 @@ def run(cmd, options): """Run command in a sub-process, capturing the output (stdout and stderr). - Return the exist code, and output.""" + Return a tuple (exitcode, output). output is None in debug mode.""" # TODO: Use subprocess.Popen if we're running on Python 2.4 + if options.debug: + proc = subprocess.Popen(cmd, shell=True) + ret = proc.wait() + return (ret, None) + if os.name == 'nt' or sys.platform.startswith('java'): tochild, fromchild = os.popen4(cmd) tochild.close() @@ -492,16 +503,24 @@ mark = '.' skipped = (ret == SKIPPED_STATUS) - # If reference output file exists, check test output against it - if os.path.exists(ref): + # If we're not in --debug mode and reference output file exists, + # check test output against it. + if options.debug: + refout = None # to match out == None + elif os.path.exists(ref): f = open(ref, "r") refout = splitnewlines(f.read()) f.close() else: refout = [] + if skipped: mark = 's' - missing, failed = parsehghaveoutput(out) + if out is None: # debug mode: nothing to parse + missing = ['unknown'] + failed = None + else: + missing, failed = parsehghaveoutput(out) if not missing: missing = ['irrelevant'] if failed: @@ -526,7 +545,7 @@ sys.stdout.write(mark) sys.stdout.flush() - if ret != 0 and not skipped: + if ret != 0 and not skipped and not options.debug: # Save errors to a file for diagnosis f = open(err, "wb") for line in out: @@ -765,8 +784,24 @@ global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE TESTDIR = os.environ["TESTDIR"] = os.getcwd() - HGTMP = os.environ['HGTMP'] = os.path.realpath(tempfile.mkdtemp('', 'hgtests.', - options.tmpdir)) + if options.tmpdir: + options.keep_tmpdir = True + tmpdir = options.tmpdir + if os.path.exists(tmpdir): + # Meaning of tmpdir has changed since 1.3: we used to create + # HGTMP inside tmpdir; now HGTMP is tmpdir. So fail if + # tmpdir already exists. + sys.exit("error: temp dir %r already exists" % tmpdir) + + # Automatically removing tmpdir sounds convenient, but could + # really annoy anyone in the habit of using "--tmpdir=/tmp" + # or "--tmpdir=$HOME". + #vlog("# Removing temp dir", tmpdir) + #shutil.rmtree(tmpdir) + os.makedirs(tmpdir) + else: + tmpdir = tempfile.mkdtemp('', 'hgtests.') + HGTMP = os.environ['HGTMP'] = os.path.realpath(tmpdir) DAEMON_PIDS = None HGRCPATH = None
--- a/tests/test-archive.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-archive.out Sat Nov 07 14:13:15 2009 -0600 @@ -5,20 +5,20 @@ % gz allowed should give 200 200 Script output follows % tar.bz2 and zip disallowed should both give 403 -403 Forbidden -403 Forbidden +403 Archive type not allowed: bz2 +403 Archive type not allowed: zip % bz2 allowed should give 200 200 Script output follows % zip and tar.gz disallowed should both give 403 -403 Forbidden -403 Forbidden +403 Archive type not allowed: zip +403 Archive type not allowed: gz % zip allowed should give 200 200 Script output follows % tar.gz and tar.bz2 disallowed should both give 403 -403 Forbidden -403 Forbidden +403 Archive type not allowed: gz +403 Archive type not allowed: bz2 % invalid arch type should give 404 -404 Not Found +404 Unsupported archive type: None test-archive-TIP/.hg_archival.txt test-archive-TIP/bar
--- a/tests/test-bisect Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-bisect Sat Nov 07 14:13:15 2009 -0600 @@ -87,7 +87,7 @@ echo % test invalid command hg bisect -r -hg bisect --command 'foobar' +hg bisect --command './foobar' 2>&1 | sed 's|\(/bin/sh: \./foobar:\).*|\1 not found|' echo % test bisecting command cat > script.py <<EOF
--- a/tests/test-bisect.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-bisect.out Sat Nov 07 14:13:15 2009 -0600 @@ -304,8 +304,8 @@ summary: msg 6 % test invalid command -/bin/sh: foobar: command not found -abort: failed to execute foobar +/bin/sh: ./foobar: not found +abort: failed to execute ./foobar % test bisecting command Testing changeset 15:e7fa0811edb0 (31 changesets remaining, ~4 tests) 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-branchmap Sat Nov 07 14:13:15 2009 -0600 @@ -0,0 +1,23 @@ +#!/bin/sh + +hgserve() +{ + hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -E errors.log -v $@ \ + | sed -e 's/:[0-9][0-9]*//g' -e 's/http:\/\/[^/]*\//http:\/\/localhost\//' + cat hg.pid >> "$DAEMON_PIDS" +} + +hg init a +hg --encoding utf-8 -R a branch æ +echo foo > a/foo +hg -R a ci -Am foo + +hgserve -R a --config web.push_ssl=False --config web.allow_push=* --encoding latin1 +hg clone http://localhost:$HGPORT1 b +hg --encoding utf-8 -R b log +echo bar >> b/foo +hg -R b ci -m bar +hg --encoding utf-8 -R b push | sed "s/$HGPORT1/PORT/" +hg -R a --encoding utf-8 log + +kill `cat hg.pid`
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-branchmap.out Sat Nov 07 14:13:15 2009 -0600 @@ -0,0 +1,36 @@ +marked working directory as branch æ +adding foo +listening at http://localhost/ (bound to 127.0.0.1) +requesting all changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files +updating working directory +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +changeset: 0:867c11ce77b8 +branch: æ +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: foo + +pushing to http://localhost:PORT +searching for changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files +changeset: 1:58e7c90d67cb +branch: æ +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: bar + +changeset: 0:867c11ce77b8 +branch: æ +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: foo +
--- a/tests/test-churn Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-churn Sat Nov 07 14:13:15 2009 -0600 @@ -50,6 +50,14 @@ echo % churn by hour hg churn -f '%H' -s +echo % churn with separated added/removed lines +hg rm d/g/f2.txt +hg ci -Am "removed d/g/f2.txt" -u user1 -d 14:00 d/g/f2.txt +hg churn --diffstat + +echo % changeset number churn +hg churn -c + cd .. # issue 833: ZeroDivisionError
--- a/tests/test-churn.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-churn.out Sat Nov 07 14:13:15 2009 -0600 @@ -10,7 +10,7 @@ user2 2 ****************************************** % churn up to rev 2 user2 2 *************************************************************** -user1 1 ******************************* +user1 1 ******************************** % churn with aliases alias3 3 ************************************************************** alias1 3 ************************************************************** @@ -24,9 +24,17 @@ user1 3 *********************** user2 2 *************** % churn by hour -06 1 **************** +06 1 ***************** 09 2 ********************************* 12 4 ****************************************************************** -13 1 **************** +13 1 ***************** +% churn with separated added/removed lines +user1 +3/-1 +++++++++++++++++++++++++++++++++++++++++-------------- +user3 +3/-0 +++++++++++++++++++++++++++++++++++++++++ +user2 +2/-0 +++++++++++++++++++++++++++ +% changeset number churn +user1 4 *************************************************************** +user3 3 *********************************************** +user2 2 ******************************** adding foo test 0
--- a/tests/test-clone Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-clone Sat Nov 07 14:13:15 2009 -0600 @@ -67,4 +67,136 @@ hg clone ../a . cd .. +echo +echo +echo % "*** tests for option -u ***" +echo + + +echo +echo % "adding some more history to repo a" +cd a +echo % "tag ref1" +hg tag ref1 +echo the quick brown fox >a +hg ci -m "hacked default" +echo % "updating back to ref1" +hg up ref1 +echo +echo % "add branch 'stable' to repo a for later tests" +hg branch stable +echo some text >a +hg ci -m "starting branch stable" +echo % "tag ref2" +hg tag ref2 +echo some more text >a +hg ci -m "another change for branch stable" +echo +echo % "updating back to ref2" +hg up ref2 +echo +echo % "parents of repo a" +hg parents +echo +echo % "repo a has two heads" +hg heads +cd .. + +echo +echo % "testing clone -U -u 1 a ua (must abort)" +hg clone -U -u 1 a ua + +echo +echo % "testing clone -u . a ua" +hg clone -u . a ua +echo +echo % "repo ua has both heads" +hg -R ua heads +echo +echo % "same revision checked out in repo a and ua" +hg -R a parents --template "{node|short}\n" +hg -R ua parents --template "{node|short}\n" +rm -r ua + +echo +echo % "testing clone --pull -u . a ua" +hg clone --pull -u . a ua +echo +echo % "repo ua has both heads" +hg -R ua heads +echo +echo % "same revision checked out in repo a and ua" +hg -R a parents --template "{node|short}\n" +hg -R ua parents --template "{node|short}\n" +rm -r ua + +echo +echo % "testing clone -u stable a ua" +hg clone -u stable a ua +echo +echo % "repo ua has both heads" +hg -R ua heads +echo +echo % "branch stable is checked out" +hg -R ua parents +rm -r ua + +echo +echo % "testing clone a ua" +hg clone a ua +echo +echo % "repo ua has both heads" +hg -R ua heads +echo +echo % "branch default is checked out" +hg -R ua parents +rm -r ua + +echo +echo % "testing clone -u . a#stable ua" +hg clone -u . a#stable ua +echo +echo % "repo ua has only branch stable" +hg -R ua heads +echo +echo % "same revision checked out in repo a and ua" +hg -R a parents --template "{node|short}\n" +hg -R ua parents --template "{node|short}\n" +rm -r ua + +echo +echo % "testing clone -u . -r stable a ua" +hg clone -u . -r stable a ua +echo +echo % "repo ua has only branch stable" +hg -R ua heads +echo +echo % "same revision checked out in repo a and ua" +hg -R a parents --template "{node|short}\n" +hg -R ua parents --template "{node|short}\n" +rm -r ua + +echo +echo % "testing clone -r stable a ua" +hg clone -r stable a ua +echo +echo % "repo ua has only branch stable" +hg -R ua heads +echo +echo % "branch stable is checked out" +hg -R ua parents +rm -r ua + +echo +echo % "testing clone -u . -r stable -r default a ua" +hg clone -u . -r stable -r default a ua +echo +echo % "repo ua has two heads" +hg -R ua heads +echo +echo % "same revision checked out in repo a and ua" +hg -R a parents --template "{node|short}\n" +hg -R ua parents --template "{node|short}\n" +rm -r ua + exit 0
--- a/tests/test-clone.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-clone.out Sat Nov 07 14:13:15 2009 -0600 @@ -54,3 +54,246 @@ % clone to . updating to branch default 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + + +% *** tests for option -u *** + + +% adding some more history to repo a +% tag ref1 +% updating back to ref1 +1 files updated, 0 files merged, 1 files removed, 0 files unresolved + +% add branch 'stable' to repo a for later tests +marked working directory as branch stable +created new head +% tag ref2 + +% updating back to ref2 +1 files updated, 0 files merged, 1 files removed, 0 files unresolved + +% parents of repo a +changeset: 13:e8ece76546a6 +branch: stable +tag: ref2 +parent: 10:a7949464abda +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: starting branch stable + + +% repo a has two heads +changeset: 15:0aae7cf88f0d +branch: stable +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: another change for branch stable + +changeset: 12:f21241060d6a +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: hacked default + + +% testing clone -U -u 1 a ua (must abort) +abort: cannot specify both --noupdate and --updaterev + +% testing clone -u . a ua +updating to branch stable +2 files updated, 0 files merged, 0 files removed, 0 files unresolved + +% repo ua has both heads +changeset: 15:0aae7cf88f0d +branch: stable +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: another change for branch stable + +changeset: 12:f21241060d6a +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: hacked default + + +% same revision checked out in repo a and ua +e8ece76546a6 +e8ece76546a6 + +% testing clone --pull -u . a ua +requesting all changes +adding changesets +adding manifests +adding file changes +added 16 changesets with 16 changes to 3 files (+1 heads) +updating to branch stable +2 files updated, 0 files merged, 0 files removed, 0 files unresolved + +% repo ua has both heads +changeset: 15:0aae7cf88f0d +branch: stable +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: another change for branch stable + +changeset: 12:f21241060d6a +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: hacked default + + +% same revision checked out in repo a and ua +e8ece76546a6 +e8ece76546a6 + +% testing clone -u stable a ua +updating to branch stable +3 files updated, 0 files merged, 0 files removed, 0 files unresolved + +% repo ua has both heads +changeset: 15:0aae7cf88f0d +branch: stable +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: another change for branch stable + +changeset: 12:f21241060d6a +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: hacked default + + +% branch stable is checked out +changeset: 15:0aae7cf88f0d +branch: stable +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: another change for branch stable + + +% testing clone a ua +updating to branch default +3 files updated, 0 files merged, 0 files removed, 0 files unresolved + +% repo ua has both heads +changeset: 15:0aae7cf88f0d +branch: stable +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: another change for branch stable + +changeset: 12:f21241060d6a +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: hacked default + + +% branch default is checked out +changeset: 12:f21241060d6a +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: hacked default + + +% testing clone -u . a#stable ua +requesting all changes +adding changesets +adding manifests +adding file changes +added 14 changesets with 14 changes to 3 files +updating to branch stable +2 files updated, 0 files merged, 0 files removed, 0 files unresolved + +% repo ua has only branch stable +changeset: 13:0aae7cf88f0d +branch: stable +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: another change for branch stable + + +% same revision checked out in repo a and ua +e8ece76546a6 +e8ece76546a6 + +% testing clone -u . -r stable a ua +requesting all changes +adding changesets +adding manifests +adding file changes +added 14 changesets with 14 changes to 3 files +updating to branch stable +2 files updated, 0 files merged, 0 files removed, 0 files unresolved + +% repo ua has only branch stable +changeset: 13:0aae7cf88f0d +branch: stable +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: another change for branch stable + + +% same revision checked out in repo a and ua +e8ece76546a6 +e8ece76546a6 + +% testing clone -r stable a ua +requesting all changes +adding changesets +adding manifests +adding file changes +added 14 changesets with 14 changes to 3 files +updating to branch stable +3 files updated, 0 files merged, 0 files removed, 0 files unresolved + +% repo ua has only branch stable +changeset: 13:0aae7cf88f0d +branch: stable +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: another change for branch stable + + +% branch stable is checked out +changeset: 13:0aae7cf88f0d +branch: stable +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: another change for branch stable + + +% testing clone -u . -r stable -r default a ua +requesting all changes +adding changesets +adding manifests +adding file changes +added 16 changesets with 16 changes to 3 files (+1 heads) +updating to branch stable +2 files updated, 0 files merged, 0 files removed, 0 files unresolved + +% repo ua has two heads +changeset: 15:0aae7cf88f0d +branch: stable +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: another change for branch stable + +changeset: 12:f21241060d6a +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: hacked default + + +% same revision checked out in repo a and ua +e8ece76546a6 +e8ece76546a6
--- a/tests/test-debugcomplete.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-debugcomplete.out Sat Nov 07 14:13:15 2009 -0600 @@ -165,9 +165,9 @@ % Show all commands + options add: include, exclude, dry-run annotate: rev, follow, text, user, date, number, changeset, line-number, include, exclude -clone: noupdate, rev, pull, uncompressed, ssh, remotecmd +clone: noupdate, updaterev, rev, pull, uncompressed, ssh, remotecmd commit: addremove, close-branch, include, exclude, message, logfile, date, user -diff: rev, change, text, git, nodates, show-function, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude +diff: rev, change, text, git, nodates, show-function, inverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude export: output, switch-parent, text, git, nodates forget: include, exclude init: ssh, remotecmd
--- a/tests/test-diff-color Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-diff-color Sat Nov 07 14:13:15 2009 -0600 @@ -51,3 +51,14 @@ y EOF echo + +echo "[extensions]" >> $HGRCPATH +echo "mq=" >> $HGRCPATH + +hg rollback +echo % qrecord +hg qrecord --color=always -m moda patch <<EOF +y +y +EOF +echo
--- a/tests/test-diff-color.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-diff-color.out Sat Nov 07 14:13:15 2009 -0600 @@ -41,3 +41,19 @@ a c record this change to 'a'? [Ynsfdaq?] +rolling back last transaction +% qrecord +[0;1mdiff --git a/a b/a[0m +[0;36;1mold mode 100644[0m +[0;36;1mnew mode 100755[0m +1 hunks, 2 lines changed +examine changes to 'a'? [Ynsfdaq?] [0;35m@@ -2,7 +2,7 @@[0m + c + a + a +[0;31m-b[0m +[0;32m+dd[0m + a + a + c +record this change to 'a'? [Ynsfdaq?]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-diff-inverse Sat Nov 07 14:13:15 2009 -0600 @@ -0,0 +1,24 @@ +#!/bin/sh + +hg init +cat > a <<EOF +a +b +c +EOF +hg ci -Am adda + +cat > a <<EOF +d +e +f +EOF +hg ci -m moda + +hg diff --inverse -r0 -r1 + +cat >> a <<EOF +g +h +EOF +hg diff --inverse --nodates
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-diff-inverse.out Sat Nov 07 14:13:15 2009 -0600 @@ -0,0 +1,20 @@ +adding a +diff -r 2855cdcfcbb7 -r 8e1805a3cf6e a +--- a/a Thu Jan 01 00:00:00 1970 +0000 ++++ b/a Thu Jan 01 00:00:00 1970 +0000 +@@ -1,3 +1,3 @@ +-d +-e +-f ++a ++b ++c +diff -r 2855cdcfcbb7 a +--- a/a ++++ b/a +@@ -1,5 +1,3 @@ + d + e + f +-g +-h
--- a/tests/test-extension Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-extension Sat Nov 07 14:13:15 2009 -0600 @@ -75,6 +75,20 @@ # command with no output, we just want to see the extensions loaded hg paths +# check hgweb's load order +echo '% hgweb.cgi' +cat > hgweb.cgi <<EOF +#!/usr/bin/env python +from mercurial import demandimport; demandimport.enable() +from mercurial.hgweb import hgweb +from mercurial.hgweb import wsgicgi + +application = hgweb('.', 'test repo') +wsgicgi.launch(application) +EOF +SCRIPT_NAME='/' SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \ + | grep '^[[:digit:]]) [[:alnum:] ]*$' # ignores HTML output + echo 'foo = !' >> $HGRCPATH echo 'bar = !' >> $HGRCPATH
--- a/tests/test-extension.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-extension.out Sat Nov 07 14:13:15 2009 -0600 @@ -24,6 +24,17 @@ 3) bar extsetup 4) foo reposetup 4) bar reposetup +% hgweb.cgi +1) foo imported +1) bar imported +2) foo uisetup +2) bar uisetup +3) foo extsetup +3) bar extsetup +4) foo reposetup +4) bar reposetup +4) foo reposetup +4) bar reposetup empty extension - empty cmdtable no commands defined @@ -54,7 +65,7 @@ --debugger start debugger --encoding set the charset encoding (default: ascii) --encodingmode set the charset encoding mode (default: strict) - --traceback print traceback on exception + --traceback always print a traceback on exception --time time how long the command takes --profile print command execution profile --version output version information and exit @@ -84,7 +95,7 @@ --debugger start debugger --encoding set the charset encoding (default: ascii) --encodingmode set the charset encoding mode (default: strict) - --traceback print traceback on exception + --traceback always print a traceback on exception --time time how long the command takes --profile print command execution profile --version output version information and exit
--- a/tests/test-glog Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-glog Sat Nov 07 14:13:15 2009 -0600 @@ -165,6 +165,9 @@ hg commit -mmore hg glog two +echo "% file log with explicit style (issue 1896)" +hg glog --style=default one + echo % incoming and outgoing cd .. hg clone -U -r31 repo repo2
--- a/tests/test-glog.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-glog.out Sat Nov 07 14:13:15 2009 -0600 @@ -575,6 +575,12 @@ date: Thu Jan 01 00:00:00 1970 +0000 summary: two +% file log with explicit style (issue 1896) +o changeset: 0:3d578b4a1f53 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: one + % incoming and outgoing requesting all changes adding changesets
--- a/tests/test-help.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-help.out Sat Nov 07 14:13:15 2009 -0600 @@ -237,6 +237,7 @@ -g --git use git extended diff format --nodates don't include dates in diff headers -p --show-function show which function each change is in + --inverse produce a diff that undoes the changes -w --ignore-all-space ignore white space when comparing lines -b --ignore-space-change ignore changes in the amount of white space -B --ignore-blank-lines ignore changes whose lines are all blank
--- a/tests/test-hgweb-commands.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-hgweb-commands.out Sat Nov 07 14:13:15 2009 -0600 @@ -210,17 +210,17 @@ <th class="description">description</th> </tr> <tr class="parity0"> - <td class="age">many years</td> + <td class="age">1970-01-01</td> <td class="author">test</td> <td class="description"><a href="/rev/1d22e65f027e">branch</a><span class="branchhead">stable</span> <span class="tag">tip</span> </td> </tr> <tr class="parity1"> - <td class="age">many years</td> + <td class="age">1970-01-01</td> <td class="author">test</td> <td class="description"><a href="/rev/a4f92ed23982">Added tag 1.0 for changeset 2ef0ac749a14</a><span class="branchhead">default</span> </td> </tr> <tr class="parity0"> - <td class="age">many years</td> + <td class="age">1970-01-01</td> <td class="author">test</td> <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> </td> </tr> @@ -291,7 +291,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td></tr> + <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr> <tr> <th class="author">parents</th> <td class="author"></td> @@ -394,6 +394,7 @@ </ul> <ul> <li class="active">file</li> +<li><a href="/file/tip/foo">latest</a></li> <li><a href="/diff/a4f92ed23982/foo">diff</a></li> <li><a href="/annotate/a4f92ed23982/foo">annotate</a></li> <li><a href="/log/a4f92ed23982/foo">file log</a></li> @@ -421,7 +422,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td> + <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td> </tr> <tr> <th class="author">parents</th> @@ -522,7 +523,7 @@ <table cellspacing="0"> <tr class="parity0"> -<td class="age"><i>many years ago</i></td> +<td class="age"><i>1970-01-01</i></td> <td><a class="list" href="/shortlog/1d22e65f027e?style=gitweb"><b>1d22e65f027e</b></a></td> <td class="open">stable</td> <td class="link"> @@ -532,7 +533,7 @@ </td> </tr> <tr class="parity1"> -<td class="age"><i>many years ago</i></td> +<td class="age"><i>1970-01-01</i></td> <td><a class="list" href="/shortlog/a4f92ed23982?style=gitweb"><b>a4f92ed23982</b></a></td> <td class="inactive">default</td> <td class="link"> @@ -607,7 +608,7 @@ <table cellspacing="0"> <tr class="parity0"> -<td class="age"><i>many years ago</i></td> +<td class="age"><i>1970-01-01</i></td> <td><i>test</i></td> <td> <a class="list" href="/rev/1d22e65f027e?style=gitweb"> @@ -621,7 +622,7 @@ </td> </tr> <tr class="parity1"> -<td class="age"><i>many years ago</i></td> +<td class="age"><i>1970-01-01</i></td> <td><i>test</i></td> <td> <a class="list" href="/rev/a4f92ed23982?style=gitweb"> @@ -635,7 +636,7 @@ </td> </tr> <tr class="parity0"> -<td class="age"><i>many years ago</i></td> +<td class="age"><i>1970-01-01</i></td> <td><i>test</i></td> <td> <a class="list" href="/rev/2ef0ac749a14?style=gitweb"> @@ -655,7 +656,7 @@ <table cellspacing="0"> <tr class="parity0"> -<td class="age"><i>many years ago</i></td> +<td class="age"><i>1970-01-01</i></td> <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>1.0</b></a></td> <td class="link"> <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> | @@ -670,7 +671,7 @@ <table cellspacing="0"> <tr class="parity0"> -<td class="age"><i>many years ago</i></td> +<td class="age"><i>1970-01-01</i></td> <td><a class="list" href="/shortlog/1d22e65f027e?style=gitweb"><b>1d22e65f027e</b></a></td> <td class="">stable</td> <td class="link"> @@ -680,7 +681,7 @@ </td> </tr> <tr class="parity1"> -<td class="age"><i>many years ago</i></td> +<td class="age"><i>1970-01-01</i></td> <td><a class="list" href="/shortlog/a4f92ed23982?style=gitweb"><b>a4f92ed23982</b></a></td> <td class="">default</td> <td class="link"> @@ -763,7 +764,7 @@ <script> <!-- hide script content -var data = [["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "many years", ["stable", true], ["tip"]], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "many years", ["default", true], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "many years", ["default", false], ["1.0"]]]; +var data = [["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", true], ["tip"]], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"]]]; var graph = new Graph(); graph.scale(39); @@ -875,7 +876,7 @@ 1 % failing unbundle, requires POST request -405 Method Not Allowed +405 push requires POST request 0 push requires POST request
--- a/tests/test-hgweb-diffs Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-hgweb-diffs Sat Nov 07 14:13:15 2009 -0600 @@ -38,5 +38,11 @@ echo % diff removed file "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/tip/a' +cd .. +echo % test import rev as raw-rev +hg clone -r0 test test1 +cd test1 +hg import -q --exact http://localhost:$HGPORT/rev/1 + echo % errors -cat errors.log +cat ../test/errors.log
--- a/tests/test-hgweb-diffs.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-hgweb-diffs.out Sat Nov 07 14:13:15 2009 -0600 @@ -59,7 +59,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td></tr> + <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr> <tr> <th class="author">parents</th> <td class="author"></td> @@ -149,6 +149,7 @@ </ul> <ul> <li><a href="/file/78e4ebad7cdf/a">file</a></li> +<li><a href="/file/tip/a">latest</a></li> <li class="active">diff</li> <li><a href="/annotate/78e4ebad7cdf/a">annotate</a></li> <li><a href="/log/78e4ebad7cdf/a">file log</a></li> @@ -176,7 +177,7 @@ </tr> <tr> <th>date</th> - <td>Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td> + <td>Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td> </tr> <tr> <th>parents</th> @@ -263,7 +264,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td></tr> + <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr> <tr> <th class="author">parents</th> <td class="author"></td> @@ -357,6 +358,7 @@ </ul> <ul> <li><a href="/file/78e4ebad7cdf/a">file</a></li> +<li><a href="/file/tip/a">latest</a></li> <li class="active">diff</li> <li><a href="/annotate/78e4ebad7cdf/a">annotate</a></li> <li><a href="/log/78e4ebad7cdf/a">file log</a></li> @@ -384,7 +386,7 @@ </tr> <tr> <th>date</th> - <td>Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td> + <td>Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td> </tr> <tr> <th>parents</th> @@ -415,4 +417,12 @@ </body> </html> +% test import rev as raw-rev +requesting all changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 2 changes to 2 files +updating to branch default +2 files updated, 0 files merged, 0 files removed, 0 files unresolved % errors
--- a/tests/test-hgweb-filelog.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-hgweb-filelog.out Sat Nov 07 14:13:15 2009 -0600 @@ -148,12 +148,12 @@ <th class="description">description</th> </tr> <tr class="parity0"> - <td class="age">many years</td> + <td class="age">1970-01-01</td> <td class="author">test</td> <td class="description"><a href="/rev/01de2d66a28d">second a</a></td> </tr> <tr class="parity1"> - <td class="age">many years</td> + <td class="age">1970-01-01</td> <td class="author">test</td> <td class="description"><a href="/rev/5ed941583260">first a</a></td> </tr> @@ -231,12 +231,12 @@ <th class="description">description</th> </tr> <tr class="parity0"> - <td class="age">many years</td> + <td class="age">1970-01-01</td> <td class="author">test</td> <td class="description"><a href="/rev/01de2d66a28d">second a</a></td> </tr> <tr class="parity1"> - <td class="age">many years</td> + <td class="age">1970-01-01</td> <td class="author">test</td> <td class="description"><a href="/rev/5ed941583260">first a</a></td> </tr> @@ -314,7 +314,7 @@ <th class="description">description</th> </tr> <tr class="parity0"> - <td class="age">many years</td> + <td class="age">1970-01-01</td> <td class="author">test</td> <td class="description"><a href="/rev/5ed941583260">first a</a></td> </tr> @@ -392,7 +392,7 @@ <th class="description">description</th> </tr> <tr class="parity0"> - <td class="age">many years</td> + <td class="age">1970-01-01</td> <td class="author">test</td> <td class="description"><a href="/rev/5ed941583260">first a</a></td> </tr> @@ -499,7 +499,7 @@ <table class="logEntry parity0"> <tr> - <th class="age">many years ago:</th> + <th class="age">1970-01-01:</th> <th class="firstline"><a href="/rev/38d962e6234d?style=spartan">change c</a></th> </tr> <tr> @@ -524,7 +524,7 @@ <table class="logEntry parity1"> <tr> - <th class="age">many years ago:</th> + <th class="age">1970-01-01:</th> <th class="firstline"><a href="/rev/a3b6a9e4507e?style=spartan">mv b</a></th> </tr> <tr>
--- a/tests/test-hgweb-removed.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-hgweb-removed.out Sat Nov 07 14:13:15 2009 -0600 @@ -57,7 +57,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td></tr> + <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr> <tr> <th class="author">parents</th> <td class="author"><a href="/rev/cb9a9f314b8b">cb9a9f314b8b</a> </td> @@ -121,6 +121,7 @@ </ul> <ul> <li><a href="/file/c78f6c5cbea9/a">file</a></li> +<li><a href="/file/tip/a">latest</a></li> <li class="active">diff</li> <li><a href="/annotate/c78f6c5cbea9/a">annotate</a></li> <li><a href="/log/c78f6c5cbea9/a">file log</a></li> @@ -148,7 +149,7 @@ </tr> <tr> <th>date</th> - <td>Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td> + <td>Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td> </tr> <tr> <th>parents</th>
--- a/tests/test-hgwebdir.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-hgwebdir.out Sat Nov 07 14:13:15 2009 -0600 @@ -29,6 +29,7 @@ 200 Script output follows +/t/a/ /b/ /coll/a/ /coll/a/.hg/patches/ @@ -39,7 +40,6 @@ /rcoll/b/ /rcoll/b/d/ /rcoll/c/ -/t/a/ 200 Script output follows @@ -64,7 +64,7 @@ <table class="bigtable"> <tr> - <th><a href="?sort=-name">Name</a></th> + <th><a href="?sort=name">Name</a></th> <th><a href="?sort=description">Description</a></th> <th><a href="?sort=contact">Contact</a></th> <th><a href="?sort=lastchange">Last change</a></th> @@ -72,7 +72,7 @@ </tr> <tr class="parity0"> -<td><a href="/b/?style=paper">b</a></td> +<td><a href="/t/a/?style=paper">t/a</a></td> <td>unknown</td> <td>Foo Bar <foo.bar@example.com></td> <td class="age">seconds ago</td> @@ -80,7 +80,7 @@ </tr> <tr class="parity1"> -<td><a href="/coll/a/?style=paper">coll/a</a></td> +<td><a href="/b/?style=paper">b</a></td> <td>unknown</td> <td>Foo Bar <foo.bar@example.com></td> <td class="age">seconds ago</td> @@ -88,7 +88,7 @@ </tr> <tr class="parity0"> -<td><a href="/coll/a/.hg/patches/?style=paper">coll/a/.hg/patches</a></td> +<td><a href="/coll/a/?style=paper">coll/a</a></td> <td>unknown</td> <td>Foo Bar <foo.bar@example.com></td> <td class="age">seconds ago</td> @@ -96,7 +96,7 @@ </tr> <tr class="parity1"> -<td><a href="/coll/b/?style=paper">coll/b</a></td> +<td><a href="/coll/a/.hg/patches/?style=paper">coll/a/.hg/patches</a></td> <td>unknown</td> <td>Foo Bar <foo.bar@example.com></td> <td class="age">seconds ago</td> @@ -104,7 +104,7 @@ </tr> <tr class="parity0"> -<td><a href="/coll/c/?style=paper">coll/c</a></td> +<td><a href="/coll/b/?style=paper">coll/b</a></td> <td>unknown</td> <td>Foo Bar <foo.bar@example.com></td> <td class="age">seconds ago</td> @@ -112,7 +112,7 @@ </tr> <tr class="parity1"> -<td><a href="/rcoll/a/?style=paper">rcoll/a</a></td> +<td><a href="/coll/c/?style=paper">coll/c</a></td> <td>unknown</td> <td>Foo Bar <foo.bar@example.com></td> <td class="age">seconds ago</td> @@ -120,7 +120,7 @@ </tr> <tr class="parity0"> -<td><a href="/rcoll/a/.hg/patches/?style=paper">rcoll/a/.hg/patches</a></td> +<td><a href="/rcoll/a/?style=paper">rcoll/a</a></td> <td>unknown</td> <td>Foo Bar <foo.bar@example.com></td> <td class="age">seconds ago</td> @@ -128,7 +128,7 @@ </tr> <tr class="parity1"> -<td><a href="/rcoll/b/?style=paper">rcoll/b</a></td> +<td><a href="/rcoll/a/.hg/patches/?style=paper">rcoll/a/.hg/patches</a></td> <td>unknown</td> <td>Foo Bar <foo.bar@example.com></td> <td class="age">seconds ago</td> @@ -136,7 +136,7 @@ </tr> <tr class="parity0"> -<td><a href="/rcoll/b/d/?style=paper">rcoll/b/d</a></td> +<td><a href="/rcoll/b/?style=paper">rcoll/b</a></td> <td>unknown</td> <td>Foo Bar <foo.bar@example.com></td> <td class="age">seconds ago</td> @@ -144,7 +144,7 @@ </tr> <tr class="parity1"> -<td><a href="/rcoll/c/?style=paper">rcoll/c</a></td> +<td><a href="/rcoll/b/d/?style=paper">rcoll/b/d</a></td> <td>unknown</td> <td>Foo Bar <foo.bar@example.com></td> <td class="age">seconds ago</td> @@ -152,7 +152,7 @@ </tr> <tr class="parity0"> -<td><a href="/t/a/?style=paper">t/a</a></td> +<td><a href="/rcoll/c/?style=paper">rcoll/c</a></td> <td>unknown</td> <td>Foo Bar <foo.bar@example.com></td> <td class="age">seconds ago</td> @@ -200,7 +200,7 @@ <table class="bigtable"> <tr> - <th><a href="?sort=-name">Name</a></th> + <th><a href="?sort=name">Name</a></th> <th><a href="?sort=description">Description</a></th> <th><a href="?sort=contact">Contact</a></th> <th><a href="?sort=lastchange">Last change</a></th>
--- a/tests/test-highlight.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-highlight.out Sat Nov 07 14:13:15 2009 -0600 @@ -33,6 +33,7 @@ </ul> <ul> <li class="active">file</li> +<li><a href="/file/tip/primes.py">latest</a></li> <li><a href="/diff/853dcd4de2a6/primes.py">diff</a></li> <li><a href="/annotate/853dcd4de2a6/primes.py">annotate</a></li> <li><a href="/log/853dcd4de2a6/primes.py">file log</a></li> @@ -60,7 +61,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td> + <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td> </tr> <tr> <th class="author">parents</th> @@ -152,6 +153,7 @@ </ul> <ul> <li><a href="/file/853dcd4de2a6/primes.py">file</a></li> +<li><a href="/file/tip/primes.py">latest</a></li> <li><a href="/diff/853dcd4de2a6/primes.py">diff</a></li> <li class="active">annotate</li> <li><a href="/log/853dcd4de2a6/primes.py">file log</a></li> @@ -179,7 +181,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td> + <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td> </tr> <tr> <th class="author">parents</th>
--- a/tests/test-install Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-install Sat Nov 07 14:13:15 2009 -0600 @@ -1,3 +1,10 @@ #!/bin/sh +echo '% hg debuginstall' hg debuginstall + +echo '% hg debuginstall with no username' +HGUSER= hg debuginstall + +# Happy End +true
--- a/tests/test-install.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-install.out Sat Nov 07 14:13:15 2009 -0600 @@ -1,3 +1,4 @@ +% hg debuginstall Checking encoding (ascii)... Checking extensions... Checking templates... @@ -5,3 +6,13 @@ Checking commit editor... Checking username... No problems detected +% hg debuginstall with no username +Checking encoding (ascii)... +Checking extensions... +Checking templates... +Checking patch... +Checking commit editor... +Checking username... + Please specify a username. + (specify a username in your .hgrc file) +1 problems detected, please check your install!
--- a/tests/test-journal-exists Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-journal-exists Sat Nov 07 14:13:15 2009 -0600 @@ -3,6 +3,7 @@ hg init echo a > a hg ci -Am0 +hg -q clone . foo touch .hg/store/journal @@ -10,3 +11,10 @@ hg ci -Am0 hg recover + +echo % check that zero-size journals are correctly aborted +hg bundle -qa repo.hg +chmod -w foo/.hg/store/00changelog.i +hg -R foo unbundle repo.hg 2>&1 | sed 's/\(abort: Permission denied\).*/\1/' +if test -f foo/.hg/store/journal; then echo 'journal exists :-('; fi +exit 0
--- a/tests/test-journal-exists.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-journal-exists.out Sat Nov 07 14:13:15 2009 -0600 @@ -1,8 +1,11 @@ adding a -abort: journal already exists - run hg recover! +abort: abandoned transaction found - run hg recover! rolling back interrupted transaction checking changesets checking manifests crosschecking files in changesets and manifests checking files 1 files, 1 changesets, 1 total revisions +% check that zero-size journals are correctly aborted +adding changesets +abort: Permission denied
--- a/tests/test-merge5.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-merge5.out Sat Nov 07 14:13:15 2009 -0600 @@ -2,6 +2,6 @@ removing b created new head % should abort -abort: crosses branches (use 'hg merge' or 'hg update -C' to discard changes) +abort: crosses branches (use 'hg merge' to merge or use 'hg update -C' to discard changes) % should succeed -abort: crosses branches (use 'hg merge' or 'hg update -C') +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/tests/test-minirst.py Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-minirst.py Sat Nov 07 14:13:15 2009 -0600 @@ -12,28 +12,13 @@ paragraphs = """ This is some text in the first paragraph. - An indented paragraph - with just two lines. - - -The third paragraph. It is followed by some -random lines with spurious spaces. + A small indented paragraph. + It is followed by some lines + containing random whitespace. - - -No indention - here, despite -the uneven left - margin. - - Only the - left-most line - (this line!) - is significant - for the indentation - +The third and final paragraph. """ debugformat('paragraphs', paragraphs, 60) @@ -108,6 +93,15 @@ Literal block with no indentation (apart from the two spaces added to all literal blocks). + +1. This is an enumerated list (first item). +2. Continuing with the second item. + +(1) foo +(2) bar + +1) Another +2) List """ debugformat('lists', lists, 60)
--- a/tests/test-minirst.py.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-minirst.py.out Sat Nov 07 14:13:15 2009 -0600 @@ -2,15 +2,10 @@ ---------------------------------------------------------------------- This is some text in the first paragraph. - An indented paragraph with just two lines. - -The third paragraph. It is followed by some random lines -with spurious spaces. + A small indented paragraph. It is followed by some lines + containing random whitespace. -No indention here, despite the uneven left margin. - - Only the left-most line (this line!) is significant for - the indentation +The third and final paragraph. ---------------------------------------------------------------------- paragraphs formatted to fit within 30 characters: @@ -18,19 +13,12 @@ This is some text in the first paragraph. - An indented paragraph with - just two lines. - -The third paragraph. It is -followed by some random lines -with spurious spaces. + A small indented paragraph. + It is followed by some lines + containing random + whitespace. -No indention here, despite the -uneven left margin. - - Only the left-most line - (this line!) is significant - for the indentation +The third and final paragraph. ---------------------------------------------------------------------- definitions formatted to fit within 60 characters: @@ -125,6 +113,13 @@ Literal block with no indentation (apart from the two spaces added to all literal blocks). + +1. This is an enumerated list (first item). +2. Continuing with the second item. +(1) foo +(2) bar +1) Another +2) List ---------------------------------------------------------------------- lists formatted to fit within 30 characters: @@ -153,6 +148,15 @@ Literal block with no indentation (apart from the two spaces added to all literal blocks). + +1. This is an enumerated list + (first item). +2. Continuing with the second + item. +(1) foo +(2) bar +1) Another +2) List ---------------------------------------------------------------------- options formatted to fit within 60 characters:
--- a/tests/test-mq-qdiff Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-mq-qdiff Sat Nov 07 14:13:15 2009 -0600 @@ -55,5 +55,8 @@ echo % qdiff -U 1 -B hg qdiff --nodates -U 1 -B -echo qdiff -w +echo % qdiff -w hg qdiff --nodates -w + +echo % qdiff --inverse +hg qdiff --nodates --inverse
--- a/tests/test-mq-qdiff.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-mq-qdiff.out Sat Nov 07 14:13:15 2009 -0600 @@ -76,7 +76,7 @@ +hello world + goodbye world 7 -qdiff -w +% qdiff -w diff -r 35fb829491c1 lines --- a/lines +++ b/lines @@ -86,3 +86,21 @@ 1 2 3 +% qdiff --inverse +diff -r 35fb829491c1 lines +--- a/lines ++++ b/lines +@@ -1,11 +1,9 @@ +- +- + 1 + 2 + 3 + 4 +-hello world +- goodbye world ++hello world ++goodbye world + 7 + 8 + 9
--- a/tests/test-mq-qnew Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-mq-qnew Sat Nov 07 14:13:15 2009 -0600 @@ -54,3 +54,7 @@ hg st hg qnew -g -f p cat ../.hg/patches/p + +echo '% qnew -u with no username configured' +HGUSER= hg qnew -u blue red +cat ../.hg/patches/red
--- a/tests/test-mq-qnew.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-mq-qnew.out Sat Nov 07 14:13:15 2009 -0600 @@ -32,3 +32,6 @@ @@ -1,1 +1,2 @@ b +b +% qnew -u with no username configured +From: blue +
--- a/tests/test-patchbomb Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-patchbomb Sat Nov 07 14:13:15 2009 -0600 @@ -170,3 +170,10 @@ echo "% test multiple flags for multiple patches" hg email --date '1970-1-1 0:1' -n --flag fooFlag --flag barFlag -f quux -t foo \ -c bar -s test -r 0:1 | fixheaders + +echo "% test multi-byte domain parsing" +UUML=`printf '\374'` +export HGENCODING=iso-8859-1 +hg email --date '1980-1-1 0:1' -m tmp.mbox -f quux -t "bar@${UUML}nicode.com" \ + -s test -r 0 +cat tmp.mbox | fixheaders
--- a/tests/test-patchbomb.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-patchbomb.out Sat Nov 07 14:13:15 2009 -0600 @@ -1469,3 +1469,34 @@ @@ -0,0 +1,1 @@ +b +% test multi-byte domain parsing +This patch series consists of 1 patches. + + +Writing [PATCH] test ... +From quux Tue Jan 1 00:01:01 1980 +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [PATCH] test +X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab +Message-Id: <8580ff50825a50c8f716.315532860@ +User-Agent: Mercurial-patchbomb +Date: Tue, 01 Jan 1980 00:01:00 +0000 +From: quux +To: bar@xn--nicode-2ya.com + +# HG changeset patch +# User test +# Date 1 0 +# Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab +# Parent 0000000000000000000000000000000000000000 +a + +diff -r 000000000000 -r 8580ff50825a a +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/a Thu Jan 01 00:00:01 1970 +0000 +@@ -0,0 +1,1 @@ ++a + +
--- a/tests/test-repair-strip.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-repair-strip.out Sat Nov 07 14:13:15 2009 -0600 @@ -10,6 +10,7 @@ rollback failed - please run hg recover abort: Permission denied .hg/store/data/b.i % after update 0, strip 2 +abandoned transaction found - run hg recover checking changesets checking manifests crosschecking files in changesets and manifests @@ -59,6 +60,7 @@ rollback failed - please run hg recover abort: Permission denied .hg/store/00manifest.i % after update 0, strip 2 +abandoned transaction found - run hg recover checking changesets checking manifests manifest@?: rev 2 points to nonexistent changeset 2
--- a/tests/test-up-local-change.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-up-local-change.out Sat Nov 07 14:13:15 2009 -0600 @@ -111,7 +111,7 @@ date: Mon Jan 12 13:46:40 1970 +0000 summary: 2 -abort: crosses branches (use 'hg merge' or 'hg update -C' to discard changes) +abort: crosses branches (use 'hg merge' to merge or use 'hg update -C' to discard changes) failed abort: outstanding uncommitted changes (use 'hg status' to list changes) failed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-update-branches Sat Nov 07 14:13:15 2009 -0600 @@ -0,0 +1,81 @@ +#!/bin/sh + +# Construct the following history tree: +# +# @ 5:e1bb631146ca b1 +# | +# o 4:a4fdb3b883c4 0:b608b9236435 b1 +# | +# | o 3:4b57d2520816 1:44592833ba9f +# | | +# | | o 2:063f31070f65 +# | |/ +# | o 1:44592833ba9f +# |/ +# o 0:b608b9236435 + +hg init +echo foo > foo +echo zero > a +hg ci -qAm0 +echo one > a ; hg ci -m1 +echo two > a ; hg ci -m2 +hg up -q 1 +echo three > a ; hg ci -qm3 +hg up -q 0 +hg branch -q b1 +echo four > a ; hg ci -qm4 +echo five > a ; hg ci -qm5 + +echo % initial repo state +echo +hg --config 'extensions.graphlog=' \ + glog --template '{rev}:{node|short} {parents} {branches}\n' + +# Test helper functions. + +revtest () { + msg=$1 + dirtyflag=$2 # 'clean' or 'dirty' + startrev=$3 + targetrev=$4 + opt=$5 + echo % revtest $msg $startrev $targetrev + hg up -qC $startrev + test $dirtyflag = dirty && echo dirty > foo + hg up $opt $targetrev + hg parent --template 'parent={rev}\n' + hg stat +} + +norevtest () { + msg=$1 + dirtyflag=$2 # 'clean' or 'dirty' + startrev=$3 + opt=$4 + echo % norevtest $msg $startrev + hg up -qC $startrev + test $dirtyflag = dirty && echo dirty > foo + hg up $opt + hg parent --template 'parent={rev}\n' + hg stat +} + +# Test cases are documented in a table in the update function of merge.py. +# Cases are run as shown in that table, row by row. + +norevtest 'none clean linear' clean 4 +norevtest 'none clean same' clean 2 + +revtest 'none clean linear' clean 1 2 +revtest 'none clean same' clean 2 3 +revtest 'none clean cross' clean 3 4 + +revtest 'none dirty linear' dirty 1 2 +revtest 'none dirty same' dirty 2 3 +revtest 'none dirty cross' dirty 3 4 + +revtest '-C dirty linear' dirty 1 2 -C +revtest '-c dirty linear' dirty 1 2 -c +norevtest '-c clean same' clean 2 -c +revtest '-cC dirty linear' dirty 1 2 -cC
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-update-branches.out Sat Nov 07 14:13:15 2009 -0600 @@ -0,0 +1,55 @@ +% initial repo state + +@ 5:e1bb631146ca b1 +| +o 4:a4fdb3b883c4 0:b608b9236435 b1 +| +| o 3:4b57d2520816 1:44592833ba9f +| | +| | o 2:063f31070f65 +| |/ +| o 1:44592833ba9f +|/ +o 0:b608b9236435 + +% norevtest none clean linear 4 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +parent=5 +% norevtest none clean same 2 +abort: crosses branches (use 'hg merge' or use 'hg update -c') +parent=2 +% revtest none clean linear 1 2 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +parent=2 +% revtest none clean same 2 3 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +parent=3 +% revtest none clean cross 3 4 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +parent=4 +% revtest none dirty linear 1 2 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +parent=2 +M foo +% revtest none dirty same 2 3 +abort: crosses branches (use 'hg merge' to merge or use 'hg update -C' to discard changes) +parent=2 +M foo +% revtest none dirty cross 3 4 +abort: crosses branches (use 'hg merge' to merge or use 'hg update -C' to discard changes) +parent=3 +M foo +% revtest -C dirty linear 1 2 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved +parent=2 +% revtest -c dirty linear 1 2 +abort: uncommitted local changes +parent=1 +M foo +% norevtest -c clean same 2 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +parent=3 +% revtest -cC dirty linear 1 2 +abort: cannot specify both -c/--check and -C/--clean +parent=1 +M foo
--- a/tests/test-verify Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-verify Sat Nov 07 14:13:15 2009 -0600 @@ -14,6 +14,12 @@ hg verify echo +echo % verify with journal +touch .hg/store/journal +hg verify +rm .hg/store/journal + +echo echo % introduce some bugs in repo cd .hg/store/data mv _f_o_o.txt.i X_f_o_o.txt.i
--- a/tests/test-verify.out Wed Nov 04 22:14:26 2009 +0100 +++ b/tests/test-verify.out Sat Nov 07 14:13:15 2009 -0600 @@ -10,6 +10,14 @@ checking files 3 files, 1 changesets, 3 total revisions +% verify with journal +abandoned transaction found - run hg recover +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +3 files, 1 changesets, 3 total revisions + % introduce some bugs in repo % verify