Mercurial > hg
changeset 9440:cd67bfcfabbe
Merge qprev/qnext backout
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Mon, 14 Sep 2009 17:29:47 -0500 |
parents | b2f3b9c82ac0 (diff) f2acc0c00bec (current diff) |
children | bafde63c913a |
files | hgext/mq.py tests/test-mq.out |
diffstat | 73 files changed, 1848 insertions(+), 577 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/Makefile Mon Sep 14 16:39:24 2009 -0500 +++ b/doc/Makefile Mon Sep 14 17:29:47 2009 -0500 @@ -5,8 +5,7 @@ MANDIR=$(PREFIX)/share/man INSTALL=install -c -m 644 PYTHON=python -RST2HTML=rst2html -RST2MAN=rst2man +RST2HTML=$(shell which rst2html 2> /dev/null || which rst2html.py) all: man html @@ -21,17 +20,13 @@ ${PYTHON} gendoc.py > $@ %: %.txt common.txt - # add newline after all literal blocks and fix backslash escape - $(RST2MAN) $*.txt \ - | sed -e 's/^\.fi$$/.fi\n/' \ - | sed -e 's/\\fB\\\\fP/\\fB\\e\\fP/' \ - > $* + $(PYTHON) rst2man.py --strip-elements-with-class htmlonly $*.txt > $* %.html: %.txt common.txt $(RST2HTML) $*.txt > $*.html MANIFEST: man html - # tracked files are already in the main MANIFEST +# tracked files are already in the main MANIFEST $(RM) $@ for i in $(MAN) $(HTML) hg.1.gendoc.txt; do \ echo "doc/$$i" >> $@ ; \
--- a/doc/README Mon Sep 14 16:39:24 2009 -0500 +++ b/doc/README Mon Sep 14 17:29:47 2009 -0500 @@ -4,14 +4,8 @@ http://docutils.sourceforge.net/rst.html It's also convertible to a variety of other formats including standard -UNIX man page format and HTML. - -To do this, you'll need to install the rst2html and rst2man tools, -which are part of Docutils: +UNIX man page format and HTML. You'll need to install Docutils: http://docutils.sourceforge.net/ -The rst2man tool is still in their so-called "sandbox". The above page -has links to tarballs of both Docutils and their sandbox. - Use the Makefile in this directory to generate the man and HTML pages.
--- a/doc/hg.1.txt Mon Sep 14 16:39:24 2009 -0500 +++ b/doc/hg.1.txt Mon Sep 14 17:29:47 2009 -0500 @@ -11,6 +11,10 @@ :Manual section: 1 :Manual group: Mercurial Manual +.. contents:: + :backlinks: top + :class: htmlonly + SYNOPSIS --------
--- a/doc/hgrc.5.txt Mon Sep 14 16:39:24 2009 -0500 +++ b/doc/hgrc.5.txt Mon Sep 14 17:29:47 2009 -0500 @@ -11,6 +11,10 @@ :Manual section: 5 :Manual group: Mercurial Manual +.. contents:: + :backlinks: top + :class: htmlonly + SYNOPSIS -------- @@ -100,6 +104,15 @@ 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 +that included files can include other files. Filenames are relative to +the configuration file in which the ``%include`` directive is found. + +A line with "``%unset name``" will remove ``name`` from the current +section, if it has been set previously. + + SECTIONS --------
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/rst2man.py Mon Sep 14 17:29:47 2009 -0500 @@ -0,0 +1,1112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# $Id: manpage.py 6110 2009-08-31 14:40:33Z grubert $ +# Author: Engelbert Gruber <grubert@users.sourceforge.net> +# Copyright: This module is put into the public domain. + +""" +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: + + 1 executable programs and shell commands + 2 system calls + 3 library functions + 4 special files + 5 file formats + 6 games + 7 miscellaneous + 8 system administration + +Man pages are written *troff*, a text file formatting system. + +See http://www.tldp.org/HOWTO/Man-Page for a start. + +Man pages have no subsection only parts. +Standard parts + + NAME , + SYNOPSIS , + DESCRIPTION , + OPTIONS , + FILES , + SEE ALSO , + BUGS , + +and + + AUTHOR . + +A unix-like system keeps an index of the DESCRIPTIONs, which is accesable +by the command whatis or apropos. + +""" + +__docformat__ = 'reStructuredText' + +import sys +import os +import time +import re +from types import ListType + +import docutils +from docutils import nodes, utils, writers, languages +import roman + +FIELD_LIST_INDENT = 7 +DEFINITION_LIST_INDENT = 7 +OPTION_LIST_INDENT = 7 +BLOCKQOUTE_INDENT = 3.5 + +# Define two macros so man/roff can calculate the +# indent/unindent margins by itself +MACRO_DEF = (r""". +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +""") + +class Writer(writers.Writer): + + supported = ('manpage') + """Formats this writer supports.""" + + output = None + """Final translated form of `document`.""" + + def __init__(self): + writers.Writer.__init__(self) + self.translator_class = Translator + + def translate(self): + visitor = self.translator_class(self.document) + self.document.walkabout(visitor) + self.output = visitor.astext() + + +class Table: + def __init__(self): + self._rows = [] + self._options = ['center', ] + self._tab_char = '\t' + self._coldefs = [] + def new_row(self): + self._rows.append([]) + def append_separator(self, separator): + """Append the separator for table head.""" + self._rows.append([separator]) + def append_cell(self, cell_lines): + """cell_lines is an array of lines""" + start = 0 + if len(cell_lines)>0 and cell_lines[0] == '.sp\n': + start = 1 + self._rows[-1].append(cell_lines[start:]) + if len(self._coldefs) < len(self._rows[-1]): + self._coldefs.append('l') + def _minimize_cell(self, cell_lines): + """Remove leading and trailing blank and ``.sp`` lines""" + while (cell_lines and cell_lines[0] in ('\n', '.sp\n')): + del cell_lines[0] + while (cell_lines and cell_lines[-1] in ('\n', '.sp\n')): + del cell_lines[-1] + def as_list(self): + text = ['.TS\n'] + text.append(' '.join(self._options) + ';\n') + 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('T{\n') + for i in range(len(row)): + cell = row[i] + self._minimize_cell(cell) + text.extend(cell) + if not text[-1].endswith('\n'): + text[-1] += '\n' + if i < len(row)-1: + text.append('T}'+self._tab_char+'T{\n') + else: + text.append('T}\n') + text.append('_\n') + text.append('.TE\n') + return text + +class Translator(nodes.NodeVisitor): + """""" + + words_and_spaces = re.compile(r'\S+| +|\n') + document_start = """Man page generated from reStructeredText.""" + + def __init__(self, document): + nodes.NodeVisitor.__init__(self, document) + self.settings = settings = document.settings + lcode = settings.language_code + self.language = languages.get_language(lcode) + self.head = [] + self.body = [] + self.foot = [] + self.section_level = 0 + self.context = [] + self.topic_class = '' + self.colspecs = [] + self.compact_p = 1 + self.compact_simple = None + # the list style "*" bullet or "#" numbered + self._list_char = [] + # writing the header .TH and .SH NAME is postboned after + # docinfo. + self._docinfo = { + "title" : "", "title_upper": "", + "subtitle" : "", + "manual_section" : "", "manual_group" : "", + "author" : [], + "date" : "", + "copyright" : "", + "version" : "", + } + self._docinfo_keys = [] # a list to keep the sequence as in source. + self._docinfo_names = {} # to get name from text not normalized. + self._in_docinfo = None + self._active_table = None + self._in_literal = False + self.header_written = 0 + self._line_block = 0 + self.authors = [] + self.section_level = 0 + self._indent = [0] + # central definition of simple processing rules + # what to output on : visit, depart + # Do not use paragraph requests ``.PP`` because these set indentation. + # use ``.sp``. Remove superfluous ``.sp`` in ``astext``. + # + # Fonts are put on a stack, the top one is used. + # ``.ft P`` or ``\\fP`` pop from stack. + # ``B`` bold, ``I`` italic, ``R`` roman should be available. + # Hopefully ``C`` courier too. + self.defs = { + 'indent' : ('.INDENT %.1f\n', '.UNINDENT\n'), + 'definition_list_item' : ('.TP', ''), + 'field_name' : ('.TP\n.B ', '\n'), + 'literal' : ('\\fC', '\\fP'), + 'literal_block' : ('.sp\n.nf\n.ft C\n', '\n.ft P\n.fi\n'), + + 'option_list_item' : ('.TP\n', ''), + + 'reference' : (r'\fI\%', r'\fP'), + 'emphasis': ('\\fI', '\\fP'), + 'strong' : ('\\fB', '\\fP'), + 'term' : ('\n.B ', '\n'), + 'title_reference' : ('\\fI', '\\fP'), + + 'topic-title' : ('.SS ', ), + 'sidebar-title' : ('.SS ', ), + + 'problematic' : ('\n.nf\n', '\n.fi\n'), + } + # NOTE dont specify the newline before a dot-command, but ensure + # it is there. + + def comment_begin(self, text): + """Return commented version of the passed text WITHOUT end of + line/comment.""" + prefix = '.\\" ' + out_text = ''.join( + [(prefix + in_line + '\n') + for in_line in text.split('\n')]) + return out_text + + def comment(self, text): + """Return commented version of the passed text.""" + return self.comment_begin(text)+'.\n' + + def ensure_eol(self): + """Ensure the last line in body is terminated by new line.""" + if self.body[-1][-1] != '\n': + self.body.append('\n') + + def astext(self): + """Return the final formatted document as a string.""" + if not self.header_written: + # ensure we get a ".TH" as viewers require it. + self.head.append(self.header()) + # filter body + for i in xrange(len(self.body)-1,0,-1): + # remove superfluous vertical gaps. + if self.body[i] == '.sp\n': + if self.body[i-1][:4] in ('.BI ','.IP '): + self.body[i] = '.\n' + 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 + self.body[i-2][0] != '.' and + (self.body[i-3][:7] == '.TP\n.B ' + or self.body[i-3][:4] == '\n.B ') + ): + self.body[i] = '.\n' + return ''.join(self.head + self.body + self.foot) + + def deunicode(self, text): + text = text.replace(u'\xa0', '\\ ') + text = text.replace(u'\u2020', '\\(dg') + return text + + def visit_Text(self, node): + text = node.astext() + text = text.replace('\\','\\e') + replace_pairs = [ + (u'-', ur'\-'), + (u'\'', ur'\(aq'), + (u'ยด', ur'\''), + (u'`', ur'\(ga'), + ] + for (in_char, out_markup) in replace_pairs: + text = text.replace(in_char, out_markup) + # unicode + text = self.deunicode(text) + if self._in_literal: + # prevent interpretation of "." at line start + if text[0] == '.': + text = '\\&' + text + text = text.replace('\n.', '\n\\&.') + self.body.append(text) + + def depart_Text(self, node): + pass + + def list_start(self, node): + class enum_char: + enum_style = { + 'bullet' : '\\(bu', + 'emdash' : '\\(em', + } + + def __init__(self, style): + self._style = style + if node.has_key('start'): + self._cnt = node['start'] - 1 + else: + self._cnt = 0 + self._indent = 2 + if style == 'arabic': + # indentation depends on number of childrens + # and start value. + self._indent = len(str(len(node.children))) + self._indent += len(str(self._cnt)) + 1 + elif style == 'loweralpha': + self._cnt += ord('a') - 1 + self._indent = 3 + elif style == 'upperalpha': + self._cnt += ord('A') - 1 + self._indent = 3 + elif style.endswith('roman'): + self._indent = 5 + + def next(self): + if self._style == 'bullet': + return self.enum_style[self._style] + elif self._style == 'emdash': + return self.enum_style[self._style] + self._cnt += 1 + # TODO add prefix postfix + if self._style == 'arabic': + return "%d." % self._cnt + elif self._style in ('loweralpha', 'upperalpha'): + return "%c." % self._cnt + elif self._style.endswith('roman'): + res = roman.toRoman(self._cnt) + '.' + if self._style.startswith('upper'): + return res.upper() + return res.lower() + else: + return "%d." % self._cnt + def get_width(self): + return self._indent + def __repr__(self): + return 'enum_style-%s' % list(self._style) + + if node.has_key('enumtype'): + self._list_char.append(enum_char(node['enumtype'])) + else: + self._list_char.append(enum_char('bullet')) + if len(self._list_char) > 1: + # indent nested lists + self.indent(self._list_char[-2].get_width()) + else: + self.indent(self._list_char[-1].get_width()) + + def list_end(self): + self.dedent() + self._list_char.pop() + + def header(self): + tmpl = (".TH %(title_upper)s %(manual_section)s" + " \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n" + ".SH NAME\n" + "%(title)s \- %(subtitle)s\n") + return tmpl % self._docinfo + + def append_header(self): + """append header with .TH and .SH NAME""" + # NOTE before everything + # .TH title_upper section date source manual + if self.header_written: + return + self.body.append(self.header()) + self.body.append(MACRO_DEF) + self.header_written = 1 + + def visit_address(self, node): + self.visit_docinfo_item(node, 'address') + + def depart_address(self, node): + pass + + def visit_admonition(self, node, name=None): + if name: + self.body.append('.IP %s\n' % + self.language.labels.get(name, name)) + + def depart_admonition(self, node): + self.body.append('.RE\n') + + def visit_attention(self, node): + self.visit_admonition(node, 'attention') + + depart_attention = depart_admonition + + def visit_docinfo_item(self, node, name): + if name == 'author': + self._docinfo[name].append(node.astext()) + else: + self._docinfo[name] = node.astext() + self._docinfo_keys.append(name) + raise nodes.SkipNode + + def depart_docinfo_item(self, node): + pass + + def visit_author(self, node): + self.visit_docinfo_item(node, 'author') + + depart_author = depart_docinfo_item + + def visit_authors(self, node): + # _author is called anyway. + pass + + def depart_authors(self, node): + pass + + def visit_block_quote(self, node): + # BUG/HACK: indent alway uses the _last_ indention, + # thus we need two of them. + self.indent(BLOCKQOUTE_INDENT) + self.indent(0) + + def depart_block_quote(self, node): + self.dedent() + self.dedent() + + def visit_bullet_list(self, node): + self.list_start(node) + + def depart_bullet_list(self, node): + self.list_end() + + def visit_caption(self, node): + pass + + def depart_caption(self, node): + pass + + def visit_caution(self, node): + self.visit_admonition(node, 'caution') + + depart_caution = depart_admonition + + def visit_citation(self, node): + num,text = node.astext().split(None,1) + num = num.strip() + self.body.append('.IP [%s] 5\n' % num) + + def depart_citation(self, node): + pass + + def visit_citation_reference(self, node): + self.body.append('['+node.astext()+']') + raise nodes.SkipNode + + def visit_classifier(self, node): + pass + + def depart_classifier(self, node): + pass + + def visit_colspec(self, node): + self.colspecs.append(node) + + def depart_colspec(self, node): + pass + + def write_colspecs(self): + self.body.append("%s.\n" % ('L '*len(self.colspecs))) + + def visit_comment(self, node, + sub=re.compile('-(?=-)').sub): + self.body.append(self.comment(node.astext())) + raise nodes.SkipNode + + def visit_contact(self, node): + self.visit_docinfo_item(node, 'contact') + + depart_contact = depart_docinfo_item + + def visit_container(self, node): + pass + + def depart_container(self, node): + pass + + def visit_compound(self, node): + pass + + def depart_compound(self, node): + pass + + def visit_copyright(self, node): + self.visit_docinfo_item(node, 'copyright') + + def visit_danger(self, node): + self.visit_admonition(node, 'danger') + + depart_danger = depart_admonition + + def visit_date(self, node): + self.visit_docinfo_item(node, 'date') + + def visit_decoration(self, node): + pass + + def depart_decoration(self, node): + pass + + def visit_definition(self, node): + pass + + def depart_definition(self, node): + pass + + def visit_definition_list(self, node): + self.indent(DEFINITION_LIST_INDENT) + + def depart_definition_list(self, node): + self.dedent() + + def visit_definition_list_item(self, node): + self.body.append(self.defs['definition_list_item'][0]) + + def depart_definition_list_item(self, node): + self.body.append(self.defs['definition_list_item'][1]) + + def visit_description(self, node): + pass + + def depart_description(self, node): + pass + + def visit_docinfo(self, node): + self._in_docinfo = 1 + + def depart_docinfo(self, node): + self._in_docinfo = None + # NOTE nothing should be written before this + self.append_header() + + def visit_doctest_block(self, node): + self.body.append(self.defs['literal_block'][0]) + self._in_literal = True + + def depart_doctest_block(self, node): + self._in_literal = False + self.body.append(self.defs['literal_block'][1]) + + def visit_document(self, node): + # no blank line between comment and header. + self.body.append(self.comment(self.document_start).rstrip()+'\n') + # writing header is postboned + self.header_written = 0 + + def depart_document(self, node): + if self._docinfo['author']: + self.body.append('.SH AUTHOR\n%s\n' + % ', '.join(self._docinfo['author'])) + skip = ('author', 'copyright', 'date', + 'manual_group', 'manual_section', + 'subtitle', + 'title', 'title_upper', 'version') + for name in self._docinfo_keys: + if name == 'address': + self.body.append("\n%s:\n%s%s.nf\n%s\n.fi\n%s%s" % ( + self.language.labels.get(name, name), + self.defs['indent'][0] % 0, + self.defs['indent'][0] % BLOCKQOUTE_INDENT, + self._docinfo[name], + self.defs['indent'][1], + self.defs['indent'][1], + ) ) + elif not name in skip: + if name in self._docinfo_names: + label = self._docinfo_names[name] + else: + 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._docinfo['copyright']) + self.body.append( self.comment( + 'Generated by docutils manpage writer.\n' ) ) + + def visit_emphasis(self, node): + self.body.append(self.defs['emphasis'][0]) + + def depart_emphasis(self, node): + self.body.append(self.defs['emphasis'][1]) + + def visit_entry(self, node): + # a cell in a table row + if 'morerows' in node: + self.document.reporter.warning('"table row spanning" not supported', + base_node=node) + if 'morecols' in node: + self.document.reporter.warning( + '"table cell spanning" not supported', base_node=node) + self.context.append(len(self.body)) + + def depart_entry(self, node): + start = self.context.pop() + self._active_table.append_cell(self.body[start:]) + del self.body[start:] + + def visit_enumerated_list(self, node): + self.list_start(node) + + def depart_enumerated_list(self, node): + self.list_end() + + def visit_error(self, node): + self.visit_admonition(node, 'error') + + depart_error = depart_admonition + + def visit_field(self, node): + pass + + def depart_field(self, node): + pass + + def visit_field_body(self, node): + if self._in_docinfo: + name_normalized = self._field_name.lower().replace(" ","_") + self._docinfo_names[name_normalized] = self._field_name + self.visit_docinfo_item(node, name_normalized) + raise nodes.SkipNode + + def depart_field_body(self, node): + pass + + def visit_field_list(self, node): + self.indent(FIELD_LIST_INDENT) + + def depart_field_list(self, node): + self.dedent() + + def visit_field_name(self, node): + if self._in_docinfo: + self._field_name = node.astext() + raise nodes.SkipNode + else: + self.body.append(self.defs['field_name'][0]) + + def depart_field_name(self, node): + self.body.append(self.defs['field_name'][1]) + + def visit_figure(self, node): + self.indent(2.5) + self.indent(0) + + def depart_figure(self, node): + self.dedent() + self.dedent() + + def visit_footer(self, node): + self.document.reporter.warning('"footer" not supported', + base_node=node) + + def depart_footer(self, node): + pass + + def visit_footnote(self, node): + num,text = node.astext().split(None,1) + num = num.strip() + self.body.append('.IP [%s] 5\n' % self.deunicode(num)) + + def depart_footnote(self, node): + pass + + def footnote_backrefs(self, node): + self.document.reporter.warning('"footnote_backrefs" not supported', + base_node=node) + + def visit_footnote_reference(self, node): + self.body.append('['+self.deunicode(node.astext())+']') + raise nodes.SkipNode + + def depart_footnote_reference(self, node): + pass + + def visit_generated(self, node): + pass + + def depart_generated(self, node): + pass + + def visit_header(self, node): + raise NotImplementedError, node.astext() + + def depart_header(self, node): + pass + + def visit_hint(self, node): + self.visit_admonition(node, 'hint') + + depart_hint = depart_admonition + + def visit_subscript(self, node): + self.body.append('\\s-2\\d') + + def depart_subscript(self, node): + self.body.append('\\u\\s0') + + def visit_superscript(self, node): + self.body.append('\\s-2\\u') + + def depart_superscript(self, node): + self.body.append('\\d\\s0') + + def visit_attribution(self, node): + self.body.append('\\(em ') + + def depart_attribution(self, node): + self.body.append('\n') + + def visit_image(self, node): + self.document.reporter.warning('"image" not supported', + base_node=node) + text = [] + if 'alt' in node.attributes: + text.append(node.attributes['alt']) + if 'uri' in node.attributes: + text.append(node.attributes['uri']) + self.body.append('[image: %s]\n' % ('/'.join(text))) + raise nodes.SkipNode + + def visit_important(self, node): + self.visit_admonition(node, 'important') + + depart_important = depart_admonition + + def visit_label(self, node): + # footnote and citation + if (isinstance(node.parent, nodes.footnote) + or isinstance(node.parent, nodes.citation)): + raise nodes.SkipNode + self.document.reporter.warning('"unsupported "label"', + base_node=node) + self.body.append('[') + + def depart_label(self, node): + self.body.append(']\n') + + def visit_legend(self, node): + pass + + def depart_legend(self, node): + pass + + # WHAT should we use .INDENT, .UNINDENT ? + def visit_line_block(self, node): + self._line_block += 1 + if self._line_block == 1: + self.body.append('.nf\n') + else: + self.body.append('.in +2\n') + + def depart_line_block(self, node): + self._line_block -= 1 + if self._line_block == 0: + self.body.append('.fi\n') + self.body.append('.sp\n') + else: + self.body.append('.in -2\n') + + def visit_line(self, node): + pass + + def depart_line(self, node): + self.body.append('\n') + + def visit_list_item(self, node): + # man 7 man argues to use ".IP" instead of ".TP" + self.body.append('.IP %s %d\n' % ( + self._list_char[-1].next(), + self._list_char[-1].get_width(),) ) + + def depart_list_item(self, node): + pass + + def visit_literal(self, node): + self.body.append(self.defs['literal'][0]) + + def depart_literal(self, node): + self.body.append(self.defs['literal'][1]) + + def visit_literal_block(self, node): + self.body.append(self.defs['literal_block'][0]) + self._in_literal = True + + def depart_literal_block(self, node): + self._in_literal = False + self.body.append(self.defs['literal_block'][1]) + + def visit_meta(self, node): + raise NotImplementedError, node.astext() + + def depart_meta(self, node): + pass + + def visit_note(self, node): + self.visit_admonition(node, 'note') + + depart_note = depart_admonition + + def indent(self, by=0.5): + # if we are in a section ".SH" there already is a .RS + step = self._indent[-1] + self._indent.append(by) + self.body.append(self.defs['indent'][0] % step) + + def dedent(self): + self._indent.pop() + self.body.append(self.defs['indent'][1]) + + def visit_option_list(self, node): + self.indent(OPTION_LIST_INDENT) + + def depart_option_list(self, node): + self.dedent() + + def visit_option_list_item(self, node): + # one item of the list + self.body.append(self.defs['option_list_item'][0]) + + def depart_option_list_item(self, node): + self.body.append(self.defs['option_list_item'][1]) + + def visit_option_group(self, node): + # as one option could have several forms it is a group + # options without parameter bold only, .B, -v + # options with parameter bold italic, .BI, -f file + # + # we do not know if .B or .BI + self.context.append('.B') # blind guess + self.context.append(len(self.body)) # to be able to insert later + self.context.append(0) # option counter + + def depart_option_group(self, node): + self.context.pop() # the counter + start_position = self.context.pop() + text = self.body[start_position:] + del self.body[start_position:] + self.body.append('%s%s\n' % (self.context.pop(), ''.join(text))) + + def visit_option(self, node): + # each form of the option will be presented separately + if self.context[-1]>0: + self.body.append(', ') + if self.context[-3] == '.BI': + self.body.append('\\') + self.body.append(' ') + + def depart_option(self, node): + self.context[-1] += 1 + + def visit_option_string(self, node): + # do not know if .B or .BI + pass + + def depart_option_string(self, node): + pass + + def visit_option_argument(self, node): + self.context[-3] = '.BI' # bold/italic alternate + if node['delimiter'] != ' ': + self.body.append('\\fB%s ' % node['delimiter'] ) + elif self.body[len(self.body)-1].endswith('='): + # a blank only means no blank in output, just changing font + self.body.append(' ') + else: + # blank backslash blank, switch font then a blank + self.body.append(' \\ ') + + def depart_option_argument(self, node): + pass + + def visit_organization(self, node): + self.visit_docinfo_item(node, 'organization') + + def depart_organization(self, node): + pass + + def visit_paragraph(self, node): + # ``.PP`` : Start standard indented paragraph. + # ``.LP`` : Start block paragraph, all except the first. + # ``.P [type]`` : Start paragraph type. + # NOTE dont use paragraph starts because they reset indentation. + # ``.sp`` is only vertical space + self.ensure_eol() + self.body.append('.sp\n') + + def depart_paragraph(self, node): + self.body.append('\n') + + def visit_problematic(self, node): + self.body.append(self.defs['problematic'][0]) + + def depart_problematic(self, node): + self.body.append(self.defs['problematic'][1]) + + def visit_raw(self, node): + if node.get('format') == 'manpage': + self.body.append(node.astext() + "\n") + # Keep non-manpage raw text out of output: + raise nodes.SkipNode + + def visit_reference(self, node): + """E.g. link or email address.""" + self.body.append(self.defs['reference'][0]) + + def depart_reference(self, node): + self.body.append(self.defs['reference'][1]) + + def visit_revision(self, node): + self.visit_docinfo_item(node, 'revision') + + depart_revision = depart_docinfo_item + + def visit_row(self, node): + self._active_table.new_row() + + def depart_row(self, node): + pass + + def visit_section(self, node): + self.section_level += 1 + + def depart_section(self, node): + self.section_level -= 1 + + def visit_status(self, node): + self.visit_docinfo_item(node, 'status') + + depart_status = depart_docinfo_item + + def visit_strong(self, node): + self.body.append(self.defs['strong'][0]) + + def depart_strong(self, node): + self.body.append(self.defs['strong'][1]) + + def visit_substitution_definition(self, node): + """Internal only.""" + raise nodes.SkipNode + + def visit_substitution_reference(self, node): + self.document.reporter.warning('"substitution_reference" not supported', + base_node=node) + + def visit_subtitle(self, node): + if isinstance(node.parent, nodes.sidebar): + self.body.append(self.defs['strong'][0]) + elif isinstance(node.parent, nodes.document): + self.visit_docinfo_item(node, 'subtitle') + elif isinstance(node.parent, nodes.section): + self.body.append(self.defs['strong'][0]) + + def depart_subtitle(self, node): + # document subtitle calls SkipNode + self.body.append(self.defs['strong'][1]+'\n.PP\n') + + def visit_system_message(self, node): + # TODO add report_level + #if node['level'] < self.document.reporter['writer'].report_level: + # Level is too low to display: + # raise nodes.SkipNode + attr = {} + backref_text = '' + if node.hasattr('id'): + attr['name'] = node['id'] + if node.hasattr('line'): + line = ', line %s' % node['line'] + else: + line = '' + self.body.append('.IP "System Message: %s/%s (%s:%s)"\n' + % (node['type'], node['level'], node['source'], line)) + + def depart_system_message(self, node): + pass + + def visit_table(self, node): + self._active_table = Table() + + def depart_table(self, node): + self.ensure_eol() + self.body.extend(self._active_table.as_list()) + self._active_table = None + + def visit_target(self, node): + # targets are in-document hyper targets, without any use for man-pages. + raise nodes.SkipNode + + def visit_tbody(self, node): + pass + + def depart_tbody(self, node): + pass + + def visit_term(self, node): + self.body.append(self.defs['term'][0]) + + def depart_term(self, node): + self.body.append(self.defs['term'][1]) + + def visit_tgroup(self, node): + pass + + def depart_tgroup(self, node): + pass + + def visit_thead(self, node): + # MAYBE double line '=' + pass + + def depart_thead(self, node): + # MAYBE double line '=' + pass + + def visit_tip(self, node): + self.visit_admonition(node, 'tip') + + depart_tip = depart_admonition + + def visit_title(self, node): + if isinstance(node.parent, nodes.topic): + self.body.append(self.defs['topic-title'][0]) + elif isinstance(node.parent, nodes.sidebar): + self.body.append(self.defs['sidebar-title'][0]) + elif isinstance(node.parent, nodes.admonition): + self.body.append('.IP "') + elif self.section_level == 0: + self._docinfo['title'] = node.astext() + # document title for .TH + self._docinfo['title_upper'] = node.astext().upper() + raise nodes.SkipNode + elif self.section_level == 1: + self.body.append('.SH ') + else: + self.body.append('.SS ') + + def depart_title(self, node): + if isinstance(node.parent, nodes.admonition): + self.body.append('"') + self.body.append('\n') + + def visit_title_reference(self, node): + """inline citation reference""" + self.body.append(self.defs['title_reference'][0]) + + def depart_title_reference(self, node): + self.body.append(self.defs['title_reference'][1]) + + def visit_topic(self, node): + pass + + def depart_topic(self, node): + pass + + def visit_sidebar(self, node): + pass + + def depart_sidebar(self, node): + pass + + def visit_rubric(self, node): + pass + + def depart_rubric(self, node): + pass + + def visit_transition(self, node): + # .PP Begin a new paragraph and reset prevailing indent. + # .sp N leaves N lines of blank space. + # .ce centers the next line + self.body.append('\n.sp\n.ce\n----\n') + + def depart_transition(self, node): + self.body.append('\n.ce 0\n.sp\n') + + def visit_version(self, node): + self.visit_docinfo_item(node, 'version') + + def visit_warning(self, node): + self.visit_admonition(node, 'warning') + + depart_warning = depart_admonition + + def unimplemented_visit(self, node): + raise NotImplementedError('visiting unimplemented node type: %s' + % node.__class__.__name__) + +# The following part is taken from the Docutils rst2man.py script: +if __name__ == "__main__": + from docutils.core import publish_cmdline, default_description + description = ("Generates plain unix manual documents. " + + default_description) + publish_cmdline(writer=Writer(), description=description) + +# vim: set fileencoding=utf-8 et ts=4 ai :
--- a/hgext/churn.py Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/churn.py Mon Sep 14 17:29:47 2009 -0500 @@ -53,15 +53,17 @@ if opts.get('date'): df = util.matchdate(opts['date']) - get = util.cachefunc(lambda r: repo[r].changeset()) + get = util.cachefunc(lambda r: repo[r]) changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts) for st, rev, fns in changeiter: + if not st == 'add': continue - if df and not df(get(rev)[2][0]): # doesn't match date format + + ctx = get(rev) + if df and not df(ctx.date()[0]): # doesn't match date format continue - ctx = repo[rev] key = getkey(ctx) key = amap.get(key, key) # alias remap if opts.get('changesets'): @@ -146,8 +148,9 @@ sortkey = ((not opts.get('sort')) and (lambda x: -x[1]) or None) rate.sort(key=sortkey) - maxcount = float(max([v for k, v in rate])) - maxname = max([len(k) for k, v in rate]) + # Be careful not to have a zero maxcount (issue833) + maxcount = float(max(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)
--- a/hgext/color.py Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/color.py Mon Sep 14 17:29:47 2009 -0500 @@ -59,7 +59,6 @@ ''' import os, sys -import itertools from mercurial import cmdutil, commands, extensions, error from mercurial.i18n import _ @@ -146,7 +145,7 @@ patchlines = ui.popbuffer().splitlines() patchnames = repo.mq.series - for patch, patchname in itertools.izip(patchlines, patchnames): + for patch, patchname in zip(patchlines, patchnames): if opts['missing']: effects = _patch_effects['missing'] # Determine if patch is applied. @@ -219,12 +218,8 @@ 'changed': ['white'], 'trailingwhitespace': ['bold', 'red_background']} -_ui = None - def uisetup(ui): '''Initialize the extension.''' - global _ui - _ui = ui _setupcmd(ui, 'diff', commands.table, colordiff, _diff_effects) _setupcmd(ui, 'incoming', commands.table, None, _diff_effects) _setupcmd(ui, 'log', commands.table, None, _diff_effects) @@ -232,17 +227,10 @@ _setupcmd(ui, 'tip', commands.table, None, _diff_effects) _setupcmd(ui, 'status', commands.table, colorstatus, _status_effects) -def extsetup(): try: mq = extensions.find('mq') - try: - # If we are loaded after mq, we must wrap commands.table - _setupcmd(_ui, 'qdiff', commands.table, colordiff, _diff_effects) - _setupcmd(_ui, 'qseries', commands.table, colorqseries, _patch_effects) - except error.UnknownCommand: - # Otherwise we wrap mq.cmdtable - _setupcmd(_ui, 'qdiff', mq.cmdtable, colordiff, _diff_effects) - _setupcmd(_ui, 'qseries', mq.cmdtable, colorqseries, _patch_effects) + _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
--- a/hgext/convert/common.py Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/convert/common.py Mon Sep 14 17:29:47 2009 -0500 @@ -203,6 +203,8 @@ """Put tags into sink. tags: {tagname: sink_rev_id, ...} where tagname is an UTF-8 string. + Return a pair (tag_revision, tag_parent_revision), or (None, None) + if nothing was changed. """ raise NotImplementedError()
--- a/hgext/convert/convcmd.py Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/convert/convcmd.py Mon Sep 14 17:29:47 2009 -0500 @@ -336,11 +336,14 @@ ctags[k] = self.map[v] if c and ctags: - nrev = self.dest.puttags(ctags) - # write another hash correspondence to override the previous - # one so we don't end up with extra tag heads - if nrev: - self.map[c] = nrev + nrev, tagsparent = self.dest.puttags(ctags) + if nrev and tagsparent: + # write another hash correspondence to override the previous + # one so we don't end up with extra tag heads + tagsparents = [e for e in self.map.iteritems() + if e[1] == tagsparent] + if tagsparents: + self.map[tagsparents[0][0]] = nrev self.writeauthormap() finally:
--- a/hgext/convert/gnuarch.py Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/convert/gnuarch.py Mon Sep 14 17:29:47 2009 -0500 @@ -284,7 +284,7 @@ self.changes[rev].summary = self.recode(self.changes[rev].summary) # Commit revision origin when dealing with a branch or tag - if catlog.has_key('Continuation-of'): + if 'Continuation-of' in catlog: self.changes[rev].continuationof = self.recode(catlog['Continuation-of']) except Exception: raise util.Abort(_('could not parse cat-log of %s') % rev)
--- a/hgext/convert/hg.py Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/convert/hg.py Mon Sep 14 17:29:47 2009 -0500 @@ -189,7 +189,7 @@ newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags]) if newlines == oldlines: - return None + return None, None data = "".join(newlines) def getfilectx(repo, memctx, f): return context.memfilectx(f, data, False, False, None) @@ -201,7 +201,7 @@ [".hgtags"], getfilectx, "convert-repo", date, extra) self.repo.commitctx(ctx) - return hex(self.repo.changelog.tip()) + return hex(self.repo.changelog.tip()), hex(tagparent) def setfilemapmode(self, active): self.filemapmode = active
--- a/hgext/graphlog.py Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/graphlog.py Mon Sep 14 17:29:47 2009 -0500 @@ -22,48 +22,31 @@ ASCIIDATA = 'ASC' -def asciiformat(ui, repo, revdag, opts, parentrepo=None): - """formats a changelog DAG walk for ASCII output""" - if parentrepo is None: - parentrepo = repo - showparents = [ctx.node() for ctx in parentrepo[None].parents()] - displayer = show_changeset(ui, repo, opts, buffered=True) - for (id, type, ctx, parentids) in revdag: - if type != graphmod.CHANGESET: - continue - displayer.show(ctx) - lines = displayer.hunk.pop(ctx.rev()).split('\n')[:-1] - char = ctx.node() in showparents and '@' or 'o' - yield (id, ASCIIDATA, (char, lines), parentids) - -def asciiedges(nodes): +def asciiedges(seen, rev, parents): """adds edge info to changelog DAG walk suitable for ascii()""" - seen = [] - for node, type, data, parents in nodes: - if node not in seen: - seen.append(node) - nodeidx = seen.index(node) + if rev not in seen: + seen.append(rev) + nodeidx = seen.index(rev) + + knownparents = [] + newparents = [] + for parent in parents: + if parent in seen: + knownparents.append(parent) + else: + newparents.append(parent) - knownparents = [] - newparents = [] - for parent in parents: - if parent in seen: - knownparents.append(parent) - else: - newparents.append(parent) + ncols = len(seen) + seen[nodeidx:nodeidx + 1] = newparents + edges = [(nodeidx, seen.index(p)) for p in knownparents] - ncols = len(seen) - nextseen = seen[:] - nextseen[nodeidx:nodeidx + 1] = newparents - edges = [(nodeidx, nextseen.index(p)) for p in knownparents] + if len(newparents) > 0: + edges.append((nodeidx, nodeidx)) + if len(newparents) > 1: + edges.append((nodeidx, nodeidx + 1)) - if len(newparents) > 0: - edges.append((nodeidx, nodeidx)) - if len(newparents) > 1: - edges.append((nodeidx, nodeidx + 1)) - nmorecols = len(nextseen) - ncols - seen = nextseen - yield (nodeidx, type, data, edges, ncols, nmorecols) + nmorecols = len(seen) - ncols + return nodeidx, edges, ncols, nmorecols def fix_long_right_edges(edges): for (i, (start, end)) in enumerate(edges): @@ -117,11 +100,13 @@ line.extend(["|", " "] * (n_columns - ni - 1)) return line -def ascii(ui, dag): +def ascii(ui, base, type, char, text, coldata): """prints an ASCII graph of the DAG - dag is a generator that emits tuples with the following elements: + takes the following arguments (one call per node in the graph): + - ui to write to + - A list we can keep the needed state in - Column of the current node in the set of ongoing edges. - Type indicator of node data == ASCIIDATA. - Payload: (char, lines): @@ -135,91 +120,87 @@ in the current revision. That is: -1 means one column removed; 0 means no columns added or removed; 1 means one column added. """ - prev_n_columns_diff = 0 - prev_node_index = 0 - for (node_index, type, (node_ch, node_lines), edges, n_columns, n_columns_diff) in dag: - assert -2 < n_columns_diff < 2 - if n_columns_diff == -1: - # Transform - # - # | | | | | | - # o | | into o---+ - # |X / |/ / - # | | | | - fix_long_right_edges(edges) - - # add_padding_line says whether to rewrite + idx, edges, ncols, coldiff = coldata + assert -2 < coldiff < 2 + if coldiff == -1: + # Transform # - # | | | | | | | | - # | o---+ into | o---+ - # | / / | | | # <--- padding line - # o | | | / / - # o | | - add_padding_line = (len(node_lines) > 2 and - n_columns_diff == -1 and - [x for (x, y) in edges if x + 1 < y]) + # | | | | | | + # o | | into o---+ + # |X / |/ / + # | | | | + fix_long_right_edges(edges) + + # add_padding_line says whether to rewrite + # + # | | | | | | | | + # | o---+ into | o---+ + # | / / | | | # <--- padding line + # o | | | / / + # o | | + add_padding_line = (len(text) > 2 and coldiff == -1 and + [x for (x, y) in edges if x + 1 < y]) - # fix_nodeline_tail says whether to rewrite - # - # | | o | | | | o | | - # | | |/ / | | |/ / - # | o | | into | o / / # <--- fixed nodeline tail - # | |/ / | |/ / - # o | | o | | - fix_nodeline_tail = len(node_lines) <= 2 and not add_padding_line + # fix_nodeline_tail says whether to rewrite + # + # | | o | | | | o | | + # | | |/ / | | |/ / + # | o | | into | o / / # <--- fixed nodeline tail + # | |/ / | |/ / + # o | | o | | + fix_nodeline_tail = len(text) <= 2 and not add_padding_line - # nodeline is the line containing the node character (typically o) - nodeline = ["|", " "] * node_index - nodeline.extend([node_ch, " "]) + # nodeline is the line containing the node character (typically o) + nodeline = ["|", " "] * idx + nodeline.extend([char, " "]) - nodeline.extend( - get_nodeline_edges_tail( - node_index, prev_node_index, n_columns, n_columns_diff, - prev_n_columns_diff, fix_nodeline_tail)) + nodeline.extend( + get_nodeline_edges_tail(idx, base[1], ncols, coldiff, + base[0], fix_nodeline_tail)) - # shift_interline is the line containing the non-vertical - # edges between this entry and the next - shift_interline = ["|", " "] * node_index - if n_columns_diff == -1: - n_spaces = 1 - edge_ch = "/" - elif n_columns_diff == 0: - n_spaces = 2 - edge_ch = "|" - else: - n_spaces = 3 - edge_ch = "\\" - shift_interline.extend(n_spaces * [" "]) - shift_interline.extend([edge_ch, " "] * (n_columns - node_index - 1)) + # shift_interline is the line containing the non-vertical + # edges between this entry and the next + shift_interline = ["|", " "] * idx + if coldiff == -1: + n_spaces = 1 + edge_ch = "/" + elif coldiff == 0: + n_spaces = 2 + edge_ch = "|" + else: + n_spaces = 3 + edge_ch = "\\" + shift_interline.extend(n_spaces * [" "]) + shift_interline.extend([edge_ch, " "] * (ncols - idx - 1)) - # draw edges from the current node to its parents - draw_edges(edges, nodeline, shift_interline) + # draw edges from the current node to its parents + draw_edges(edges, nodeline, shift_interline) - # lines is the list of all graph lines to print - lines = [nodeline] - if add_padding_line: - lines.append(get_padding_line(node_index, n_columns, edges)) - lines.append(shift_interline) + # lines is the list of all graph lines to print + lines = [nodeline] + if add_padding_line: + lines.append(get_padding_line(idx, ncols, edges)) + lines.append(shift_interline) - # make sure that there are as many graph lines as there are - # log strings - while len(node_lines) < len(lines): - node_lines.append("") - if len(lines) < len(node_lines): - extra_interline = ["|", " "] * (n_columns + n_columns_diff) - while len(lines) < len(node_lines): - lines.append(extra_interline) + # make sure that there are as many graph lines as there are + # log strings + while len(text) < len(lines): + text.append("") + if len(lines) < len(text): + extra_interline = ["|", " "] * (ncols + coldiff) + while len(lines) < len(text): + lines.append(extra_interline) - # print lines - indentation_level = max(n_columns, n_columns + n_columns_diff) - for (line, logstr) in zip(lines, node_lines): - ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr) - ui.write(ln.rstrip() + '\n') + # print lines + indentation_level = max(ncols, ncols + coldiff) + for (line, logstr) in zip(lines, text): + ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr) + ui.write(ln.rstrip() + '\n') - # ... and start over - prev_node_index = node_index - prev_n_columns_diff = n_columns_diff + # ... and start over + base[0] = coldiff + base[1] = idx def get_revs(repo, rev_opt): if rev_opt: @@ -235,6 +216,14 @@ if op in opts and opts[op]: raise util.Abort(_("--graph option is incompatible with --%s") % op) +def generate(ui, dag, displayer, showparents, edgefn): + seen, base = [], [0, 0] + for rev, type, ctx, parents in dag: + char = ctx.node() in showparents and '@' or 'o' + displayer.show(ctx) + lines = displayer.hunk.pop(rev).split('\n')[:-1] + ascii(ui, base, type, char, lines, edgefn(seen, rev, parents)) + def graphlog(ui, repo, path=None, **opts): """show revision history alongside an ASCII revision graph @@ -259,8 +248,9 @@ else: revdag = graphmod.revisions(repo, start, stop) - fmtdag = asciiformat(ui, repo, revdag, opts) - ascii(ui, asciiedges(fmtdag)) + displayer = show_changeset(ui, repo, opts, buffered=True) + showparents = [ctx.node() for ctx in repo[None].parents()] + generate(ui, revdag, displayer, showparents, asciiedges) def graphrevs(repo, nodes, opts): limit = cmdutil.loglimit(opts) @@ -294,8 +284,9 @@ o = repo.changelog.nodesbetween(o, revs)[0] revdag = graphrevs(repo, o, opts) - fmtdag = asciiformat(ui, repo, revdag, opts) - ascii(ui, asciiedges(fmtdag)) + displayer = show_changeset(ui, repo, opts, buffered=True) + showparents = [ctx.node() for ctx in repo[None].parents()] + generate(ui, revdag, displayer, showparents, asciiedges) def gincoming(ui, repo, source="default", **opts): """show the incoming changesets alongside an ASCII revision graph @@ -343,8 +334,9 @@ chlist = other.changelog.nodesbetween(incoming, revs)[0] revdag = graphrevs(other, chlist, opts) - fmtdag = asciiformat(ui, other, revdag, opts, parentrepo=repo) - ascii(ui, asciiedges(fmtdag)) + displayer = show_changeset(ui, other, opts, buffered=True) + showparents = [ctx.node() for ctx in repo[None].parents()] + generate(ui, revdag, displayer, showparents, asciiedges) finally: if hasattr(other, 'close'):
--- a/hgext/highlight/__init__.py Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/highlight/__init__.py Mon Sep 14 17:29:47 2009 -0500 @@ -53,8 +53,9 @@ req.respond(common.HTTP_OK, 'text/css') return ['/* pygments_style = %s */\n\n' % pg_style, fmter.get_style_defs('')] -# monkeypatch in the new version -extensions.wrapfunction(webcommands, '_filerevision', filerevision_highlight) -extensions.wrapfunction(webcommands, 'annotate', annotate_highlight) -webcommands.highlightcss = generate_css -webcommands.__all__.append('highlightcss') +def extsetup(): + # monkeypatch in the new version + extensions.wrapfunction(webcommands, '_filerevision', filerevision_highlight) + extensions.wrapfunction(webcommands, 'annotate', annotate_highlight) + webcommands.highlightcss = generate_css + webcommands.__all__.append('highlightcss')
--- a/hgext/highlight/highlight.py Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/highlight/highlight.py Mon Sep 14 17:29:47 2009 -0500 @@ -32,26 +32,27 @@ if util.binary(text): return - # avoid UnicodeDecodeError in pygments - text = encoding.tolocal(text) + # Pygments is best used with Unicode strings: + # <http://pygments.org/docs/unicode/> + text = text.decode(encoding.encoding, 'replace') # To get multi-line strings right, we can't format line-by-line try: - lexer = guess_lexer_for_filename(fctx.path(), text[:1024], - encoding=encoding.encoding) + lexer = guess_lexer_for_filename(fctx.path(), text[:1024]) except (ClassNotFound, ValueError): try: - lexer = guess_lexer(text[:1024], encoding=encoding.encoding) + lexer = guess_lexer(text[:1024]) except (ClassNotFound, ValueError): - lexer = TextLexer(encoding=encoding.encoding) + lexer = TextLexer() - formatter = HtmlFormatter(style=style, encoding=encoding.encoding) + formatter = HtmlFormatter(style=style) colorized = highlight(text, lexer, formatter) # strip wrapping div colorized = colorized[:colorized.find('\n</pre>')] colorized = colorized[colorized.find('<pre>')+5:] - coloriter = iter(colorized.splitlines()) + coloriter = (s.encode(encoding.encoding, 'replace') + for s in colorized.splitlines()) tmpl.filters['colorize'] = lambda x: coloriter.next()
--- a/hgext/inotify/linux/_inotify.c Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/inotify/linux/_inotify.c Mon Sep 14 17:29:47 2009 -0500 @@ -106,13 +106,12 @@ static PyObject *remove_watch(PyObject *self, PyObject *args) { - PyObject *ret = NULL; uint32_t wd; int fd; int r; if (!PyArg_ParseTuple(args, "iI:remove_watch", &fd, &wd)) - goto bail; + return NULL; Py_BEGIN_ALLOW_THREADS r = inotify_rm_watch(fd, wd); @@ -120,18 +119,11 @@ if (r == -1) { PyErr_SetFromErrno(PyExc_OSError); - goto bail; + return NULL; } Py_INCREF(Py_None); - - goto done; - -bail: - Py_CLEAR(ret); - -done: - return ret; + return Py_None; } PyDoc_STRVAR(
--- a/hgext/mq.py Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/mq.py Mon Sep 14 17:29:47 2009 -0500 @@ -22,7 +22,6 @@ print patch series qseries print applied patches qapplied - print name of top applied patch qtop add known patch to applied stack qpush remove patch from applied stack qpop @@ -2550,7 +2549,7 @@ "qapplied": (applied, [('1', 'last', None, _('show only the last patch'))] + seriesopts, - _('hg qapplied [-s] [PATCH]')), + _('hg qapplied [-1] [-s] [PATCH]')), "qclone": (clone, [('', 'pull', None, _('use pull protocol to copy metadata')), @@ -2676,7 +2675,7 @@ "qunapplied": (unapplied, [('1', 'first', None, _('show only the first patch'))] + seriesopts, - _('hg qunapplied [-s] [PATCH]')), + _('hg qunapplied [-1] [-s] [PATCH]')), "qfinish": (finish, [('a', 'applied', None, _('finish all applied changesets'))],
--- a/hgext/transplant.py Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/transplant.py Mon Sep 14 17:29:47 2009 -0500 @@ -182,7 +182,7 @@ fp.write("# HG changeset patch\n") fp.write("# User %s\n" % user) fp.write("# Date %d %d\n" % date) - fp.write(changelog[4]) + fp.write(msg + '\n') fp.close() try:
--- a/hgext/win32mbcs.py Mon Sep 14 16:39:24 2009 -0500 +++ b/hgext/win32mbcs.py Mon Sep 14 17:29:47 2009 -0500 @@ -101,7 +101,7 @@ if args: args = list(args) args[0] = appendsep(args[0]) - if kwds.has_key('path'): + if 'path' in kwds: kwds['path'] = appendsep(kwds['path']) return func(*args, **kwds)
--- a/mercurial/changegroup.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/changegroup.py Mon Sep 14 17:29:47 2009 -0500 @@ -10,7 +10,7 @@ import struct, os, bz2, zlib, tempfile def getchunk(source): - """get a chunk from a changegroup""" + """return the next chunk from changegroup 'source' as a string""" d = source.read(4) if not d: return "" @@ -25,7 +25,8 @@ return d def chunkiter(source): - """iterate through the chunks in source""" + """iterate through the chunks in source, yielding a sequence of chunks + (strings)""" while 1: c = getchunk(source) if not c: @@ -33,10 +34,11 @@ yield c def chunkheader(length): - """build a changegroup chunk header""" + """return a changegroup chunk header (string)""" return struct.pack(">l", length + 4) def closechunk(): + """return a changegroup chunk header (string) for a zero-length chunk""" return struct.pack(">l", 0) class nocompress(object):
--- a/mercurial/cmdutil.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/cmdutil.py Mon Sep 14 17:29:47 2009 -0500 @@ -987,12 +987,12 @@ 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].changeset()) + get = util.cachefunc(lambda r: repo[r]) changeiter, matchfn = walkchangerevs(ui, repo, [], get, {'rev':None}) results = {} for st, rev, fns in changeiter: if st == 'add': - d = get(rev)[2] + d = get(rev).date() if df(d[0]): results[rev] = d elif st == 'iter': @@ -1118,13 +1118,13 @@ def changerevgen(): for i, window in increasing_windows(len(repo) - 1, nullrev): for j in xrange(i - window, i + 1): - yield j, change(j)[3] + yield change(j) - for rev, changefiles in changerevgen(): - matches = filter(m, changefiles) + for ctx in changerevgen(): + matches = filter(m, ctx.files()) if matches: - fncache[rev] = matches - wanted.add(rev) + fncache[ctx.rev()] = matches + wanted.add(ctx.rev()) class followfilter(object): def __init__(self, onlyfirst=False): @@ -1189,7 +1189,7 @@ fns = fncache.get(rev) if not fns: def fns_generator(): - for f in change(rev)[3]: + for f in change(rev).files(): if m(f): yield f fns = fns_generator()
--- a/mercurial/commands.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/commands.py Mon Sep 14 17:29:47 2009 -0500 @@ -1275,9 +1275,9 @@ if opts.get('all'): cols.append(change) if opts.get('user'): - cols.append(ui.shortuser(get(r)[1])) + cols.append(ui.shortuser(get(r).user())) if opts.get('date'): - cols.append(datefunc(get(r)[2])) + cols.append(datefunc(get(r).date())) if opts.get('files_with_matches'): c = (fn, r) if c in filerevmatches: @@ -1291,7 +1291,7 @@ skip = {} revfiles = {} - get = util.cachefunc(lambda r: repo[r].changeset()) + get = util.cachefunc(lambda r: repo[r]) changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts) found = False follow = opts.get('follow') @@ -1300,7 +1300,7 @@ matches.clear() revfiles.clear() elif st == 'add': - ctx = repo[rev] + ctx = get(rev) pctx = ctx.parents()[0] parent = pctx.rev() matches.setdefault(rev, {}) @@ -1323,18 +1323,18 @@ continue files.append(fn) - if not matches[rev].has_key(fn): + if fn not in matches[rev]: grepbody(fn, rev, flog.read(fnode)) pfn = copy or fn - if not matches[parent].has_key(pfn): + if pfn not in matches[parent]: try: fnode = pctx.filenode(pfn) grepbody(pfn, parent, flog.read(fnode)) except error.LookupError: pass elif st == 'iter': - parent = repo[rev].parents()[0].rev() + parent = get(rev).parents()[0].rev() for fn in sorted(revfiles.get(rev, [])): states = matches[rev][fn] copy = copies.get(rev, {}).get(fn) @@ -1982,7 +1982,7 @@ will appear in files:. """ - get = util.cachefunc(lambda r: repo[r].changeset()) + get = util.cachefunc(lambda r: repo[r]) changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts) limit = cmdutil.loglimit(opts) @@ -2040,40 +2040,37 @@ if opts.get('only_merges') and len(parents) != 2: continue - if only_branches: - revbranch = get(rev)[5]['branch'] - if revbranch not in only_branches: - continue - - if df: - changes = get(rev) - if not df(changes[2][0]): - continue + ctx = get(rev) + if only_branches and ctx.branch() not in only_branches: + continue + + if df and not df(ctx.date()[0]): + continue if opts.get('keyword'): - changes = get(rev) miss = 0 for k in [kw.lower() for kw in opts['keyword']]: - if not (k in changes[1].lower() or - k in changes[4].lower() or - k in " ".join(changes[3]).lower()): + 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']: - changes = get(rev) - if not [k for k in opts['user'] if k in changes[1]]: + if not [k for k in opts['user'] if k in ctx.user()]: continue copies = [] if opts.get('copies') and rev: - for fn in get(rev)[3]: + for fn in ctx.files(): rename = getrenamed(fn, rev) if rename: copies.append((fn, rename[0])) - displayer.show(context.changectx(repo, rev), copies=copies) + + displayer.show(ctx, copies=copies) + elif st == 'iter': if count == limit: break if displayer.flush(rev): @@ -2158,7 +2155,8 @@ roots, heads = [common.node()], [p2.node()] displayer = cmdutil.show_changeset(ui, repo, opts) for node in repo.changelog.nodesbetween(roots=roots, heads=heads)[0]: - displayer.show(repo[node]) + if node not in roots: + displayer.show(repo[node]) return 0 return hg.merge(repo, node, force=opts.get('force'))
--- a/mercurial/dirstate.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/dirstate.py Mon Sep 14 17:29:47 2009 -0500 @@ -377,9 +377,9 @@ gran = int(self._ui.config('dirstate', 'granularity', 1)) except ValueError: gran = 1 - limit = sys.maxint if gran > 0: - limit = util.fstat(st).st_mtime - gran + hlimit = util.fstat(st).st_mtime + llimit = hlimit - gran cs = cStringIO.StringIO() copymap = self._copymap @@ -389,7 +389,8 @@ for f, e in self._map.iteritems(): if f in copymap: f = "%s\0%s" % (f, copymap[f]) - if e[3] > limit and e[0] == 'n': + if gran > 0 and e[0] == 'n' and llimit < e[3] <= hlimit: + # file was updated too recently, ignore stat data e = (e[0], 0, -1, -1) e = pack(_format, e[0], e[1], e[2], e[3], len(f)) write(e)
--- a/mercurial/dispatch.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/dispatch.py Mon Sep 14 17:29:47 2009 -0500 @@ -335,7 +335,7 @@ path = _findrepo(os.getcwd()) or "" if not path: lui = ui - if path: + else: try: lui = ui.copy() lui.readconfig(os.path.join(path, ".hg", "hgrc")) @@ -349,19 +349,25 @@ lui = ui.copy() lui.readconfig(os.path.join(path, ".hg", "hgrc")) + # Configure extensions in phases: uisetup, extsetup, cmdtable, and + # reposetup. Programs like TortoiseHg will call _dispatch several + # times so we keep track of configured extensions in _loaded. extensions.loadall(lui) - for name, module in extensions.extensions(): - if name in _loaded: - continue + exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded] - # setup extensions - # TODO this should be generalized to scheme, where extensions can - # redepend on other extensions. then we should toposort them, and - # do initialization in correct order + # (uisetup is handled in extensions.loadall) + + for name, module in exts: extsetup = getattr(module, 'extsetup', None) if extsetup: - extsetup() + try: + extsetup(ui) + except TypeError: + if extsetup.func_code.co_argcount != 0: + raise + extsetup() # old extsetup with no ui argument + for name, module in exts: cmdtable = getattr(module, 'cmdtable', {}) overrides = [cmd for cmd in cmdtable if cmd in commands.table] if overrides: @@ -370,6 +376,8 @@ commands.table.update(cmdtable) _loaded.add(name) + # (reposetup is handled in hg.repository) + addaliases(lui, commands.table) # check for fallback encoding
--- a/mercurial/error.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/error.py Mon Sep 14 17:29:47 2009 -0500 @@ -36,6 +36,9 @@ class RepoError(Exception): pass +class RepoLookupError(RepoError): + pass + class CapabilityError(RepoError): pass
--- a/mercurial/extensions.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/extensions.py Mon Sep 14 17:29:47 2009 -0500 @@ -40,6 +40,7 @@ return imp.load_source(module_name, path) def load(ui, name, path): + # unused ui argument kept for backwards compatibility if name.startswith('hgext.') or name.startswith('hgext/'): shortname = name[6:] else: @@ -66,12 +67,9 @@ _extensions[shortname] = mod _order.append(shortname) - uisetup = getattr(mod, 'uisetup', None) - if uisetup: - uisetup(ui) - def loadall(ui): result = ui.configitems("extensions") + newindex = len(_order) for (name, path) in result: if path: if path[0] == '!': @@ -90,6 +88,11 @@ if ui.traceback(): return 1 + for name in _order[newindex:]: + uisetup = getattr(_extensions[name], 'uisetup', None) + if uisetup: + uisetup(ui) + def wrapcommand(table, command, wrapper): aliases, entry = cmdutil.findcmd(command, table) for alias, e in table.iteritems():
--- a/mercurial/hg.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/hg.py Mon Sep 14 17:29:47 2009 -0500 @@ -137,10 +137,12 @@ if update is not True: checkout = update for test in (checkout, 'default', 'tip'): + if test is None: + continue try: uprev = r.lookup(test) break - except LookupError: + except error.RepoLookupError: continue _update(r, uprev) @@ -309,10 +311,12 @@ if update is not True: checkout = update for test in (checkout, 'default', 'tip'): + if test is None: + continue try: uprev = dest_repo.lookup(test) break - except: + except error.RepoLookupError: continue _update(dest_repo, uprev)
--- a/mercurial/hgweb/webcommands.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/hgweb/webcommands.py Mon Sep 14 17:29:47 2009 -0500 @@ -236,7 +236,11 @@ parity=parity.next())) parity = paritygen(web.stripecount) - diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity) + style = web.config('web', 'style', 'paper') + if 'style' in req.form: + style = req.form['style'][0] + + diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity, style) return tmpl('changeset', diff=diffs, rev=ctx.rev(), @@ -474,7 +478,11 @@ # path already defined in except clause parity = paritygen(web.stripecount) - diffs = webutil.diffs(web.repo, tmpl, fctx or ctx, [path], parity) + style = web.config('web', 'style', 'paper') + if 'style' in req.form: + style = req.form['style'][0] + + diffs = webutil.diffs(web.repo, tmpl, fctx or ctx, [path], parity, style) rename = fctx and webutil.renamelink(fctx) or [] ctx = fctx and fctx or ctx return tmpl("filediff",
--- a/mercurial/hgweb/webutil.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/hgweb/webutil.py Mon Sep 14 17:29:47 2009 -0500 @@ -153,7 +153,7 @@ if len(files) > max: yield tmpl('fileellipses') -def diffs(repo, tmpl, ctx, files, parity): +def diffs(repo, tmpl, ctx, files, parity, style): def countgen(): start = 1 @@ -195,7 +195,7 @@ yield tmpl('diffblock', parity=parity.next(), lines=prettyprintlines(''.join(block))) block = [] - if chunk.startswith('diff'): + if chunk.startswith('diff') and style != 'raw': chunk = ''.join(chunk.splitlines(True)[1:]) block.append(chunk) yield tmpl('diffblock', parity=parity.next(),
--- a/mercurial/localrepo.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/localrepo.py Mon Sep 14 17:29:47 2009 -0500 @@ -459,7 +459,7 @@ key = hex(key) except: pass - raise error.RepoError(_("unknown revision '%s'") % key) + raise error.RepoLookupError(_("unknown revision '%s'") % key) def local(self): return True @@ -1457,6 +1457,12 @@ return self.push_addchangegroup(remote, force, revs) def prepush(self, remote, force, revs): + '''Analyze the local and remote repositories and determine which + changesets need to be pushed to the remote. Return a tuple + (changegroup, remoteheads). changegroup is a readable file-like + object whose read() returns successive changegroup chunks ready to + be sent over the wire. remoteheads is the list of remote heads. + ''' common = {} remote_heads = remote.heads() inc = self.findincoming(remote, common, remote_heads, force=force) @@ -1601,9 +1607,10 @@ self.ui.debug("%s\n" % hex(node)) def changegroupsubset(self, bases, heads, source, extranodes=None): - """This function generates a changegroup consisting of all the nodes - that are descendents of any of the bases, and ancestors of any of - the heads. + """Compute a changegroup consisting of all the nodes that are + descendents of any of the bases and ancestors of any of the heads. + Return a chunkbuffer object whose read() method will return + successive changegroup chunks. It is fairly complex as determining which filenodes and which manifest nodes need to be included for the changeset to be complete @@ -1902,8 +1909,9 @@ return self.changegroupsubset(basenodes, self.heads(), source) def _changegroup(self, common, source): - """Generate a changegroup of all nodes that we have that a recipient - doesn't. + """Compute the changegroup of all nodes that we have that a recipient + doesn't. Return a chunkbuffer object whose read() method will return + successive changegroup chunks. This is much easier than the previous function as we can assume that the recipient has any changenode we aren't sending them. @@ -1937,6 +1945,7 @@ return lookuprevlink def gengroup(): + '''yield a sequence of changegroup chunks (strings)''' # construct a list of all changed files changedfiles = set()
--- a/mercurial/manifest.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/manifest.py Mon Sep 14 17:29:47 2009 -0500 @@ -20,12 +20,11 @@ def set(self, f, flags): self._flags[f] = flags def copy(self): - return manifestdict(dict.copy(self), dict.copy(self._flags)) + return manifestdict(self, dict.copy(self._flags)) class manifest(revlog.revlog): def __init__(self, opener): - self.mapcache = None - self.listcache = None + self._mancache = None revlog.revlog.__init__(self, opener, "00manifest.i") def parse(self, lines): @@ -40,12 +39,12 @@ def read(self, node): if node == revlog.nullid: return manifestdict() # don't upset local cache - if self.mapcache and self.mapcache[0] == node: - return self.mapcache[1] + if self._mancache and self._mancache[0] == node: + return self._mancache[1] text = self.revision(node) - self.listcache = array.array('c', text) + arraytext = array.array('c', text) mapping = self.parse(text) - self.mapcache = (node, mapping) + self._mancache = (node, mapping, arraytext) return mapping def _search(self, m, s, lo=0, hi=None): @@ -93,8 +92,8 @@ def find(self, node, f): '''look up entry for a single file efficiently. return (node, flags) pair if found, (None, None) if not.''' - if self.mapcache and node == self.mapcache[0]: - return self.mapcache[1].get(f), self.mapcache[1].flags(f) + if self._mancache and self._mancache[0] == node: + return self._mancache[1].get(f), self._mancache[1].flags(f) text = self.revision(node) start, end = self._search(text, f) if start == end: @@ -110,17 +109,13 @@ def addlistdelta(addlist, x): # start from the bottom up # so changes to the offsets don't mess things up. - i = len(x) - while i > 0: - i -= 1 - start = x[i][0] - end = x[i][1] - if x[i][2]: - addlist[start:end] = array.array('c', x[i][2]) + for start, end, content in reversed(x): + if content: + addlist[start:end] = array.array('c', content) else: del addlist[start:end] - return "".join([struct.pack(">lll", d[0], d[1], len(d[2])) + d[2] - for d in x ]) + return "".join(struct.pack(">lll", start, end, len(content)) + content + for start, end, content in x) def checkforbidden(l): for f in l: @@ -128,26 +123,29 @@ raise error.RevlogError( _("'\\n' and '\\r' disallowed in filenames: %r") % f) - # if we're using the listcache, make sure it is valid and + # if we're using the cache, make sure it is valid and # parented by the same node we're diffing against - if not (changed and self.listcache and p1 and self.mapcache[0] == p1): + if not (changed and self._mancache and p1 and self._mancache[0] == p1): files = sorted(map) checkforbidden(files) # if this is changed to support newlines in filenames, # be sure to check the templates/ dir again (especially *-raw.tmpl) hex, flags = revlog.hex, map.flags - text = ["%s\000%s%s\n" % (f, hex(map[f]), flags(f)) - for f in files] - self.listcache = array.array('c', "".join(text)) + text = ''.join("%s\000%s%s\n" % (f, hex(map[f]), flags(f)) + for f in files) + arraytext = array.array('c', text) cachedelta = None else: - addlist = self.listcache + added, removed = changed + addlist = self._mancache[2] - checkforbidden(changed[0]) + checkforbidden(added) # combine the changed lists into one list for sorting - work = [[x, 0] for x in changed[0]] - work[len(work):] = [[x, 1] for x in changed[1]] + work = [(x, False) for x in added] + work.extend((x, True) for x in removed) + # this could use heapq.merge() (from python2.6+) or equivalent + # since the lists are already sorted work.sort() delta = [] @@ -160,18 +158,17 @@ # start with a readonly loop that finds the offset of # each line and creates the deltas - for w in work: - f = w[0] + for f, todelete in work: # bs will either be the index of the item or the insert point start, end = self._search(addbuf, f, start) - if w[1] == 0: + if not todelete: l = "%s\000%s%s\n" % (f, revlog.hex(map[f]), map.flags(f)) else: + if start == end: + # item we want to delete was not found, error out + raise AssertionError( + _("failed to remove %s from manifest") % f) l = "" - if start == end and w[1] == 1: - # item we want to delete was not found, error out - raise AssertionError( - _("failed to remove %s from manifest") % f) if dstart != None and dstart <= start and dend >= start: if dend < end: dend = end @@ -190,12 +187,12 @@ cachedelta = addlistdelta(addlist, delta) # the delta is only valid if we've been processing the tip revision - if self.mapcache[0] != self.tip(): + if p1 != self.tip(): cachedelta = None - self.listcache = addlist + arraytext = addlist + text = buffer(arraytext) - n = self.addrevision(buffer(self.listcache), transaction, link, - p1, p2, cachedelta) - self.mapcache = (n, map) + n = self.addrevision(text, transaction, link, p1, p2, cachedelta) + self._mancache = (n, map, arraytext) return n
--- a/mercurial/minirst.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/minirst.py Mon Sep 14 17:29:47 2009 -0500 @@ -279,6 +279,8 @@ def formatblock(block, width): """Format a block according to width.""" + if width <= 0: + width = 78 indent = ' ' * block['indent'] if block['type'] == 'margin': return ''
--- a/mercurial/parsers.c Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/parsers.c Mon Sep 14 17:29:47 2009 -0500 @@ -92,8 +92,6 @@ goto bail; if (nlen > 40) { - PyObject *flags; - flags = PyString_FromStringAndSize(zero + 41, nlen - 40); if (!flags)
--- a/mercurial/patch.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/patch.py Mon Sep 14 17:29:47 2009 -0500 @@ -188,7 +188,7 @@ if m: if gp: gitpatches.append(gp) - src, dst = m.group(1, 2) + dst = m.group(2) gp = patchmeta(dst) gp.lineno = lineno elif gp: @@ -378,15 +378,13 @@ self.write() self.write_rej() - def apply(self, h, reverse): + def apply(self, h): if not h.complete(): raise PatchError(_("bad hunk #%d %s (%d %d %d %d)") % (h.number, h.desc, len(h.a), h.lena, len(h.b), h.lenb)) self.hunks += 1 - if reverse: - h.reverse() if self.missing: self.rej.append(h) @@ -600,31 +598,6 @@ self.startb, self.lenb) self.hunk[0] = self.desc - def reverse(self): - self.create, self.remove = self.remove, self.create - origlena = self.lena - origstarta = self.starta - self.lena = self.lenb - self.starta = self.startb - self.lenb = origlena - self.startb = origstarta - self.a = [] - self.b = [] - # self.hunk[0] is the @@ description - for x in xrange(1, len(self.hunk)): - o = self.hunk[x] - if o.startswith('-'): - n = '+' + o[1:] - self.b.append(o[1:]) - elif o.startswith('+'): - n = '-' + o[1:] - self.a.append(n) - else: - n = o - self.b.append(o[1:]) - self.a.append(o) - self.hunk[x] = o - def fix_newline(self): diffhelpers.fix_newline(self.hunk, self.a, self.b) @@ -762,7 +735,7 @@ return s return s[:i] -def selectfile(afile_orig, bfile_orig, hunk, strip, reverse): +def selectfile(afile_orig, bfile_orig, hunk, strip): def pathstrip(path, count=1): pathlen = len(path) i = 0 @@ -790,8 +763,6 @@ else: goodb = not nullb and os.path.exists(bfile) createfunc = hunk.createfile - if reverse: - createfunc = hunk.rmfile missing = not goodb and not gooda and not createfunc() # some diff programs apparently produce create patches where the @@ -977,8 +948,7 @@ if hunknum == 0 and dopatch and not gitworkdone: raise NoHunks -def applydiff(ui, fp, changed, strip=1, sourcefile=None, reverse=False, - eol=None): +def applydiff(ui, fp, changed, strip=1, sourcefile=None, eol=None): """ Reads a patch from fp and tries to apply it. @@ -1008,7 +978,7 @@ if not current_file: continue current_hunk = values - ret = current_file.apply(current_hunk, reverse) + ret = current_file.apply(current_hunk) if ret >= 0: changed.setdefault(current_file.fname, None) if ret > 0: @@ -1021,7 +991,7 @@ current_file = patchfile(ui, sourcefile, opener, eol=eol) else: current_file, missing = selectfile(afile, bfile, first_hunk, - strip, reverse) + strip) current_file = patchfile(ui, current_file, opener, missing, eol) except PatchError, err: ui.warn(str(err) + '\n')
--- a/mercurial/repo.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/repo.py Mon Sep 14 17:29:47 2009 -0500 @@ -40,4 +40,5 @@ url = self.url() if url.endswith('/'): return url + path - return url + '/' + path + else: + return url + '/' + path
--- a/mercurial/revlog.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/revlog.py Mon Sep 14 17:29:47 2009 -0500 @@ -973,7 +973,7 @@ if node == nullid: return "" if self._cache and self._cache[0] == node: - return str(self._cache[2]) + return self._cache[2] # look up what we need to read text = None @@ -988,7 +988,7 @@ # do we have useful data cached? if self._cache and self._cache[1] >= base and self._cache[1] < rev: base = self._cache[1] - text = str(self._cache[2]) + text = self._cache[2] self._loadindex(base, rev + 1) self._chunkraw(base, rev) @@ -1111,7 +1111,8 @@ ifh.write(data[1]) self.checkinlinesize(transaction, ifh) - self._cache = (node, curr, text) + if type(text) == str: # only accept immutable objects + self._cache = (node, curr, text) return node def ancestor(self, a, b): @@ -1127,7 +1128,8 @@ return self.node(c) def group(self, nodelist, lookup, infocollect=None): - """calculate a delta group + """Calculate a delta group, yielding a sequence of changegroup chunks + (strings). Given a list of changeset revs, return a set of deltas and metadata corresponding to nodes. the first delta is
--- a/mercurial/tags.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/tags.py Mon Sep 14 17:29:47 2009 -0500 @@ -301,7 +301,10 @@ def _writetagcache(ui, repo, heads, tagfnode, cachetags): - cachefile = repo.opener('tags.cache', 'w', atomictemp=True) + try: + cachefile = repo.opener('tags.cache', 'w', atomictemp=True) + except (OSError, IOError): + return _debug(ui, 'writing cache file %s\n' % cachefile.name) realheads = repo.heads() # for sanity checks below
--- a/mercurial/templatefilters.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/templatefilters.py Mon Sep 14 17:29:47 2009 -0500 @@ -105,13 +105,14 @@ '''indent each non-empty line of text after first with prefix.''' lines = text.splitlines() num_lines = len(lines) + endswithnewline = text[-1:] == '\n' def indenter(): for i in xrange(num_lines): l = lines[i] if i and l.strip(): yield prefix yield l - if i < num_lines - 1 or text.endswith('\n'): + if i < num_lines - 1 or endswithnewline: yield '\n' return "".join(indenter())
--- a/mercurial/templater.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/templater.py Mon Sep 14 17:29:47 2009 -0500 @@ -42,7 +42,7 @@ filter uses function to transform value. syntax is {key|filter1|filter2|...}.''' - template_re = re.compile(r'{([\w\|%]+)}|#([\w\|%]+)#') + template_re = re.compile(r'{([\w\|%]+)}') def __init__(self, loader, filters={}, defaults={}): self.loader = loader
--- a/mercurial/ui.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/ui.py Mon Sep 14 17:29:47 2009 -0500 @@ -199,7 +199,7 @@ def _path(self, loc): p = self.config('paths', loc) if p and '%%' in p: - self.warn('(deprecated \'%%\' in path %s=%s from %s)\n' % + self.warn("(deprecated '%%' in path %s=%s from %s)\n" % (loc, p, self.configsource('paths', loc))) p = p.replace('%%', '%') return p @@ -358,7 +358,7 @@ visible. 'topic' is the current operation, 'item' is a non-numeric marker of the current position (ie the currently in-process file), 'pos' is the current numeric position (ie - revision, bytes, etc.), units is a corresponding unit label, + revision, bytes, etc.), unit is a corresponding unit label, and total is the highest expected pos. Multiple nested topics may be active at a time. All topics @@ -368,14 +368,14 @@ if pos == None or not self.debugflag: return - if units: - units = ' ' + units + if unit: + unit = ' ' + unit if item: item = ' ' + item if total: pct = 100.0 * pos / total ui.debug('%s:%s %s/%s%s (%4.2g%%)\n' - % (topic, item, pos, total, units, pct)) + % (topic, item, pos, total, unit, pct)) else: - ui.debug('%s:%s %s%s\n' % (topic, item, pos, units)) + ui.debug('%s:%s %s%s\n' % (topic, item, pos, unit))
--- a/mercurial/util.py Mon Sep 14 16:39:24 2009 -0500 +++ b/mercurial/util.py Mon Sep 14 17:29:47 2009 -0500 @@ -84,7 +84,7 @@ '%b %d %Y', '%b %d', '%H:%M:%S', - '%I:%M:%SP', + '%I:%M:%S%p', '%H:%M', '%I:%M%p', ) @@ -266,9 +266,7 @@ def canonpath(root, cwd, myname): """return the canonical path of myname, given cwd and root""" - if root == os.sep: - rootsep = os.sep - elif endswithsep(root): + if endswithsep(root): rootsep = root else: rootsep = root + os.sep @@ -663,8 +661,9 @@ contents = _fspathcache[dir] lpart = part.lower() + lenp = len(part) for n in contents: - if n.lower() == lpart: + if lenp == len(n) and n.lower() == lpart: result.append(n) break else: @@ -1275,6 +1274,9 @@ def wrap(line, hangindent, width=None): if width is None: width = termwidth() - 2 + if width <= hangindent: + # adjust for weird terminal size + width = max(78, hangindent + 1) padding = '\n' + ' ' * hangindent return padding.join(textwrap.wrap(line, width=width - hangindent))
--- a/tests/hghave Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/hghave Mon Sep 14 17:29:47 2009 -0500 @@ -78,7 +78,7 @@ def has_icasefs(): # Stolen from mercurial.util - fd, path = tempfile.mkstemp(prefix=tempprefix) + fd, path = tempfile.mkstemp(prefix=tempprefix, dir='.') os.close(fd) try: s1 = os.stat(path)
--- a/tests/printenv.py Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/printenv.py Mon Sep 14 17:29:47 2009 -0500 @@ -46,12 +46,9 @@ elif url.startswith("remote:http"): os.environ["HG_URL"] = "remote:http" -if "HG_PENDING" in os.environ: - os.environ["HG_PENDING"] = os.environ["HG_PENDING"] and "true" - out.write("%s hook: " % name) for v in env: - out.write("%s=%s " % (v, os.environ[v])) + out.write("%s=%s " % (v, os.environ[v].replace(os.environ["HGTMP"], '$HGTMP'))) out.write("\n") out.close()
--- a/tests/run-tests.py Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/run-tests.py Mon Sep 14 17:29:47 2009 -0500 @@ -167,16 +167,22 @@ 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: - print >> sys.stderr, 'ERROR: -j/--jobs must be positive' - sys.exit(1) + parser.error('--jobs must be positive') if options.interactive and options.jobs > 1: print '(--interactive overrides --jobs)' options.jobs = 1 if options.py3k_warnings: if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0): - print 'ERROR: Py3k warnings switch can only be used on Python 2.6+' - sys.exit(1) + parser.error('--py3k-warnings can only be used on Python 2.6+') return (options, args)
--- a/tests/test-casefolding Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-casefolding Mon Sep 14 17:29:47 2009 -0500 @@ -31,6 +31,9 @@ hg rm a hg ci -Am removea echo A > A +# on linux hfs keeps the old case stored, force it +mv a aa +mv aa A hg ci -Am addA # Used to fail under case insensitive fs hg up -C 0
--- a/tests/test-churn Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-churn Mon Sep 14 17:29:47 2009 -0500 @@ -50,3 +50,13 @@ echo % churn by hour hg churn -f '%H' -s +cd .. + +# issue 833: ZeroDivisionError +hg init issue-833 +cd issue-833 +touch foo +hg ci -Am foo +# this was failing with a ZeroDivisionError +hg churn +cd ..
--- a/tests/test-churn.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-churn.out Mon Sep 14 17:29:47 2009 -0500 @@ -28,3 +28,5 @@ 09 2 ********************************* 12 4 ****************************************************************** 13 1 **************** +adding foo +test 0
--- a/tests/test-command-template Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-command-template Mon Sep 14 17:29:47 2009 -0500 @@ -43,15 +43,15 @@ echo '# normal' hg log > log.out hg log --style default > style.out -diff -u log.out style.out +cmp log.out style.out || diff -u log.out style.out echo '# verbose' hg log -v > log.out hg log -v --style default > style.out -diff -u log.out style.out +cmp log.out style.out || diff -u log.out style.out echo '# debug' hg log --debug > log.out hg log --debug --style default > style.out -diff -u log.out style.out +cmp log.out style.out || diff -u log.out style.out echo '# revision with no copies (used to print a traceback)' hg tip -v --template '\n'
--- a/tests/test-convert-clonebranches.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-convert-clonebranches.out Mon Sep 14 17:29:47 2009 -0500 @@ -18,12 +18,12 @@ % incremental conversion 2 c1 pulling from branch0 into branch1 -2 changesets found +4 changesets found 1 c2 pulling from branch0 into branch2 -2 changesets found +4 changesets found 0 c3 pulling from branch2 into branch3 -3 changesets found +5 changesets found pulling from branch1 into branch3 1 changesets found
--- a/tests/test-convert-git Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-convert-git Mon Sep 14 17:29:47 2009 -0500 @@ -42,7 +42,7 @@ echo b >> a commit -a -m t4.1 -git checkout -b other HEAD^ >/dev/null 2>/dev/null +git checkout -b other HEAD~ >/dev/null 2>/dev/null echo c > a echo a >> a commit -a -m t4.2 @@ -68,7 +68,7 @@ echo >> foo commit -a -m 'change foo' -git checkout -b Bar HEAD^ >/dev/null 2>/dev/null +git checkout -b Bar HEAD~ >/dev/null 2>/dev/null echo quux >> quux git add quux commit -a -m 'add quux' @@ -77,7 +77,7 @@ git add bar commit -a -m 'add bar' -git checkout -b Baz HEAD^ >/dev/null 2>/dev/null +git checkout -b Baz HEAD~ >/dev/null 2>/dev/null echo baz > baz git add baz commit -a -m 'add baz' @@ -89,7 +89,7 @@ echo bar >> bar commit -a -m 'change bar' -git checkout -b Foo HEAD^ >/dev/null 2>/dev/null +git checkout -b Foo HEAD~ >/dev/null 2>/dev/null echo >> foo commit -a -m 'change foo'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-convert-tagsbranch-topology Mon Sep 14 17:29:47 2009 -0500 @@ -0,0 +1,64 @@ +#!/bin/sh + +"$TESTDIR/hghave" git || exit 80 + +echo "[extensions]" >> $HGRCPATH +echo "convert=" >> $HGRCPATH +echo 'hgext.graphlog =' >> $HGRCPATH +echo '[convert]' >> $HGRCPATH +echo 'hg.usebranchnames = True' >> $HGRCPATH +echo 'hg.tagsbranch = tags-update' >> $HGRCPATH + +GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME +GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL +GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE +GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME +GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL +GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE + +count=10 +action() +{ + GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000" + GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" + git "$@" >/dev/null 2>/dev/null || echo "git command error" + count=`expr $count + 1` +} + +glog() +{ + hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@" +} + +convertrepo() +{ + hg convert --datesort git-repo hg-repo +} + +# Build a GIT repo with at least 1 tag +mkdir git-repo +cd git-repo +git init >/dev/null 2>&1 +echo a > a +git add a +action commit -m "rev1" +action tag -m "tag1" tag1 +cd .. + +# Do a first conversion +convertrepo + +# Simulate upstream updates after first conversion +cd git-repo +echo b > a +git add a +action commit -m "rev2" +action tag -m "tag2" tag2 +cd .. + +# Perform an incremental conversion +convertrepo + +# Print the log +cd hg-repo +glog
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-convert-tagsbranch-topology.out Mon Sep 14 17:29:47 2009 -0500 @@ -0,0 +1,19 @@ +initializing destination hg-repo repository +scanning source... +sorting... +converting... +0 rev1 +updating tags +scanning source... +sorting... +converting... +0 rev2 +updating tags +o 3 "update tags" files: .hgtags +| +| o 2 "rev2" files: a +| | +o | 1 "update tags" files: .hgtags + / +o 0 "rev1" files: a +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-dirstate-future Mon Sep 14 17:29:47 2009 -0500 @@ -0,0 +1,13 @@ +#!/bin/sh + +hg init +echo a > a +hg add +hg ci -m1 + +# set mtime of a into the future +touch -t 202101011200 a + +# status must not set a's entry to unset (issue1790) +hg status +hg debugstate
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-dirstate-future.out Mon Sep 14 17:29:47 2009 -0500 @@ -0,0 +1,2 @@ +adding a +n 644 2 2021-01-01 12:00:00 a
--- a/tests/test-double-merge.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-double-merge.out Mon Sep 14 17:29:47 2009 -0500 @@ -1,9 +1,4 @@ created new head -changeset: 0:310fd17130da -user: test -date: Mon Jan 12 13:46:40 1970 +0000 -summary: add foo - changeset: 1:7731dad1c2b9 user: test date: Mon Jan 12 13:46:40 1970 +0000
--- a/tests/test-extension Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-extension Mon Sep 14 17:29:47 2009 -0500 @@ -55,6 +55,29 @@ hg foo echo 'barfoo = !' >> $HGRCPATH +# check that extensions are loaded in phases +cat > foo.py <<EOF +import os +name = os.path.basename(__file__).rsplit('.', 1)[0] +print "1) %s imported" % name +def uisetup(ui): + print "2) %s uisetup" % name +def extsetup(): + print "3) %s extsetup" % name +def reposetup(ui, repo): + print "4) %s reposetup" % name +EOF + +cp foo.py bar.py +echo 'foo = foo.py' >> $HGRCPATH +echo 'bar = bar.py' >> $HGRCPATH + +# command with no output, we just want to see the extensions loaded +hg paths + +echo 'foo = !' >> $HGRCPATH +echo 'bar = !' >> $HGRCPATH + cd .. cat > empty.py <<EOF '''empty cmdtable
--- a/tests/test-extension.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-extension.out Mon Sep 14 17:29:47 2009 -0500 @@ -16,6 +16,14 @@ reposetup called for a ui == repo.ui Foo +1) foo imported +1) bar imported +2) foo uisetup +2) bar uisetup +3) foo extsetup +3) bar extsetup +4) foo reposetup +4) bar reposetup empty extension - empty cmdtable no commands defined
--- a/tests/test-grep Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-grep Mon Sep 14 17:29:47 2009 -0500 @@ -22,14 +22,14 @@ echo % simple hg grep port port echo % all -hg grep --all -nu port port +hg grep --traceback --all -nu port port echo % other hg grep import port hg cp port port2 hg commit -m 4 -u spam -d '5 0' -echo '% follow' -hg grep -f 'import$' port2 +echo % follow +hg grep --traceback -f 'import$' port2 echo deport >> port2 hg commit -m 5 -u eggs -d '6 0' hg grep -f --all -nu port port2
--- a/tests/test-hgweb-commands.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-hgweb-commands.out Mon Sep 14 17:29:47 2009 -0500 @@ -337,6 +337,7 @@ # Parent 2ef0ac749a14e4f57a5a822464a0902c6f7f448f Added tag 1.0 for changeset 2ef0ac749a14 +diff -r 2ef0ac749a14 -r a4f92ed23982 .hgtags --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000 @@ -0,0 +1,1 @@ @@ -451,6 +452,7 @@ 200 Script output follows +diff -r 000000000000 -r a4f92ed23982 foo --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foo Thu Jan 01 00:00:00 1970 +0000 @@ -0,0 +1,1 @@
--- a/tests/test-hgweb-diffs Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-hgweb-diffs Mon Sep 14 17:29:47 2009 -0500 @@ -18,6 +18,9 @@ echo % revision "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/rev/0' +echo % raw revision +"$TESTDIR/get-with-headers.py" localhost:$HGPORT '/raw-rev/0' + echo % diff removed file "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/tip/a' @@ -29,6 +32,9 @@ echo % revision "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/rev/0' +echo % revision +"$TESTDIR/get-with-headers.py" localhost:$HGPORT '/raw-rev/0' + echo % diff removed file "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/tip/a'
--- a/tests/test-hgweb-diffs.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-hgweb-diffs.out Mon Sep 14 17:29:47 2009 -0500 @@ -95,6 +95,28 @@ </body> </html> +% raw revision +200 Script output follows + + +# HG changeset patch +# User test +# Date 0 0 +# Node ID 0cd96de13884b090099512d4794ae87ad067ea8e + +a + +diff -r 000000000000 -r 0cd96de13884 a +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/a Thu Jan 01 00:00:00 1970 +0000 +@@ -0,0 +1,1 @@ ++a +diff -r 000000000000 -r 0cd96de13884 b +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/b Thu Jan 01 00:00:00 1970 +0000 +@@ -0,0 +1,1 @@ ++b + % diff removed file 200 Script output follows @@ -279,6 +301,30 @@ </body> </html> +% revision +200 Script output follows + + +# HG changeset patch +# User test +# Date 0 0 +# Node ID 0cd96de13884b090099512d4794ae87ad067ea8e + +a + +diff --git a/a b/a +new file mode 100644 +--- /dev/null ++++ b/a +@@ -0,0 +1,1 @@ ++a +diff --git a/b b/b +new file mode 100644 +--- /dev/null ++++ b/b +@@ -0,0 +1,1 @@ ++b + % diff removed file 200 Script output follows
--- a/tests/test-highlight Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-highlight Mon Sep 14 17:29:47 2009 -0500 @@ -47,9 +47,6 @@ print "The first %d primes: %s" % (n, list(islice(p, n))) EOF -# check for UnicodeDecodeError with iso-8859-1 file contents -python -c 'fp = open("isolatin.txt", "w"); fp.write("h\xFCbsch\n"); fp.close();' - hg ci -Ama echo % hg serve @@ -60,10 +57,6 @@ ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file/tip/primes.py') \ | sed "s/class=\"k\"/class=\"kn\"/g" | sed "s/class=\"mf\"/class=\"mi\"/g" -echo % hgweb filerevision, html -("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file/tip/isolatin.txt') \ - | sed "s/class=\"k\"/class=\"kn\"/g" - echo % hgweb fileannotate, html ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/annotate/tip/primes.py') \ | sed "s/class=\"k\"/class=\"kn\"/g" | sed "s/class=\"mi\"/class=\"mf\"/g" @@ -121,3 +114,28 @@ echo % errors encountered cat errors.log + +cd .. +hg init eucjp +cd eucjp + +printf '\265\376\n' >> eucjp.txt # Japanese kanji "Kyo" + +hg ci -Ama + +hgserveget () { + "$TESTDIR/killdaemons.py" + echo % HGENCODING="$1" hg serve + HGENCODING="$1" hg serve -p $HGPORT -d -n test --pid-file=hg.pid -E errors.log + cat hg.pid >> $DAEMON_PIDS + + echo % hgweb filerevision, html + "$TESTDIR/get-with-headers.py" localhost:$HGPORT "/file/tip/$2" \ + | grep '<div class="parity0 source">' | $TESTDIR/printrepr.py + echo % errors encountered + cat errors.log +} + +hgserveget euc-jp eucjp.txt +hgserveget utf-8 eucjp.txt +hgserveget us-ascii eucjp.txt
--- a/tests/test-highlight.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-highlight.out Mon Sep 14 17:29:47 2009 -0500 @@ -1,4 +1,3 @@ -adding isolatin.txt adding primes.py % hg serve % hgweb filerevision, html @@ -12,7 +11,7 @@ <link rel="stylesheet" href="/static/style-paper.css" type="text/css" /> <link rel="stylesheet" href="/highlightcss" type="text/css" /> -<title>test: 3e1445510fe7 primes.py</title> +<title>test: 853dcd4de2a6 primes.py</title> </head> <body> @@ -23,27 +22,27 @@ <img src="/static/hglogo.png" alt="mercurial" /></a> </div> <ul> -<li><a href="/shortlog/3e1445510fe7">log</a></li> -<li><a href="/graph/3e1445510fe7">graph</a></li> +<li><a href="/shortlog/853dcd4de2a6">log</a></li> +<li><a href="/graph/853dcd4de2a6">graph</a></li> <li><a href="/tags">tags</a></li> <li><a href="/branches">branches</a></li> </ul> <ul> -<li><a href="/rev/3e1445510fe7">changeset</a></li> -<li><a href="/file/3e1445510fe7/">browse</a></li> +<li><a href="/rev/853dcd4de2a6">changeset</a></li> +<li><a href="/file/853dcd4de2a6/">browse</a></li> </ul> <ul> <li class="active">file</li> -<li><a href="/diff/3e1445510fe7/primes.py">diff</a></li> -<li><a href="/annotate/3e1445510fe7/primes.py">annotate</a></li> -<li><a href="/log/3e1445510fe7/primes.py">file log</a></li> -<li><a href="/raw-file/3e1445510fe7/primes.py">raw</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> +<li><a href="/raw-file/853dcd4de2a6/primes.py">raw</a></li> </ul> </div> <div class="main"> <h2><a href="/">test</a></h2> -<h3>view primes.py @ 0:3e1445510fe7</h3> +<h3>view primes.py @ 0:853dcd4de2a6</h3> <form class="search" action="/log"> @@ -119,93 +118,6 @@ </body> </html> -% hgweb filerevision, html -200 Script output follows - -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"> -<head> -<link rel="icon" href="/static/hgicon.png" type="image/png" /> -<meta name="robots" content="index, nofollow" /> -<link rel="stylesheet" href="/static/style-paper.css" type="text/css" /> - -<link rel="stylesheet" href="/highlightcss" type="text/css" /> -<title>test: 3e1445510fe7 isolatin.txt</title> -</head> -<body> - -<div class="container"> -<div class="menu"> -<div class="logo"> -<a href="http://mercurial.selenic.com/"> -<img src="/static/hglogo.png" alt="mercurial" /></a> -</div> -<ul> -<li><a href="/shortlog/3e1445510fe7">log</a></li> -<li><a href="/graph/3e1445510fe7">graph</a></li> -<li><a href="/tags">tags</a></li> -<li><a href="/branches">branches</a></li> -</ul> -<ul> -<li><a href="/rev/3e1445510fe7">changeset</a></li> -<li><a href="/file/3e1445510fe7/">browse</a></li> -</ul> -<ul> -<li class="active">file</li> -<li><a href="/diff/3e1445510fe7/isolatin.txt">diff</a></li> -<li><a href="/annotate/3e1445510fe7/isolatin.txt">annotate</a></li> -<li><a href="/log/3e1445510fe7/isolatin.txt">file log</a></li> -<li><a href="/raw-file/3e1445510fe7/isolatin.txt">raw</a></li> -</ul> -</div> - -<div class="main"> -<h2><a href="/">test</a></h2> -<h3>view isolatin.txt @ 0:3e1445510fe7</h3> - -<form class="search" action="/log"> - -<p><input name="rev" id="search1" type="text" size="30" /></p> -<div id="hint">find changesets by author, revision, -files, or words in the commit message</div> -</form> - -<div class="description">a</div> - -<table id="changesetEntry"> -<tr> - <th class="author">author</th> - <td class="author">test</td> -</tr> -<tr> - <th class="date">date</th> - <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td> -</tr> -<tr> - <th class="author">parents</th> - <td class="author"></td> -</tr> -<tr> - <th class="author">children</th> - <td class="author"></td> -</tr> - -</table> - -<div class="overflow"> -<div class="sourcefirst"> line source</div> - -<div class="parity0 source"><a href="#l1" id="l1"> 1</a> h?bsch</div> -<div class="sourcelast"></div> -</div> -</div> -</div> - - - -</body> -</html> - % hgweb fileannotate, html 200 Script output follows @@ -228,28 +140,28 @@ <img src="/static/hglogo.png" alt="mercurial" /></a> </div> <ul> -<li><a href="/shortlog/3e1445510fe7">log</a></li> -<li><a href="/graph/3e1445510fe7">graph</a></li> +<li><a href="/shortlog/853dcd4de2a6">log</a></li> +<li><a href="/graph/853dcd4de2a6">graph</a></li> <li><a href="/tags">tags</a></li> <li><a href="/branches">branches</a></li> </ul> <ul> -<li><a href="/rev/3e1445510fe7">changeset</a></li> -<li><a href="/file/3e1445510fe7/">browse</a></li> +<li><a href="/rev/853dcd4de2a6">changeset</a></li> +<li><a href="/file/853dcd4de2a6/">browse</a></li> </ul> <ul> -<li><a href="/file/3e1445510fe7/primes.py">file</a></li> -<li><a href="/diff/3e1445510fe7/primes.py">diff</a></li> +<li><a href="/file/853dcd4de2a6/primes.py">file</a></li> +<li><a href="/diff/853dcd4de2a6/primes.py">diff</a></li> <li class="active">annotate</li> -<li><a href="/log/3e1445510fe7/primes.py">file log</a></li> -<li><a href="/raw-annotate/3e1445510fe7/primes.py">raw</a></li> +<li><a href="/log/853dcd4de2a6/primes.py">file log</a></li> +<li><a href="/raw-annotate/853dcd4de2a6/primes.py">raw</a></li> </ul> </div> <div class="main"> <h2><a href="/">test</a></h2> -<h3>annotate primes.py @ 0:3e1445510fe7</h3> +<h3>annotate primes.py @ 0:853dcd4de2a6</h3> <form class="search" action="/log"> @@ -289,225 +201,225 @@ <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#1" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#1" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l1" id="l1"> 1</a> <span class="c">#!/usr/bin/env python</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#2" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#2" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l2" id="l2"> 2</a> </td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#3" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#3" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l3" id="l3"> 3</a> <span class="sd">"""Fun with generators. Corresponding Haskell implementation:</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#4" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#4" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l4" id="l4"> 4</a> </td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#5" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#5" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l5" id="l5"> 5</a> <span class="sd">primes = 2 : sieve [3, 5..]</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#6" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#6" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l6" id="l6"> 6</a> <span class="sd"> where sieve (p:ns) = p : sieve [n | n <- ns, mod n p /= 0]</span></td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#7" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#7" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l7" id="l7"> 7</a> <span class="sd">"""</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#8" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#8" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l8" id="l8"> 8</a> </td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#9" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#9" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l9" id="l9"> 9</a> <span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">dropwhile</span><span class="p">,</span> <span class="n">ifilter</span><span class="p">,</span> <span class="n">islice</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">chain</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#10" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#10" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l10" id="l10"> 10</a> </td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#11" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#11" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l11" id="l11"> 11</a> <span class="kn">def</span> <span class="nf">primes</span><span class="p">():</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#12" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#12" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l12" id="l12"> 12</a> <span class="sd">"""Generate all primes."""</span></td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#13" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#13" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l13" id="l13"> 13</a> <span class="kn">def</span> <span class="nf">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#14" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#14" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l14" id="l14"> 14</a> <span class="n">p</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">next</span><span class="p">()</span></td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#15" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#15" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l15" id="l15"> 15</a> <span class="c"># It is important to yield *here* in order to stop the</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#16" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#16" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l16" id="l16"> 16</a> <span class="c"># infinite recursion.</span></td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#17" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#17" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l17" id="l17"> 17</a> <span class="kn">yield</span> <span class="n">p</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#18" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#18" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l18" id="l18"> 18</a> <span class="n">ns</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">%</span> <span class="n">p</span> <span class="o">!=</span> <span class="mf">0</span><span class="p">,</span> <span class="n">ns</span><span class="p">)</span></td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#19" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#19" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l19" id="l19"> 19</a> <span class="kn">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#20" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#20" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l20" id="l20"> 20</a> <span class="kn">yield</span> <span class="n">n</span></td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#21" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#21" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l21" id="l21"> 21</a> </td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#22" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#22" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l22" id="l22"> 22</a> <span class="n">odds</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">i</span><span class="p">:</span> <span class="n">i</span> <span class="o">%</span> <span class="mf">2</span> <span class="o">==</span> <span class="mf">1</span><span class="p">,</span> <span class="n">count</span><span class="p">())</span></td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#23" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#23" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l23" id="l23"> 23</a> <span class="kn">return</span> <span class="n">chain</span><span class="p">([</span><span class="mf">2</span><span class="p">],</span> <span class="n">sieve</span><span class="p">(</span><span class="n">dropwhile</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o"><</span> <span class="mf">3</span><span class="p">,</span> <span class="n">odds</span><span class="p">)))</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#24" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#24" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l24" id="l24"> 24</a> </td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#25" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#25" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l25" id="l25"> 25</a> <span class="kn">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#26" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#26" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l26" id="l26"> 26</a> <span class="kn">import</span> <span class="nn">sys</span></td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#27" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#27" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l27" id="l27"> 27</a> <span class="kn">try</span><span class="p">:</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#28" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#28" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l28" id="l28"> 28</a> <span class="n">n</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mf">1</span><span class="p">])</span></td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#29" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#29" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l29" id="l29"> 29</a> <span class="kn">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#30" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#30" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l30" id="l30"> 30</a> <span class="n">n</span> <span class="o">=</span> <span class="mf">10</span></td> </tr> <tr class="parity0"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#31" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#31" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l31" id="l31"> 31</a> <span class="n">p</span> <span class="o">=</span> <span class="n">primes</span><span class="p">()</span></td> </tr> <tr class="parity1"> <td class="annotate"> -<a href="/annotate/3e1445510fe7/primes.py#32" -title="3e1445510fe7: a">test@0</a> +<a href="/annotate/853dcd4de2a6/primes.py#32" +title="853dcd4de2a6: a">test@0</a> </td> <td class="source"><a href="#l32" id="l32"> 32</a> <span class="kn">print</span> <span class="s">"The first </span><span class="si">%d</span><span class="s"> primes: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">islice</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">)))</span></td> </tr> @@ -538,3 +450,16 @@ /* pygments_style = fruity */ % errors encountered +adding eucjp.txt +% HGENCODING=euc-jp hg serve +% hgweb filerevision, html +<div class="parity0 source"><a href="#l1" id="l1"> 1</a> \xb5\xfe</div> +% errors encountered +% HGENCODING=utf-8 hg serve +% hgweb filerevision, html +<div class="parity0 source"><a href="#l1" id="l1"> 1</a> \xef\xbf\xbd\xef\xbf\xbd</div> +% errors encountered +% HGENCODING=us-ascii hg serve +% hgweb filerevision, html +<div class="parity0 source"><a href="#l1" id="l1"> 1</a> ??</div> +% errors encountered
--- a/tests/test-hook.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-hook.out Mon Sep 14 17:29:47 2009 -0500 @@ -1,18 +1,18 @@ precommit hook: HG_PARENT1=0000000000000000000000000000000000000000 -pretxncommit hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=true +pretxncommit hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$HGTMP/test-hook/a 0:29b62aeb769f commit hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000 commit.b hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000 updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved precommit hook: HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b -pretxncommit hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PENDING=true +pretxncommit hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PENDING=$HGTMP/test-hook/a 1:b702efe96888 commit hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b commit.b hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b 1 files updated, 0 files merged, 0 files removed, 0 files unresolved precommit hook: HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b -pretxncommit hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PENDING=true +pretxncommit hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PENDING=$HGTMP/test-hook/a 2:1324a5531bac commit hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b commit.b hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b @@ -20,7 +20,7 @@ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) precommit hook: HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2 -pretxncommit hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PENDING=true +pretxncommit hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PENDING=$HGTMP/test-hook/a 3:4c52fb2e4022 commit hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2 commit.b hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2 @@ -43,7 +43,7 @@ (run 'hg update' to get a working copy) pretag hook: HG_LOCAL=0 HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_TAG=a precommit hook: HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321 -pretxncommit hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321 HG_PENDING=true +pretxncommit hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321 HG_PENDING=$HGTMP/test-hook/a 4:8ea2ef7ad3e8 commit hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321 commit.b hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321 @@ -58,10 +58,10 @@ abort: pretag.forbid hook exited with status 1 4:8ea2ef7ad3e8 precommit hook: HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 -pretxncommit hook: HG_NODE=fad284daf8c032148abaffcd745dafeceefceb61 HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=true +pretxncommit hook: HG_NODE=fad284daf8c032148abaffcd745dafeceefceb61 HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=$HGTMP/test-hook/a 5:fad284daf8c0 5:fad284daf8c0 -pretxncommit.forbid hook: HG_NODE=fad284daf8c032148abaffcd745dafeceefceb61 HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=true +pretxncommit.forbid hook: HG_NODE=fad284daf8c032148abaffcd745dafeceefceb61 HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=$HGTMP/test-hook/a transaction abort! rollback completed abort: pretxncommit.forbid1 hook exited with status 1 @@ -81,7 +81,7 @@ searching for changes abort: prechangegroup.forbid hook exited with status 1 4:8ea2ef7ad3e8 -pretxnchangegroup.forbid hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=true HG_SOURCE=pull HG_URL=file: +pretxnchangegroup.forbid hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=$HGTMP/test-hook/b HG_SOURCE=pull HG_URL=file: pulling from ../a searching for changes adding changesets
--- a/tests/test-keyword.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-keyword.out Mon Sep 14 17:29:47 2009 -0500 @@ -359,6 +359,7 @@ # Parent bb948857c743469b22bbf51f7ec8112279ca5d83 xa +diff -r bb948857c743 -r cfa68229c116 x/a --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000 @@ -0,0 +1,4 @@ @@ -371,6 +372,7 @@ 200 Script output follows +diff -r ef63ca68695b -r bb948857c743 a --- a/a Thu Jan 01 00:00:00 1970 +0000 +++ b/a Thu Jan 01 00:00:02 1970 +0000 @@ -1,3 +1,4 @@
--- a/tests/test-log Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-log Mon Sep 14 17:29:47 2009 -0500 @@ -104,6 +104,12 @@ echo '% log -r <some unknown node id>' hg log -r 1000000000000000000000000000000000000000 +echo '% log -k r1' +hg log -k r1 + +echo '% log -d -1' +hg log -d -1 + cd .. hg init usertest
--- a/tests/test-log.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-log.out Mon Sep 14 17:29:47 2009 -0500 @@ -239,6 +239,13 @@ abort: 00changelog.i@: ambiguous identifier! % log -r <some unknown node id> abort: unknown revision '1000000000000000000000000000000000000000'! +% log -k r1 +changeset: 1:3d5bf5654eda +user: test +date: Thu Jan 01 00:00:01 1970 +0000 +summary: r1 + +% log -d -1 adding a adding b changeset: 0:29a4c94f1924
--- a/tests/test-merge-default.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-merge-default.out Mon Sep 14 17:29:47 2009 -0500 @@ -13,11 +13,6 @@ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) % should succeed - 2 heads -changeset: 1:ba677d0156c1 -user: test -date: Thu Jan 01 00:00:00 1970 +0000 -summary: b - changeset: 3:903c264cdf57 parent: 1:ba677d0156c1 user: test
--- a/tests/test-merge1.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-merge1.out Mon Sep 14 17:29:47 2009 -0500 @@ -1,11 +1,6 @@ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved created new head %% no merges expected -changeset: 0:98e00378acd0 -user: test -date: Mon Jan 12 13:46:40 1970 +0000 -summary: commit #0 - changeset: 1:4ee19afe4659 user: test date: Mon Jan 12 13:46:40 1970 +0000
--- a/tests/test-mq.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-mq.out Mon Sep 14 17:29:47 2009 -0500 @@ -16,7 +16,6 @@ print patch series qseries print applied patches qapplied - print name of top applied patch qtop add known patch to applied stack qpush remove patch from applied stack qpop
--- a/tests/test-parse-date Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-parse-date Mon Sep 14 17:29:47 2009 -0500 @@ -44,6 +44,10 @@ hg debugdate "Sat Sep 08 21:16:40 2001 +0430" hg debugdate "Sat Sep 08 21:16:40 2001 -0430" +# Test 12-hours times +hg debugdate "2006-02-01 1:00:30PM +0000" +hg debugdate "1:00:30PM" > /dev/null || echo 'failed' + #Test date formats with '>' or '<' accompanied by space characters hg log -d '>' --template '{date|date}\n' hg log -d '<' hg log -d '>' --template '{date|date}\n'
--- a/tests/test-parse-date.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-parse-date.out Mon Sep 14 17:29:47 2009 -0500 @@ -34,6 +34,8 @@ standard: Sat Sep 08 21:16:40 2001 +0430 internal: 1000000000 16200 standard: Sat Sep 08 21:16:40 2001 -0430 +internal: 1138798830 0 +standard: Wed Feb 01 13:00:30 2006 +0000 Sun Jan 15 13:30:00 2006 +0500 Sun Jan 15 13:30:00 2006 -0800 Sat Jul 15 13:30:00 2006 +0500
--- a/tests/test-tags Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-tags Mon Sep 14 17:29:47 2009 -0500 @@ -37,9 +37,17 @@ hg identify # repeat with cold tag cache +echo "% identify with cold cache" rm -f .hg/tags.cache hg identify +# and again, but now unable to write tag cache +echo "% identify with unwritable cache" +rm -f .hg/tags.cache +chmod 555 .hg +hg identify +chmod 755 .hg + echo "% create a branch" echo bb > a hg status
--- a/tests/test-tags.out Mon Sep 14 16:39:24 2009 -0500 +++ b/tests/test-tags.out Mon Sep 14 17:29:47 2009 -0500 @@ -13,6 +13,9 @@ tip 1:b9154636be93 first 0:acb14030fe0a b9154636be93 tip +% identify with cold cache +b9154636be93 tip +% identify with unwritable cache b9154636be93 tip % create a branch M a