# HG changeset patch # User Matt Mackall # Date 1254982592 18000 # Node ID ceb0f59e1327adbac83bd5f2c1806a19456fd37d # Parent f0417b6ff98a995a15cecea6c39d50ebfafb94a0# Parent 620d6b20ef8557db1669c8efc6c511507f2ff7cd Merge with i18n diff -r 620d6b20ef85 -r ceb0f59e1327 Makefile --- a/Makefile Tue Oct 06 11:18:58 2009 +0300 +++ b/Makefile Thu Oct 08 01:16:32 2009 -0500 @@ -79,16 +79,16 @@ update-pot: i18n/hg.pot -i18n/hg.pot: $(PYTHON_FILES) +i18n/hg.pot: $(PYTHON_FILES) help/*.txt $(PYTHON) i18n/hggettext mercurial/commands.py \ - hgext/*.py hgext/*/__init__.py > i18n/hg.pot + hgext/*.py hgext/*/__init__.py help/*.txt > i18n/hg.pot # All strings marked for translation in Mercurial contain # ASCII characters only. But some files contain string # literals like this '\037\213'. xgettext thinks it has to # parse them even though they are not marked for translation. # Extracting with an explicit encoding of ISO-8859-1 will make # xgettext "parse" and ignore them. - echo $^ | xargs \ + echo $(PYTHON_FILES) | xargs \ xgettext --package-name "Mercurial" \ --msgid-bugs-address "" \ --copyright-holder "Matt Mackall and others" \ diff -r 620d6b20ef85 -r ceb0f59e1327 contrib/bash_completion --- a/contrib/bash_completion Tue Oct 06 11:18:58 2009 +0300 +++ b/contrib/bash_completion Thu Oct 08 01:16:32 2009 -0500 @@ -530,3 +530,20 @@ return } +# shelve +_hg_shelves() +{ + local shelves="$("$hg" unshelve -l . 2>/dev/null)" + local IFS=$'\n' + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$shelves' -- "$cur")) +} + +_hg_cmd_shelve() +{ + _hg_status "mard" +} + +_hg_cmd_unshelve() +{ + _hg_shelves +} diff -r 620d6b20ef85 -r ceb0f59e1327 contrib/shrink-revlog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/shrink-revlog.py Thu Oct 08 01:16:32 2009 -0500 @@ -0,0 +1,218 @@ +#!/usr/bin/env python + +"""\ +Reorder a revlog (by default the the manifest file in the current +repository) to save space. Specifically, this topologically sorts the +revisions in the revlog so that revisions on the same branch are adjacent +as much as possible. This is a workaround for the fact that Mercurial +computes deltas relative to the previous revision rather than relative to a +parent revision. This is *not* safe to run on a changelog. +""" + +# Originally written by Benoit Boissinot +# as a patch to rewrite-log. Cleaned up, refactored, documented, and +# renamed by Greg Ward . + +# XXX would be nice to have a way to verify the repository after shrinking, +# e.g. by comparing "before" and "after" states of random changesets +# (maybe: export before, shrink, export after, diff). + +import sys, os, tempfile +import optparse +from mercurial import ui as ui_, hg, revlog, transaction, node, util + +def toposort(rl): + write = sys.stdout.write + + children = {} + root = [] + # build children and roots + write('reading %d revs ' % len(rl)) + try: + for i in rl: + children[i] = [] + parents = [p for p in rl.parentrevs(i) if p != node.nullrev] + # in case of duplicate parents + if len(parents) == 2 and parents[0] == parents[1]: + del parents[1] + for p in parents: + assert p in children + children[p].append(i) + + if len(parents) == 0: + root.append(i) + + if i % 1000 == 0: + write('.') + finally: + write('\n') + + # XXX this is a reimplementation of the 'branchsort' topo sort + # algorithm in hgext.convert.convcmd... would be nice not to duplicate + # the algorithm + write('sorting ...') + visit = root + ret = [] + while visit: + i = visit.pop(0) + ret.append(i) + if i not in children: + # This only happens if some node's p1 == p2, which can + # happen in the manifest in certain circumstances. + continue + next = [] + for c in children.pop(i): + parents_unseen = [p for p in rl.parentrevs(c) + if p != node.nullrev and p in children] + if len(parents_unseen) == 0: + next.append(c) + visit = next + visit + write('\n') + return ret + +def writerevs(r1, r2, order, tr): + write = sys.stdout.write + write('writing %d revs ' % len(order)) + try: + count = 0 + for rev in order: + n = r1.node(rev) + p1, p2 = r1.parents(n) + l = r1.linkrev(rev) + t = r1.revision(n) + n2 = r2.addrevision(t, tr, l, p1, p2) + + if count % 1000 == 0: + write('.') + count += 1 + finally: + write('\n') + +def report(olddatafn, newdatafn): + oldsize = float(os.stat(olddatafn).st_size) + newsize = float(os.stat(newdatafn).st_size) + + # argh: have to pass an int to %d, because a float >= 2^32 + # blows up under Python 2.5 or earlier + sys.stdout.write('old file size: %12d bytes (%6.1f MiB)\n' + % (int(oldsize), oldsize/1024/1024)) + sys.stdout.write('new file size: %12d bytes (%6.1f MiB)\n' + % (int(newsize), newsize/1024/1024)) + + shrink_percent = (oldsize - newsize) / oldsize * 100 + shrink_factor = oldsize / newsize + sys.stdout.write('shrinkage: %.1f%% (%.1fx)\n' + % (shrink_percent, shrink_factor)) + +def main(): + + # Unbuffer stdout for nice progress output. + sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) + write = sys.stdout.write + + parser = optparse.OptionParser(description=__doc__) + parser.add_option('-R', '--repository', + default=os.path.curdir, + metavar='REPO', + help='repository root directory [default: current dir]') + parser.add_option('--revlog', + metavar='FILE', + help='shrink FILE [default: REPO/hg/store/00manifest.i]') + (options, args) = parser.parse_args() + if args: + parser.error('too many arguments') + + # Open the specified repository. + ui = ui_.ui() + repo = hg.repository(ui, options.repository) + if not repo.local(): + parser.error('not a local repository: %s' % options.repository) + + if options.revlog is None: + indexfn = repo.sjoin('00manifest.i') + else: + if not options.revlog.endswith('.i'): + parser.error('--revlog option must specify the revlog index file ' + '(*.i), not %s' % options.revlog) + + indexfn = os.path.realpath(options.revlog) + store = repo.sjoin('') + if not indexfn.startswith(store): + parser.error('--revlog option must specify a revlog in %s, not %s' + % (store, indexfn)) + + datafn = indexfn[:-2] + '.d' + if not os.path.exists(indexfn): + parser.error('no such file: %s' % indexfn) + if '00changelog' in indexfn: + parser.error('shrinking the changelog will corrupt your repository') + if not os.path.exists(datafn): + # This is just a lazy shortcut because I can't be bothered to + # handle all the special cases that entail from no .d file. + parser.error('%s does not exist: revlog not big enough ' + 'to be worth shrinking' % datafn) + + oldindexfn = indexfn + '.old' + olddatafn = datafn + '.old' + if os.path.exists(oldindexfn) or os.path.exists(olddatafn): + parser.error('one or both of\n' + ' %s\n' + ' %s\n' + 'exists from a previous run; please clean up before ' + 'running again' + % (oldindexfn, olddatafn)) + + write('shrinking %s\n' % indexfn) + prefix = os.path.basename(indexfn)[:-1] + (tmpfd, tmpindexfn) = tempfile.mkstemp(dir=os.path.dirname(indexfn), + prefix=prefix, + suffix='.i') + tmpdatafn = tmpindexfn[:-2] + '.d' + os.close(tmpfd) + + r1 = revlog.revlog(util.opener(os.getcwd(), audit=False), indexfn) + r2 = revlog.revlog(util.opener(os.getcwd(), audit=False), tmpindexfn) + + # Don't use repo.transaction(), because then things get hairy with + # paths: some need to be relative to .hg, and some need to be + # absolute. Doing it this way keeps things simple: everything is an + # absolute path. + lock = repo.lock(wait=False) + tr = transaction.transaction(sys.stderr.write, + open, + repo.sjoin('journal')) + + try: + try: + order = toposort(r1) + writerevs(r1, r2, order, tr) + report(datafn, tmpdatafn) + tr.close() + except: + # Abort transaction first, so we truncate the files before + # deleting them. + tr.abort() + if os.path.exists(tmpindexfn): + os.unlink(tmpindexfn) + if os.path.exists(tmpdatafn): + os.unlink(tmpdatafn) + raise + finally: + lock.release() + + os.link(indexfn, oldindexfn) + os.link(datafn, olddatafn) + os.rename(tmpindexfn, indexfn) + os.rename(tmpdatafn, datafn) + write('note: old revlog saved in:\n' + ' %s\n' + ' %s\n' + '(You can delete those files when you are satisfied that your\n' + 'repository is still sane. ' + 'Running \'hg verify\' is strongly recommended.)\n' + % (oldindexfn, olddatafn)) + +try: + main() +except KeyboardInterrupt: + sys.exit("interrupted") diff -r 620d6b20ef85 -r ceb0f59e1327 doc/gendoc.py --- a/doc/gendoc.py Tue Oct 06 11:18:58 2009 +0300 +++ b/doc/gendoc.py Thu Oct 08 01:16:32 2009 -0500 @@ -1,9 +1,10 @@ -import os, sys, textwrap +import os, sys # import from the live mercurial repo sys.path.insert(0, "..") # fall back to pure modules if required C extensions are not available sys.path.append(os.path.join('..', 'mercurial', 'pure')) from mercurial import demandimport; demandimport.enable() +from mercurial import encoding from mercurial.commands import table, globalopts from mercurial.i18n import _ from mercurial.help import helptable @@ -55,9 +56,9 @@ def show_doc(ui): def section(s): - ui.write("%s\n%s\n\n" % (s, "-" * len(s))) + ui.write("%s\n%s\n\n" % (s, "-" * encoding.colwidth(s))) def subsection(s): - ui.write("%s\n%s\n\n" % (s, '"' * len(s))) + ui.write("%s\n%s\n\n" % (s, '"' * encoding.colwidth(s))) # print options section(_("OPTIONS")) @@ -92,9 +93,7 @@ s = "%-*s %s" % (opts_len, optstr, desc) else: s = optstr - s = textwrap.fill(s, initial_indent=4 * " ", - subsequent_indent=(6 + opts_len) * " ") - ui.write("%s\n" % s) + ui.write(" %s\n" % s) ui.write("\n") # aliases if d['aliases']: diff -r 620d6b20ef85 -r ceb0f59e1327 doc/hg.1.txt --- a/doc/hg.1.txt Tue Oct 06 11:18:58 2009 +0300 +++ b/doc/hg.1.txt Thu Oct 08 01:16:32 2009 -0500 @@ -95,6 +95,6 @@ ------- Copyright \(C) 2005-2009 Matt Mackall. Free use of this software is granted under the terms of the GNU General -Public License (GPL). +Public License version 2. .. include:: common.txt diff -r 620d6b20ef85 -r ceb0f59e1327 doc/hgignore.5.txt --- a/doc/hgignore.5.txt Tue Oct 06 11:18:58 2009 +0300 +++ b/doc/hgignore.5.txt Thu Oct 08 01:16:32 2009 -0500 @@ -106,6 +106,6 @@ This manual page is copyright 2006 Vadim Gelfer. Mercurial is copyright 2005-2009 Matt Mackall. Free use of this software is granted under the terms of the GNU General -Public License (GPL). +Public License version 2. .. include:: common.txt diff -r 620d6b20ef85 -r ceb0f59e1327 doc/hgrc.5.txt --- a/doc/hgrc.5.txt Tue Oct 06 11:18:58 2009 +0300 +++ b/doc/hgrc.5.txt Thu Oct 08 01:16:32 2009 -0500 @@ -946,6 +946,6 @@ This manual page is copyright 2005 Bryan O'Sullivan. Mercurial is copyright 2005-2009 Matt Mackall. Free use of this software is granted under the terms of the GNU General -Public License (GPL). +Public License version 2. .. include:: common.txt diff -r 620d6b20ef85 -r ceb0f59e1327 help/dates.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help/dates.txt Thu Oct 08 01:16:32 2009 -0500 @@ -0,0 +1,36 @@ +Some commands allow the user to specify a date, e.g.: + +- backout, commit, import, tag: Specify the commit date. +- log, revert, update: Select revision(s) by date. + +Many date formats are valid. Here are some examples:: + + "Wed Dec 6 13:18:29 2006" (local timezone assumed) + "Dec 6 13:18 -0600" (year assumed, time offset provided) + "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000) + "Dec 6" (midnight) + "13:18" (today assumed) + "3:39" (3:39AM assumed) + "3:39pm" (15:39) + "2006-12-06 13:18:29" (ISO 8601 format) + "2006-12-6 13:18" + "2006-12-6" + "12-6" + "12/6" + "12/6/6" (Dec 6 2006) + +Lastly, there is Mercurial's internal format:: + + "1165432709 0" (Wed Dec 6 13:18:29 2006 UTC) + +This is the internal representation format for dates. unixtime is the +number of seconds since the epoch (1970-01-01 00:00 UTC). offset is +the offset of the local timezone, in seconds west of UTC (negative if +the timezone is east of UTC). + +The log command also accepts date ranges:: + + "<{datetime}" - at or before a given date/time + ">{datetime}" - on or after a given date/time + "{datetime} to {datetime}" - a date range, inclusive + "-{days}" - within a given number of days of today diff -r 620d6b20ef85 -r ceb0f59e1327 help/diffs.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help/diffs.txt Thu Oct 08 01:16:32 2009 -0500 @@ -0,0 +1,29 @@ +Mercurial's default format for showing changes between two versions of +a file is compatible with the unified format of GNU diff, which can be +used by GNU patch and many other standard tools. + +While this standard format is often enough, it does not encode the +following information: + +- executable status and other permission bits +- copy or rename information +- changes in binary files +- creation or deletion of empty files + +Mercurial also supports the extended diff format from the git VCS +which addresses these limitations. The git diff format is not produced +by default because a few widespread tools still do not understand this +format. + +This means that when generating diffs from a Mercurial repository +(e.g. with "hg export"), you should be careful about things like file +copies and renames or other things mentioned above, because when +applying a standard diff to a different repository, this extra +information is lost. Mercurial's internal operations (like push and +pull) are not affected by this, because they use an internal binary +format for communicating changes. + +To make Mercurial produce the git extended diff format, use the --git +option available for many commands, or set 'git = True' in the [diff] +section of your hgrc. You do not need to set this option when +importing diffs in this format or using them in the mq extension. diff -r 620d6b20ef85 -r ceb0f59e1327 help/environment.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help/environment.txt Thu Oct 08 01:16:32 2009 -0500 @@ -0,0 +1,76 @@ +HG + Path to the 'hg' executable, automatically passed when running + hooks, extensions or external tools. If unset or empty, this is + the hg executable's name if it's frozen, or an executable named + 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on + Windows) is searched. + +HGEDITOR + This is the name of the editor to run when committing. See EDITOR. + + (deprecated, use .hgrc) + +HGENCODING + This overrides the default locale setting detected by Mercurial. + This setting is used to convert data including usernames, + changeset descriptions, tag names, and branches. This setting can + be overridden with the --encoding command-line option. + +HGENCODINGMODE + This sets Mercurial's behavior for handling unknown characters + while transcoding user input. The default is "strict", which + causes Mercurial to abort if it can't map a character. Other + settings include "replace", which replaces unknown characters, and + "ignore", which drops them. This setting can be overridden with + the --encodingmode command-line option. + +HGMERGE + An executable to use for resolving merge conflicts. The program + will be executed with three arguments: local file, remote file, + ancestor file. + + (deprecated, use .hgrc) + +HGRCPATH + A list of files or directories to search for hgrc files. Item + separator is ":" on Unix, ";" on Windows. If HGRCPATH is not set, + platform default search path is used. If empty, only the .hg/hgrc + from the current repository is read. + + For each element in HGRCPATH: + + - if it's a directory, all files ending with .rc are added + - otherwise, the file itself will be added + +HGUSER + This is the string used as the author of a commit. If not set, + available values will be considered in this order: + + - HGUSER (deprecated) + - hgrc files from the HGRCPATH + - EMAIL + - interactive prompt + - LOGNAME (with '@hostname' appended) + + (deprecated, use .hgrc) + +EMAIL + May be used as the author of a commit; see HGUSER. + +LOGNAME + May be used as the author of a commit; see HGUSER. + +VISUAL + This is the name of the editor to use when committing. See EDITOR. + +EDITOR + Sometimes Mercurial needs to open a text file in an editor for a + user to modify, for example when writing commit messages. The + editor it uses is determined by looking at the environment + variables HGEDITOR, VISUAL and EDITOR, in that order. The first + non-empty one is chosen. If all of them are empty, the editor + defaults to 'vi'. + +PYTHONPATH + This is used by Python to find imported modules and may need to be + set appropriately if this Mercurial is not installed system-wide. diff -r 620d6b20ef85 -r ceb0f59e1327 help/extensions.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help/extensions.txt Thu Oct 08 01:16:32 2009 -0500 @@ -0,0 +1,33 @@ +Mercurial has the ability to add new features through the use of +extensions. Extensions may add new commands, add options to +existing commands, change the default behavior of commands, or +implement hooks. + +Extensions are not loaded by default for a variety of reasons: +they can increase startup overhead; they may be meant for advanced +usage only; they may provide potentially dangerous abilities (such +as letting you destroy or modify history); they might not be ready +for prime time; or they may alter some usual behaviors of stock +Mercurial. It is thus up to the user to activate extensions as +needed. + +To enable the "foo" extension, either shipped with Mercurial or in +the Python search path, create an entry for it in your hgrc, like +this:: + + [extensions] + foo = + +You may also specify the full path to an extension:: + + [extensions] + myfeature = ~/.hgext/myfeature.py + +To explicitly disable an extension enabled in an hgrc of broader +scope, prepend its path with !:: + + [extensions] + # disabling extension bar residing in /path/to/extension/bar.py + hgext.bar = !/path/to/extension/bar.py + # ditto, but no path was supplied for extension baz + hgext.baz = ! diff -r 620d6b20ef85 -r ceb0f59e1327 help/multirevs.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help/multirevs.txt Thu Oct 08 01:16:32 2009 -0500 @@ -0,0 +1,13 @@ +When Mercurial accepts more than one revision, they may be specified +individually, or provided as a topologically continuous range, +separated by the ":" character. + +The syntax of range notation is [BEGIN]:[END], where BEGIN and END are +revision identifiers. Both BEGIN and END are optional. If BEGIN is not +specified, it defaults to revision number 0. If END is not specified, +it defaults to the tip. The range ":" thus means "all revisions". + +If BEGIN is greater than END, revisions are treated in reverse order. + +A range acts as a closed interval. This means that a range of 3:5 +gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6. diff -r 620d6b20ef85 -r ceb0f59e1327 help/patterns.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help/patterns.txt Thu Oct 08 01:16:32 2009 -0500 @@ -0,0 +1,41 @@ +Mercurial accepts several notations for identifying one or more files +at a time. + +By default, Mercurial treats filenames as shell-style extended glob +patterns. + +Alternate pattern notations must be specified explicitly. + +To use a plain path name without any pattern matching, start it with +"path:". These path names must completely match starting at the +current repository root. + +To use an extended glob, start a name with "glob:". Globs are rooted +at the current directory; a glob such as "``*.c``" will only match +files in the current directory ending with ".c". + +The supported glob syntax extensions are "``**``" to match any string +across path separators and "{a,b}" to mean "a or b". + +To use a Perl/Python regular expression, start a name with "re:". +Regexp pattern matching is anchored at the root of the repository. + +Plain examples:: + + path:foo/bar a name bar in a directory named foo in the root + of the repository + path:path:name a file or directory named "path:name" + +Glob examples:: + + glob:*.c any name ending in ".c" in the current directory + *.c any name ending in ".c" in the current directory + **.c any name ending in ".c" in any subdirectory of the + current directory including itself. + foo/*.c any name ending in ".c" in the directory foo + foo/**.c any name ending in ".c" in any subdirectory of foo + including itself. + +Regexp examples:: + + re:.*\.c$ any name ending in ".c", anywhere in the repository diff -r 620d6b20ef85 -r ceb0f59e1327 help/revisions.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help/revisions.txt Thu Oct 08 01:16:32 2009 -0500 @@ -0,0 +1,29 @@ +Mercurial supports several ways to specify individual revisions. + +A plain integer is treated as a revision number. Negative integers are +treated as sequential offsets from the tip, with -1 denoting the tip, +-2 denoting the revision prior to the tip, and so forth. + +A 40-digit hexadecimal string is treated as a unique revision +identifier. + +A hexadecimal string less than 40 characters long is treated as a +unique revision identifier and is referred to as a short-form +identifier. A short-form identifier is only valid if it is the prefix +of exactly one full-length identifier. + +Any other string is treated as a tag or branch name. A tag name is a +symbolic name associated with a revision identifier. A branch name +denotes the tipmost revision of that branch. Tag and branch names must +not contain the ":" character. + +The reserved name "tip" is a special tag that always identifies the +most recent revision. + +The reserved name "null" indicates the null revision. This is the +revision of an empty repository, and the parent of revision 0. + +The reserved name "." indicates the working directory parent. If no +working directory is checked out, it is equivalent to null. If an +uncommitted merge is in progress, "." is the revision of the first +parent. diff -r 620d6b20ef85 -r ceb0f59e1327 help/templates.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help/templates.txt Thu Oct 08 01:16:32 2009 -0500 @@ -0,0 +1,113 @@ +Mercurial allows you to customize output of commands through +templates. You can either pass in a template from the command +line, via the --template option, or select an existing +template-style (--style). + +You can customize output for any "log-like" command: log, +outgoing, incoming, tip, parents, heads and glog. + +Three styles are packaged with Mercurial: default (the style used +when no explicit preference is passed), compact and changelog. +Usage:: + + $ hg log -r1 --style changelog + +A template is a piece of text, with markup to invoke variable +expansion:: + + $ hg log -r1 --template "{node}\n" + b56ce7b07c52de7d5fd79fb89701ea538af65746 + +Strings in curly braces are called keywords. The availability of +keywords depends on the exact context of the templater. These +keywords are usually available for templating a log-like command: + +:author: String. The unmodified author of the changeset. +:branches: String. The name of the branch on which the changeset + was committed. Will be empty if the branch name was + default. +:date: Date information. The date when the changeset was + committed. +:desc: String. The text of the changeset description. +:diffstat: String. Statistics of changes with the following + format: "modified files: +added/-removed lines" +:files: List of strings. All files modified, added, or removed + by this changeset. +:file_adds: List of strings. Files added by this changeset. +:file_mods: List of strings. Files modified by this changeset. +:file_dels: List of strings. Files removed by this changeset. +:node: String. The changeset identification hash, as a + 40-character hexadecimal string. +:parents: List of strings. The parents of the changeset. +:rev: Integer. The repository-local changeset revision + number. +:tags: List of strings. Any tags associated with the + changeset. +:latesttag: String. Most recent global tag in the ancestors of this + changeset. +:latesttagdistance: Integer. Longest path to the latest tag. + +The "date" keyword does not produce human-readable output. If you +want to use a date in your output, you can use a filter to process +it. Filters are functions which return a string based on the input +variable. You can also use a chain of filters to get the desired +output:: + + $ hg tip --template "{date|isodate}\n" + 2008-08-21 18:22 +0000 + +List of filters: + +:addbreaks: Any text. Add an XHTML "
" tag before the end of + every line except the last. +:age: Date. Returns a human-readable date/time difference + between the given date/time and the current + date/time. +:basename: Any text. Treats the text as a path, and returns the + last component of the path after splitting by the + path separator (ignoring trailing separators). For + example, "foo/bar/baz" becomes "baz" and "foo/bar//" + becomes "bar". +:stripdir: Treat the text as path and strip a directory level, + if possible. For example, "foo" and "foo/bar" becomes + "foo". +:date: Date. Returns a date in a Unix date format, including + the timezone: "Mon Sep 04 15:13:13 2006 0700". +:domain: Any text. Finds the first string that looks like an + email address, and extracts just the domain + component. Example: 'User ' becomes + 'example.com'. +:email: Any text. Extracts the first string that looks like + an email address. Example: 'User ' + becomes 'user@example.com'. +:escape: Any text. Replaces the special XML/XHTML characters + "&", "<" and ">" with XML entities. +:fill68: Any text. Wraps the text to fit in 68 columns. +:fill76: Any text. Wraps the text to fit in 76 columns. +:firstline: Any text. Returns the first line of text. +:nonempty: Any text. Returns '(none)' if the string is empty. +:hgdate: Date. Returns the date as a pair of numbers: + "1157407993 25200" (Unix timestamp, timezone offset). +:isodate: Date. Returns the date in ISO 8601 format: + "2009-08-18 13:00 +0200". +:isodatesec: Date. Returns the date in ISO 8601 format, including + seconds: "2009-08-18 13:00:13 +0200". See also the + rfc3339date filter. +:localdate: Date. Converts a date to local date. +:obfuscate: Any text. Returns the input text rendered as a + sequence of XML entities. +:person: Any text. Returns the text before an email address. +:rfc822date: Date. Returns a date using the same format used in + email headers: "Tue, 18 Aug 2009 13:00:13 +0200". +:rfc3339date: Date. Returns a date using the Internet date format + specified in RFC 3339: "2009-08-18T13:00:13+02:00". +:short: Changeset hash. Returns the short form of a changeset + hash, i.e. a 12-byte hexadecimal string. +:shortdate: Date. Returns a date like "2006-09-18". +:strip: Any text. Strips all leading and trailing whitespace. +:tabindent: Any text. Returns the text, with every line except + the first starting with a tab character. +:urlescape: Any text. Escapes all "special" characters. For + example, "foo bar" becomes "foo%20bar". +:user: Any text. Returns the user portion of an email + address. diff -r 620d6b20ef85 -r ceb0f59e1327 help/urls.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help/urls.txt Thu Oct 08 01:16:32 2009 -0500 @@ -0,0 +1,63 @@ +Valid URLs are of the form:: + + local/filesystem/path[#revision] + file://local/filesystem/path[#revision] + http://[user[:pass]@]host[:port]/[path][#revision] + https://[user[:pass]@]host[:port]/[path][#revision] + ssh://[user[:pass]@]host[:port]/[path][#revision] + +Paths in the local filesystem can either point to Mercurial +repositories or to bundle files (as created by 'hg bundle' or 'hg +incoming --bundle'). + +An optional identifier after # indicates a particular branch, tag, or +changeset to use from the remote repository. See also 'hg help +revisions'. + +Some features, such as pushing to http:// and https:// URLs are only +possible if the feature is explicitly enabled on the remote Mercurial +server. + +Some notes about using SSH with Mercurial: + +- SSH requires an accessible shell account on the destination machine + and a copy of hg in the remote path or specified with as remotecmd. +- path is relative to the remote user's home directory by default. Use + an extra slash at the start of a path to specify an absolute path:: + + ssh://example.com//tmp/repository + +- Mercurial doesn't use its own compression via SSH; the right thing + to do is to configure it in your ~/.ssh/config, e.g.:: + + Host *.mylocalnetwork.example.com + Compression no + Host * + Compression yes + + Alternatively specify "ssh -C" as your ssh command in your hgrc or + with the --ssh command line option. + +These URLs can all be stored in your hgrc with path aliases under the +[paths] section like so:: + + [paths] + alias1 = URL1 + alias2 = URL2 + ... + +You can then use the alias for any command that uses a URL (for +example 'hg pull alias1' would pull from the 'alias1' path). + +Two path aliases are special because they are used as defaults when +you do not provide the URL to a command: + +default: + When you create a repository with hg clone, the clone command saves + the location of the source repository as the new repository's + 'default' path. This is then used when you omit path from push- and + pull-like commands (including incoming and outgoing). + +default-push: + The push command will look for a path named 'default-push', and + prefer it over 'default' if both are defined. diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/acl.py --- a/hgext/acl.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/acl.py Thu Oct 08 01:16:32 2009 -0500 @@ -60,12 +60,12 @@ def buildmatch(ui, repo, user, key): '''return tuple of (match function, list enabled).''' if not ui.has_section(key): - ui.debug(_('acl: %s not enabled\n') % key) + ui.debug('acl: %s not enabled\n' % key) return None pats = [pat for pat, users in ui.configitems(key) if user in users.replace(',', ' ').split()] - ui.debug(_('acl: %s enabled, %d entries for user %s\n') % + ui.debug('acl: %s enabled, %d entries for user %s\n' % (key, len(pats), user)) if pats: return match.match(repo.root, '', pats) @@ -77,7 +77,7 @@ raise util.Abort(_('config error - hook type "%s" cannot stop ' 'incoming changesets') % hooktype) if source not in ui.config('acl', 'sources', 'serve').split(): - ui.debug(_('acl: changes have source "%s" - skipping\n') % source) + ui.debug('acl: changes have source "%s" - skipping\n' % source) return user = None @@ -99,9 +99,9 @@ ctx = repo[rev] for f in ctx.files(): if deny and deny(f): - ui.debug(_('acl: user %s denied on %s\n') % (user, f)) + ui.debug('acl: user %s denied on %s\n' % (user, f)) raise util.Abort(_('acl: access denied for changeset %s') % ctx) if allow and not allow(f): - ui.debug(_('acl: user %s not allowed on %s\n') % (user, f)) + ui.debug('acl: user %s not allowed on %s\n' % (user, f)) raise util.Abort(_('acl: access denied for changeset %s') % ctx) - ui.debug(_('acl: allowing changeset %s\n') % ctx) + ui.debug('acl: allowing changeset %s\n' % ctx) diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/churn.py --- a/hgext/churn.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/churn.py Thu Oct 08 01:16:32 2009 -0500 @@ -153,7 +153,7 @@ maxname = max(len(k) for k, v in rate) ttywidth = util.termwidth() - ui.debug(_("assuming %i character terminal\n") % ttywidth) + ui.debug("assuming %i character terminal\n" % ttywidth) width = ttywidth - maxname - 2 - 6 - 2 - 2 for date, count in rate: diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/color.py --- a/hgext/color.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/color.py Thu Oct 08 01:16:32 2009 -0500 @@ -160,25 +160,26 @@ return retval _patch_effects = { 'applied': ['blue', 'bold', 'underline'], - 'missing': ['red', 'bold'], - 'unapplied': ['black', 'bold'], } - -def colorwrap(orig, s): + 'missing': ['red', 'bold'], + 'unapplied': ['black', 'bold'], } +def colorwrap(orig, *args): '''wrap ui.write for colored diff output''' - lines = s.split('\n') - for i, line in enumerate(lines): - stripline = line - if line and line[0] in '+-': - # highlight trailing whitespace, but only in changed lines - stripline = line.rstrip() - for prefix, style in _diff_prefixes: - if stripline.startswith(prefix): - lines[i] = render_effects(stripline, _diff_effects[style]) - break - if line != stripline: - lines[i] += render_effects( - line[len(stripline):], _diff_effects['trailingwhitespace']) - orig('\n'.join(lines)) + def _colorize(s): + lines = s.split('\n') + for i, line in enumerate(lines): + stripline = line + if line and line[0] in '+-': + # highlight trailing whitespace, but only in changed lines + stripline = line.rstrip() + for prefix, style in _diff_prefixes: + if stripline.startswith(prefix): + lines[i] = render_effects(stripline, _diff_effects[style]) + break + if line != stripline: + lines[i] += render_effects( + line[len(stripline):], _diff_effects['trailingwhitespace']) + return '\n'.join(lines) + orig(*[_colorize(s) for s in args]) def colorshowpatch(orig, self, node): '''wrap cmdutil.changeset_printer.showpatch with colored output''' @@ -235,6 +236,13 @@ # The mq extension is not enabled pass + try: + rec = extensions.find('record') + _setupcmd(ui, 'record', rec.cmdtable, colordiff, _diff_effects) + except KeyError: + # The record extension is not enabled + pass + def _setupcmd(ui, cmd, table, func, effectsmap): '''patch in command to command table and load effect map''' def nocolor(orig, *args, **opts): @@ -256,7 +264,7 @@ entry = extensions.wrapcommand(table, cmd, nocolor) entry[1].extend([ ('', 'color', 'auto', _("when to colorize (always, auto, or never)")), - ('', 'no-color', None, _("don't colorize output")), + ('', 'no-color', None, _("don't colorize output (DEPRECATED)")), ]) for status in effectsmap: diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/convert/__init__.py --- a/hgext/convert/__init__.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/convert/__init__.py Thu Oct 08 01:16:32 2009 -0500 @@ -142,23 +142,8 @@ converted, and that any directory reorganization in the CVS sandbox is ignored. - Because CVS does not have changesets, it is necessary to collect - individual commits to CVS and merge them into changesets. CVS - source uses its internal changeset merging code by default but can - be configured to call the external 'cvsps' program by setting:: - - --config convert.cvsps='cvsps -A -u --cvs-direct -q' - - This option is deprecated and will be removed in Mercurial 1.4. - The options shown are the defaults. - Internal cvsps is selected by setting :: - - --config convert.cvsps=builtin - - and has a few more configurable options: - --config convert.cvsps.cache=True (boolean) Set to False to disable remote log caching, for testing and debugging purposes. @@ -178,9 +163,10 @@ add the most recent revision on the branch indicated in the regex as the second parent of the changeset. - The hgext/convert/cvsps wrapper script allows the builtin + An additional "debugcvsps" Mercurial command allows the builtin changeset merging code to be run without doing a conversion. Its - parameters and output are similar to that of cvsps 2.1. + parameters and output are similar to that of cvsps 2.1. Please see + the command help for more details. Subversion Source ----------------- diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/convert/common.py --- a/hgext/convert/common.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/convert/common.py Thu Oct 08 01:16:32 2009 -0500 @@ -266,7 +266,7 @@ def _run(self, cmd, *args, **kwargs): cmdline = self._cmdline(cmd, *args, **kwargs) - self.ui.debug(_('running: %s\n') % (cmdline,)) + self.ui.debug('running: %s\n' % (cmdline,)) self.prerun() try: return util.popen(cmdline) @@ -365,7 +365,7 @@ return for i, line in enumerate(fp): try: - key, value = line[:-1].rsplit(' ', 1) + key, value = line.splitlines()[0].rsplit(' ', 1) except ValueError: raise util.Abort(_('syntax error in %s(%d): key/value pair expected') % (self.path, i+1)) diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/convert/cvs.py --- a/hgext/convert/cvs.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/convert/cvs.py Thu Oct 08 01:16:32 2009 -0500 @@ -22,21 +22,11 @@ raise NoRepo("%s does not look like a CVS checkout" % path) checktool('cvs') - self.cmd = ui.config('convert', 'cvsps', 'builtin') - cvspsexe = self.cmd.split(None, 1)[0] - self.builtin = cvspsexe == 'builtin' - if not self.builtin: - ui.warn(_('warning: support for external cvsps is deprecated and ' - 'will be removed in Mercurial 1.4\n')) - - if not self.builtin: - checktool(cvspsexe) self.changeset = None self.files = {} self.tags = {} self.lastbranch = {} - self.parent = {} self.socket = None self.cvsroot = open(os.path.join(cvs, "Root")).read()[:-1] self.cvsrepo = open(os.path.join(cvs, "Repository")).read()[:-1] @@ -50,19 +40,13 @@ self.changeset = {} maxrev = 0 - cmd = self.cmd if self.rev: # TODO: handle tags try: # patchset number? maxrev = int(self.rev) except ValueError: - try: - # date - util.parsedate(self.rev, ['%Y/%m/%d %H:%M:%S']) - cmd = '%s -d "1970/01/01 00:00:01" -d "%s"' % (cmd, self.rev) - except util.Abort: - raise util.Abort(_('revision %s is not a patchset number or date') % self.rev) + raise util.Abort(_('revision %s is not a patchset number') % self.rev) d = os.getcwd() try: @@ -71,116 +55,36 @@ state = 0 filerevids = {} - if self.builtin: - # builtin cvsps code - self.ui.status(_('using builtin cvsps\n')) - - cache = 'update' - if not self.ui.configbool('convert', 'cvsps.cache', True): - cache = None - db = cvsps.createlog(self.ui, cache=cache) - db = cvsps.createchangeset(self.ui, db, - fuzz=int(self.ui.config('convert', 'cvsps.fuzz', 60)), - mergeto=self.ui.config('convert', 'cvsps.mergeto', None), - mergefrom=self.ui.config('convert', 'cvsps.mergefrom', None)) - - for cs in db: - if maxrev and cs.id>maxrev: - break - id = str(cs.id) - cs.author = self.recode(cs.author) - self.lastbranch[cs.branch] = id - cs.comment = self.recode(cs.comment) - date = util.datestr(cs.date) - self.tags.update(dict.fromkeys(cs.tags, id)) - - files = {} - for f in cs.entries: - files[f.file] = "%s%s" % ('.'.join([str(x) for x in f.revision]), - ['', '(DEAD)'][f.dead]) + cache = 'update' + if not self.ui.configbool('convert', 'cvsps.cache', True): + cache = None + db = cvsps.createlog(self.ui, cache=cache) + db = cvsps.createchangeset(self.ui, db, + fuzz=int(self.ui.config('convert', 'cvsps.fuzz', 60)), + mergeto=self.ui.config('convert', 'cvsps.mergeto', None), + mergefrom=self.ui.config('convert', 'cvsps.mergefrom', None)) - # add current commit to set - c = commit(author=cs.author, date=date, - parents=[str(p.id) for p in cs.parents], - desc=cs.comment, branch=cs.branch or '') - self.changeset[id] = c - self.files[id] = files - else: - # external cvsps - for l in util.popen(cmd): - if state == 0: # header - if l.startswith("PatchSet"): - id = l[9:-2] - if maxrev and int(id) > maxrev: - # ignore everything - state = 3 - elif l.startswith("Date:"): - date = util.parsedate(l[6:-1], ["%Y/%m/%d %H:%M:%S"]) - date = util.datestr(date) - elif l.startswith("Branch:"): - branch = l[8:-1] - self.parent[id] = self.lastbranch.get(branch, 'bad') - self.lastbranch[branch] = id - elif l.startswith("Ancestor branch:"): - ancestor = l[17:-1] - # figure out the parent later - self.parent[id] = self.lastbranch[ancestor] - elif l.startswith("Author:"): - author = self.recode(l[8:-1]) - elif l.startswith("Tag:") or l.startswith("Tags:"): - t = l[l.index(':')+1:] - t = [ut.strip() for ut in t.split(',')] - if (len(t) > 1) or (t[0] and (t[0] != "(none)")): - self.tags.update(dict.fromkeys(t, id)) - elif l.startswith("Log:"): - # switch to gathering log - state = 1 - log = "" - elif state == 1: # log - if l == "Members: \n": - # switch to gathering members - files = {} - oldrevs = [] - log = self.recode(log[:-1]) - state = 2 - else: - # gather log - log += l - elif state == 2: # members - if l == "\n": # start of next entry - state = 0 - p = [self.parent[id]] - if id == "1": - p = [] - if branch == "HEAD": - branch = "" - if branch: - latest = 0 - # the last changeset that contains a base - # file is our parent - for r in oldrevs: - latest = max(filerevids.get(r, 0), latest) - if latest: - p = [latest] + for cs in db: + if maxrev and cs.id>maxrev: + break + id = str(cs.id) + cs.author = self.recode(cs.author) + self.lastbranch[cs.branch] = id + cs.comment = self.recode(cs.comment) + date = util.datestr(cs.date) + self.tags.update(dict.fromkeys(cs.tags, id)) - # add current commit to set - c = commit(author=author, date=date, parents=p, - desc=log, branch=branch) - self.changeset[id] = c - self.files[id] = files - else: - colon = l.rfind(':') - file = l[1:colon] - rev = l[colon+1:-2] - oldrev, rev = rev.split("->") - files[file] = rev + files = {} + for f in cs.entries: + files[f.file] = "%s%s" % ('.'.join([str(x) for x in f.revision]), + ['', '(DEAD)'][f.dead]) - # save some information for identifying branch points - oldrevs.append("%s:%s" % (oldrev, file)) - filerevids["%s:%s" % (rev, file)] = id - elif state == 3: - # swallow all input - continue + # add current commit to set + c = commit(author=cs.author, date=date, + parents=[str(p.id) for p in cs.parents], + desc=cs.comment, branch=cs.branch or '') + self.changeset[id] = c + self.files[id] = files self.heads = self.lastbranch.values() finally: diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/convert/cvsps.py --- a/hgext/convert/cvsps.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/convert/cvsps.py Thu Oct 08 01:16:32 2009 -0500 @@ -199,7 +199,7 @@ cmd = [util.shellquote(arg) for arg in cmd] ui.note(_("running %s\n") % (' '.join(cmd))) - ui.debug(_("prefix=%r directory=%r root=%r\n") % (prefix, directory, root)) + ui.debug("prefix=%r directory=%r root=%r\n" % (prefix, directory, root)) pfp = util.popen(' '.join(cmd)) peek = pfp.readline() @@ -378,7 +378,7 @@ e.revision[-1] == 1 and # 1.1 or 1.1.x.1 len(e.comment) == 1 and file_added_re.match(e.comment[0])): - ui.debug(_('found synthetic revision in %s: %r\n') + ui.debug('found synthetic revision in %s: %r\n' % (e.rcs, e.comment[0])) e.synthetic = True diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/convert/darcs.py --- a/hgext/convert/darcs.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/convert/darcs.py Thu Oct 08 01:16:32 2009 -0500 @@ -75,7 +75,7 @@ self.parents[child] = [] def after(self): - self.ui.debug(_('cleaning up %s\n') % self.tmppath) + self.ui.debug('cleaning up %s\n' % self.tmppath) shutil.rmtree(self.tmppath, ignore_errors=True) def xml(self, cmd, **kwargs): @@ -85,6 +85,17 @@ self.checkexit(fp.close()) return etree.getroot() + def manifest(self): + man = [] + output, status = self.run('show', 'files', no_directories=True, + repodir=self.tmppath) + self.checkexit(status) + for line in output.split('\n'): + path = line[2:] + if path: + man.append(path) + return man + def getheads(self): return self.parents[None] @@ -107,18 +118,35 @@ output, status = self.run('revert', all=True, repodir=self.tmppath) self.checkexit(status, output) - def getchanges(self, rev): - self.pull(rev) + def getchanges(self, rev): copies = {} changes = [] + man = None for elt in self.changes[rev].find('summary').getchildren(): if elt.tag in ('add_directory', 'remove_directory'): continue if elt.tag == 'move': - changes.append((elt.get('from'), rev)) - copies[elt.get('from')] = elt.get('to') + if man is None: + man = self.manifest() + source, dest = elt.get('from'), elt.get('to') + if source in man: + # File move + changes.append((source, rev)) + changes.append((dest, rev)) + copies[dest] = source + else: + # Directory move, deduce file moves from manifest + source = source + '/' + for f in man: + if not f.startswith(source): + continue + fdest = dest + '/' + f[len(source):] + changes.append((f, rev)) + changes.append((fdest, rev)) + copies[fdest] = f else: changes.append((elt.text.strip(), rev)) + self.pull(rev) self.lastrev = rev return sorted(changes), copies diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/convert/gnuarch.py --- a/hgext/convert/gnuarch.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/convert/gnuarch.py Thu Oct 08 01:16:32 2009 -0500 @@ -125,7 +125,7 @@ break def after(self): - self.ui.debug(_('cleaning up %s\n') % self.tmppath) + self.ui.debug('cleaning up %s\n' % self.tmppath) shutil.rmtree(self.tmppath, ignore_errors=True) def getheads(self): @@ -195,7 +195,7 @@ return os.system(cmdline) def _update(self, rev): - self.ui.debug(_('applying revision %s...\n') % rev) + self.ui.debug('applying revision %s...\n' % rev) changeset, status = self.runlines('replay', '-d', self.tmppath, rev) if status: @@ -205,7 +205,7 @@ self._obtainrevision(rev) else: old_rev = self.parents[rev][0] - self.ui.debug(_('computing changeset between %s and %s...\n') + self.ui.debug('computing changeset between %s and %s...\n' % (old_rev, rev)) self._parsechangeset(changeset, rev) @@ -254,10 +254,10 @@ return changes, copies def _obtainrevision(self, rev): - self.ui.debug(_('obtaining revision %s...\n') % rev) + self.ui.debug('obtaining revision %s...\n' % rev) output = self._execute('get', rev, self.tmppath) self.checkexit(output) - self.ui.debug(_('analyzing revision %s...\n') % rev) + self.ui.debug('analyzing revision %s...\n' % rev) files = self._readcontents(self.tmppath) self.changes[rev].add_files += files diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/convert/hg.py --- a/hgext/convert/hg.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/convert/hg.py Thu Oct 08 01:16:32 2009 -0500 @@ -55,12 +55,12 @@ self.filemapmode = False def before(self): - self.ui.debug(_('run hg sink pre-conversion action\n')) + self.ui.debug('run hg sink pre-conversion action\n') self.wlock = self.repo.wlock() self.lock = self.repo.lock() def after(self): - self.ui.debug(_('run hg sink post-conversion action\n')) + self.ui.debug('run hg sink post-conversion action\n') self.lock.release() self.wlock.release() @@ -248,8 +248,7 @@ return self.lastctx def parents(self, ctx): - return [p.node() for p in ctx.parents() - if p and self.keep(p.node())] + return [p for p in ctx.parents() if p and self.keep(p.node())] def getheads(self): if self.rev: @@ -275,20 +274,20 @@ if self.ignoreerrors: # calling getcopies() is a simple way to detect missing # revlogs and populate self.ignored - self.getcopies(ctx, files) + self.getcopies(ctx, parents, files) return [(f, rev) for f in files if f not in self.ignored], {} if self._changescache and self._changescache[0] == rev: m, a, r = self._changescache[1] else: - m, a, r = self.repo.status(parents[0], ctx.node())[:3] + m, a, r = self.repo.status(parents[0].node(), ctx.node())[:3] # getcopies() detects missing revlogs early, run it before # filtering the changes. - copies = self.getcopies(ctx, m + a) + copies = self.getcopies(ctx, parents, m + a) changes = [(name, rev) for name in m + a + r if name not in self.ignored] return sorted(changes), copies - def getcopies(self, ctx, files): + def getcopies(self, ctx, parents, files): copies = {} for name in files: if name in self.ignored: @@ -297,6 +296,14 @@ copysource, copynode = ctx.filectx(name).renamed() if copysource in self.ignored or not self.keep(copynode): continue + # Ignore copy sources not in parent revisions + found = False + for p in parents: + if copysource in p: + found = True + break + if not found: + continue copies[name] = copysource except TypeError: pass @@ -309,7 +316,7 @@ def getcommit(self, rev): ctx = self.changectx(rev) - parents = [hex(p) for p in self.parents(ctx)] + parents = [p.hex() for p in self.parents(ctx)] if self.saverev: crev = rev else: @@ -332,7 +339,7 @@ changes = [], ctx.manifest().keys(), [] else: i = i or 0 - changes = self.repo.status(parents[i], ctx.node())[:3] + changes = self.repo.status(parents[i].node(), ctx.node())[:3] changes = [[f for f in l if f not in self.ignored] for l in changes] if i == 0: @@ -348,10 +355,10 @@ self.convertfp.flush() def before(self): - self.ui.debug(_('run hg source pre-conversion action\n')) + self.ui.debug('run hg source pre-conversion action\n') def after(self): - self.ui.debug(_('run hg source post-conversion action\n')) + self.ui.debug('run hg source post-conversion action\n') def hasnativeorder(self): return True diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/convert/subversion.py --- a/hgext/convert/subversion.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/convert/subversion.py Thu Oct 08 01:16:32 2009 -0500 @@ -22,6 +22,7 @@ from common import commandline, converter_source, converter_sink, mapfile try: + raise ImportError("SVN support disabled due to license incompatibility") from svn.core import SubversionException, Pool import svn import svn.client @@ -152,11 +153,13 @@ def issvnurl(url): try: proto, path = url.split('://', 1) - path = urllib.url2pathname(path) + if proto == 'file': + path = urllib.url2pathname(path) except ValueError: proto = 'file' path = os.path.abspath(url) - path = path.replace(os.sep, '/') + if proto == 'file': + path = path.replace(os.sep, '/') check = protomap.get(proto, lambda p, p2: False) while '/' in path: if check(path, proto): @@ -531,7 +534,7 @@ """ if not path.startswith(self.rootmodule): # Requests on foreign branches may be forbidden at server level - self.ui.debug(_('ignoring foreign branch %r\n') % path) + self.ui.debug('ignoring foreign branch %r\n' % path) return None if not stop: @@ -559,7 +562,7 @@ if not path.startswith(p) or not paths[p].copyfrom_path: continue newpath = paths[p].copyfrom_path + path[len(p):] - self.ui.debug(_("branch renamed from %s to %s at %d\n") % + self.ui.debug("branch renamed from %s to %s at %d\n" % (path, newpath, revnum)) path = newpath break @@ -567,7 +570,7 @@ stream.close() if not path.startswith(self.rootmodule): - self.ui.debug(_('ignoring foreign branch %r\n') % path) + self.ui.debug('ignoring foreign branch %r\n' % path) return None return self.revid(dirent.created_rev, path) @@ -579,7 +582,7 @@ prevmodule = self.prevmodule if prevmodule is None: prevmodule = '' - self.ui.debug(_("reparent to %s\n") % svnurl) + self.ui.debug("reparent to %s\n" % svnurl) svn.ra.reparent(self.ra, svnurl) self.prevmodule = module return prevmodule @@ -612,14 +615,14 @@ copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule) if not copyfrom_path: continue - self.ui.debug(_("copied to %s from %s@%s\n") % + self.ui.debug("copied to %s from %s@%s\n" % (entrypath, copyfrom_path, ent.copyfrom_rev)) copies[self.recode(entrypath)] = self.recode(copyfrom_path) elif kind == 0: # gone, but had better be a deleted *file* - self.ui.debug(_("gone from %s\n") % ent.copyfrom_rev) + self.ui.debug("gone from %s\n" % ent.copyfrom_rev) pmodule, prevnum = self.revsplit(parents[0])[1:] parentpath = pmodule + "/" + entrypath - self.ui.debug(_("entry %s\n") % parentpath) + self.ui.debug("entry %s\n" % parentpath) # We can avoid the reparent calls if the module has # not changed but it probably does not worth the pain. @@ -646,7 +649,7 @@ del copies[childpath] entries.append(childpath) else: - self.ui.debug(_('unknown path in revision %d: %s\n') % \ + self.ui.debug('unknown path in revision %d: %s\n' % \ (revnum, path)) elif kind == svn.core.svn_node_dir: # If the directory just had a prop change, @@ -679,7 +682,7 @@ if not copyfrompath: continue copyfrom[path] = ent - self.ui.debug(_("mark %s came from %s:%d\n") + self.ui.debug("mark %s came from %s:%d\n" % (path, copyfrompath, ent.copyfrom_rev)) children = self._find_children(ent.copyfrom_path, ent.copyfrom_rev) children.sort() @@ -703,7 +706,7 @@ """Return the parsed commit object or None, and True if the revision is a branch root. """ - self.ui.debug(_("parsing revision %d (%d changes)\n") % + self.ui.debug("parsing revision %d (%d changes)\n" % (revnum, len(orig_paths))) branched = False @@ -732,7 +735,7 @@ self.ui.note(_('found parent of branch %s at %d: %s\n') % (self.module, prevnum, prevmodule)) else: - self.ui.debug(_("no copyfrom path, don't know what to do.\n")) + self.ui.debug("no copyfrom path, don't know what to do.\n") paths = [] # filter out unrelated paths @@ -785,7 +788,7 @@ lastonbranch = True break if not paths: - self.ui.debug(_('revision %d has no entries\n') % revnum) + self.ui.debug('revision %d has no entries\n' % revnum) continue cset, lastonbranch = parselogentry(paths, revnum, author, date, message) @@ -867,7 +870,7 @@ return relative # The path is outside our tracked tree... - self.ui.debug(_('%r is not under %r, ignoring\n') % (path, module)) + self.ui.debug('%r is not under %r, ignoring\n' % (path, module)) return None def _checkpath(self, path, revnum): diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/extdiff.py --- a/hgext/extdiff.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/extdiff.py Thu Oct 08 01:16:32 2009 -0500 @@ -42,9 +42,9 @@ ''' from mercurial.i18n import _ -from mercurial.node import short +from mercurial.node import short, nullid from mercurial import cmdutil, util, commands -import os, shlex, shutil, tempfile +import os, shlex, shutil, tempfile, re def snapshot(ui, repo, files, node, tmproot): '''snapshot files as of some revision @@ -69,7 +69,7 @@ for fn in files: wfn = util.pconvert(fn) if not wfn in ctx: - # skipping new file after a merge ? + # File doesn't exist; could be a bogus modify continue ui.note(' %s\n' % wfn) dest = os.path.join(base, wfn) @@ -96,59 +96,102 @@ revs = opts.get('rev') change = opts.get('change') + args = ' '.join(diffopts) + do3way = '$parent2' in args if revs and change: msg = _('cannot specify --rev and --change at the same time') raise util.Abort(msg) elif change: node2 = repo.lookup(change) - node1 = repo[node2].parents()[0].node() + node1a, node1b = repo.changelog.parents(node2) else: - node1, node2 = cmdutil.revpair(repo, revs) + node1a, node2 = cmdutil.revpair(repo, revs) + if not revs: + node1b = repo.dirstate.parents()[1] + else: + node1b = nullid + + # Disable 3-way merge if there is only one parent + if do3way: + if node1b == nullid: + do3way = False matcher = cmdutil.match(repo, pats, opts) - modified, added, removed = repo.status(node1, node2, matcher)[:3] - if not (modified or added or removed): - return 0 + mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher)[:3]) + if do3way: + mod_b, add_b, rem_b = map(set, repo.status(node1b, node2, matcher)[:3]) + else: + mod_b, add_b, rem_b = set(), set(), set() + modadd = mod_a | add_a | mod_b | add_b + common = modadd | rem_a | rem_b + if not common: + return 0 tmproot = tempfile.mkdtemp(prefix='extdiff.') - dir2root = '' try: - # Always make a copy of node1 - dir1 = snapshot(ui, repo, modified + removed, node1, tmproot)[0] - changes = len(modified) + len(removed) + len(added) + # Always make a copy of node1a (and node1b, if applicable) + dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a) + dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot)[0] + if do3way: + dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b) + dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot)[0] + else: + dir1b = None + + fns_and_mtime = [] # If node2 in not the wc or there is >1 change, copy it - if node2 or changes > 1: - dir2, fns_and_mtime = snapshot(ui, repo, modified + added, node2, tmproot) + dir2root = '' + if node2: + dir2 = snapshot(ui, repo, modadd, node2, tmproot)[0] + elif len(common) > 1: + #we only actually need to get the files to copy back to the working + #dir in this case (because the other cases are: diffing 2 revisions + #or single file -- in which case the file is already directly passed + #to the diff tool). + dir2, fns_and_mtime = snapshot(ui, repo, modadd, None, tmproot) else: # This lets the diff tool open the changed file directly dir2 = '' dir2root = repo.root - fns_and_mtime = [] # If only one change, diff the files instead of the directories - if changes == 1 : - if len(modified): - dir1 = os.path.join(dir1, util.localpath(modified[0])) - dir2 = os.path.join(dir2root, dir2, util.localpath(modified[0])) - elif len(removed) : - dir1 = os.path.join(dir1, util.localpath(removed[0])) - dir2 = os.devnull - else: - dir1 = os.devnull - dir2 = os.path.join(dir2root, dir2, util.localpath(added[0])) + # Handle bogus modifies correctly by checking if the files exist + if len(common) == 1: + common_file = util.localpath(common.pop()) + dir1a = os.path.join(dir1a, common_file) + if not os.path.isfile(os.path.join(tmproot, dir1a)): + dir1a = os.devnull + if do3way: + dir1b = os.path.join(dir1b, common_file) + if not os.path.isfile(os.path.join(tmproot, dir1b)): + dir1b = os.devnull + dir2 = os.path.join(dir2root, dir2, common_file) - cmdline = ('%s %s %s %s' % - (util.shellquote(diffcmd), ' '.join(diffopts), - util.shellquote(dir1), util.shellquote(dir2))) - ui.debug(_('running %r in %s\n') % (cmdline, tmproot)) + # Function to quote file/dir names in the argument string + # When not operating in 3-way mode, an empty string is returned for parent2 + replace = dict(parent=dir1a, parent1=dir1a, parent2=dir1b, child=dir2) + def quote(match): + key = match.group()[1:] + if not do3way and key == 'parent2': + return '' + return util.shellquote(replace[key]) + + # Match parent2 first, so 'parent1?' will match both parent1 and parent + regex = '\$(parent2|parent1?|child)' + if not do3way and not re.search(regex, args): + args += ' $parent1 $child' + args = re.sub(regex, quote, args) + cmdline = util.shellquote(diffcmd) + ' ' + args + + ui.debug('running %r in %s\n' % (cmdline, tmproot)) util.system(cmdline, cwd=tmproot) for copy_fn, working_fn, mtime in fns_and_mtime: if os.path.getmtime(copy_fn) != mtime: - ui.debug(_('file changed while diffing. ' - 'Overwriting: %s (src: %s)\n') % (working_fn, copy_fn)) + ui.debug('file changed while diffing. ' + 'Overwriting: %s (src: %s)\n' % (working_fn, copy_fn)) util.copyfile(copy_fn, working_fn) return 1 @@ -173,11 +216,11 @@ that revision is compared to the working directory, and, when no revisions are specified, the working directory files are compared to its parent.''' - program = opts['program'] or 'diff' - if opts['program']: - option = opts['option'] - else: - option = opts['option'] or ['-Npru'] + program = opts.get('program') + option = opts.get('option') + if not program: + program = 'diff' + option = option or ['-Npru'] return dodiff(ui, repo, program, option, pats, opts) cmdtable = { diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/hgcia.py --- a/hgext/hgcia.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/hgcia.py Thu Oct 08 01:16:32 2009 -0500 @@ -229,10 +229,10 @@ n = bin(node) cia = hgcia(ui, repo) if not cia.user: - ui.debug(_('cia: no user specified')) + ui.debug('cia: no user specified') return if not cia.project: - ui.debug(_('cia: no project specified')) + ui.debug('cia: no project specified') return if hooktype == 'changegroup': start = repo.changelog.rev(n) diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/hgk.py --- a/hgext/hgk.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/hgk.py Thu Oct 08 01:16:32 2009 -0500 @@ -308,7 +308,7 @@ os.chdir(repo.root) optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems() if v]) cmd = ui.config("hgk", "path", "hgk") + " %s %s" % (optstr, " ".join(etc)) - ui.debug(_("running %s\n") % cmd) + ui.debug("running %s\n" % cmd) util.system(cmd) cmdtable = { diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/inotify/__init__.py --- a/hgext/inotify/__init__.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/inotify/__init__.py Thu Oct 08 01:16:32 2009 -0500 @@ -17,28 +17,7 @@ def serve(ui, repo, **opts): '''start an inotify server for this repository''' - timeout = opts.get('timeout') - if timeout: - timeout = float(timeout) * 1e3 - - class service(object): - def init(self): - try: - self.master = server.master(ui, repo.dirstate, - repo.root, timeout) - except server.AlreadyStartedException, inst: - raise util.Abort(str(inst)) - - def run(self): - try: - self.master.run() - finally: - self.master.shutdown() - - service = service() - logfile = ui.config('inotify', 'log') - cmdutil.service(opts, initfn=service.init, runfn=service.run, - logfile=logfile) + server.start(ui, repo.dirstate, repo.root, opts) def debuginotify(ui, repo, **opts): '''debugging information for inotify extension diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/inotify/client.py --- a/hgext/inotify/client.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/inotify/client.py Thu Oct 08 01:16:32 2009 -0500 @@ -31,10 +31,11 @@ 'removing it)\n')) os.unlink(os.path.join(self.root, '.hg', 'inotify.sock')) if err[0] in (errno.ECONNREFUSED, errno.ENOENT) and autostart: - self.ui.debug(_('(starting inotify server)\n')) + self.ui.debug('(starting inotify server)\n') try: try: - server.start(self.ui, self.dirstate, self.root) + server.start(self.ui, self.dirstate, self.root, + dict(daemon=True, daemon_pipefds='')) except server.AlreadyStartedException, inst: # another process may have started its own # inotify server while this one was starting. @@ -50,7 +51,7 @@ 'server: %s\n') % err[-1]) elif err[0] in (errno.ECONNREFUSED, errno.ENOENT): # silently ignore normal errors if autostart is False - self.ui.debug(_('(inotify server not running)\n')) + self.ui.debug('(inotify server not running)\n') else: self.ui.warn(_('failed to contact inotify server: %s\n') % err[-1]) diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/inotify/server.py --- a/hgext/inotify/server.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/inotify/server.py Thu Oct 08 01:16:32 2009 -0500 @@ -7,7 +7,7 @@ # GNU General Public License version 2, incorporated herein by reference. from mercurial.i18n import _ -from mercurial import osutil, util +from mercurial import cmdutil, osutil, util import common import errno, os, select, socket, stat, struct, sys, tempfile, time @@ -823,52 +823,29 @@ sys.exit(0) pollable.run() -def start(ui, dirstate, root): - def closefds(ignore): - # (from python bug #1177468) - # close all inherited file descriptors - # Python 2.4.1 and later use /dev/urandom to seed the random module's RNG - # a file descriptor is kept internally as os._urandomfd (created on demand - # the first time os.urandom() is called), and should not be closed - try: - os.urandom(4) - urandom_fd = getattr(os, '_urandomfd', None) - except AttributeError: - urandom_fd = None - ignore.append(urandom_fd) - for fd in range(3, 256): - if fd in ignore: - continue +def start(ui, dirstate, root, opts): + timeout = opts.get('timeout') + if timeout: + timeout = float(timeout) * 1e3 + + class service(object): + def init(self): try: - os.close(fd) - except OSError: - pass - - m = master(ui, dirstate, root) - sys.stdout.flush() - sys.stderr.flush() + self.master = master(ui, dirstate, root, timeout) + except AlreadyStartedException, inst: + raise util.Abort(str(inst)) - pid = os.fork() - if pid: - return pid - - closefds(pollable.instances.keys()) - os.setsid() - - fd = os.open('/dev/null', os.O_RDONLY) - os.dup2(fd, 0) - if fd > 0: - os.close(fd) + def run(self): + try: + self.master.run() + finally: + self.master.shutdown() - fd = os.open(ui.config('inotify', 'log', '/dev/null'), - os.O_RDWR | os.O_CREAT | os.O_TRUNC) - os.dup2(fd, 1) - os.dup2(fd, 2) - if fd > 2: - os.close(fd) + runargs = None + if 'inserve' not in sys.argv: + runargs = [sys.argv[0], 'inserve', '-R', root] - try: - m.run() - finally: - m.shutdown() - os._exit(0) + service = service() + logfile = ui.config('inotify', 'log') + cmdutil.service(opts, initfn=service.init, runfn=service.run, + logfile=logfile, runargs=runargs) diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/keyword.py --- a/hgext/keyword.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/keyword.py Thu Oct 08 01:16:32 2009 -0500 @@ -244,12 +244,14 @@ return t2 != text return revlog.revlog.cmp(self, node, text) -def _status(ui, repo, kwt, unknown, *pats, **opts): +def _status(ui, repo, kwt, *pats, **opts): '''Bails out if [keyword] configuration is not active. Returns status of working directory.''' if kwt: - match = cmdutil.match(repo, pats, opts) - return repo.status(match=match, unknown=unknown, clean=True) + unknown = (opts.get('unknown') or opts.get('all') + or opts.get('untracked')) + return repo.status(match=cmdutil.match(repo, pats, opts), clean=True, + unknown=unknown) if ui.configitems('keyword'): raise util.Abort(_('[keyword] patterns cannot match')) raise util.Abort(_('no [keyword] patterns configured')) @@ -259,7 +261,7 @@ if repo.dirstate.parents()[1] != nullid: raise util.Abort(_('outstanding uncommitted merge')) kwt = kwtools['templater'] - status = _status(ui, repo, kwt, False, *pats, **opts) + status = _status(ui, repo, kwt, *pats, **opts) modified, added, removed, deleted = status[:4] if modified or added or removed or deleted: raise util.Abort(_('outstanding uncommitted changes')) @@ -354,7 +356,7 @@ repo.commit(text=msg) ui.status(_('\n\tkeywords expanded\n')) ui.write(repo.wread(fn)) - ui.debug(_('\nremoving temporary repository %s\n') % tmpdir) + ui.debug('\nremoving temporary repository %s\n' % tmpdir) shutil.rmtree(tmpdir, ignore_errors=True) def expand(ui, repo, *pats, **opts): @@ -380,30 +382,32 @@ See "hg help keyword" on how to construct patterns both for inclusion and exclusion of files. - Use -u/--untracked to list untracked files as well. - - With -a/--all and -v/--verbose the codes used to show the status + With -A/--all and -v/--verbose the codes used to show the status of files are:: K = keyword expansion candidate - k = keyword expansion candidate (untracked) + k = keyword expansion candidate (not tracked) I = ignored - i = ignored (untracked) + i = ignored (not tracked) ''' kwt = kwtools['templater'] - status = _status(ui, repo, kwt, opts.get('untracked'), *pats, **opts) + status = _status(ui, repo, kwt, *pats, **opts) + cwd = pats and repo.getcwd() or '' modified, added, removed, deleted, unknown, ignored, clean = status - files = sorted(modified + added + clean) + files = [] + if not (opts.get('unknown') or opts.get('untracked')) or opts.get('all'): + files = sorted(modified + added + clean) wctx = repo[None] kwfiles = [f for f in files if kwt.iskwfile(f, wctx.flags)] - kwuntracked = [f for f in unknown if kwt.iskwfile(f, wctx.flags)] - cwd = pats and repo.getcwd() or '' - kwfstats = (not opts.get('ignore') and - (('K', kwfiles), ('k', kwuntracked),) or ()) + kwunknown = [f for f in unknown if kwt.iskwfile(f, wctx.flags)] + if not opts.get('ignore') or opts.get('all'): + showfiles = kwfiles, kwunknown + else: + showfiles = [], [] if opts.get('all') or opts.get('ignore'): - kwfstats += (('I', [f for f in files if f not in kwfiles]), - ('i', [f for f in unknown if f not in kwuntracked]),) - for char, filenames in kwfstats: + showfiles += ([f for f in files if f not in kwfiles], + [f for f in unknown if f not in kwunknown]) + for char, filenames in zip('KkIi', showfiles): fmt = (opts.get('all') or ui.verbose) and '%s %%s\n' % char or '%s\n' for f in filenames: ui.write(fmt % repo.pathto(f, cwd)) @@ -545,9 +549,12 @@ _('hg kwexpand [OPTION]... [FILE]...')), 'kwfiles': (files, - [('a', 'all', None, _('show keyword status flags of all files')), + [('A', 'all', None, _('show keyword status flags of all files')), ('i', 'ignore', None, _('show files excluded from expansion')), - ('u', 'untracked', None, _('additionally show untracked files')), + ('u', 'unknown', None, _('only show unknown (not tracked) files')), + ('a', 'all', None, + _('show keyword status flags of all files (DEPRECATED)')), + ('u', 'untracked', None, _('only show untracked files (DEPRECATED)')), ] + commands.walkopts, _('hg kwfiles [OPTION]... [FILE]...')), 'kwshrink': (shrink, commands.walkopts, diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/mq.py --- a/hgext/mq.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/mq.py Thu Oct 08 01:16:32 2009 -0500 @@ -321,7 +321,7 @@ if bad: raise util.Abort(bad) guards = sorted(set(guards)) - self.ui.debug(_('active guards: %s\n') % ' '.join(guards)) + self.ui.debug('active guards: %s\n' % ' '.join(guards)) self.active_guards = guards self.guards_dirty = True diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/notify.py --- a/hgext/notify.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/notify.py Thu Oct 08 01:16:32 2009 -0500 @@ -43,6 +43,7 @@ diffstat = True # add a diffstat before the diff content sources = serve # notify if source of incoming changes in this list # (serve == ssh or http, push, pull, bundle) + merge = False # send notification for merges (default True) [email] from = user@host.com # email address to send as if none given [web] @@ -111,6 +112,7 @@ self.test = self.ui.configbool('notify', 'test', True) self.charsets = mail._charsets(self.ui) self.subs = self.subscribers() + self.merge = self.ui.configbool('notify', 'merge', True) mapfile = self.ui.config('notify', 'style') template = (self.ui.config('notify', hooktype) or @@ -165,11 +167,14 @@ def url(self, path=None): return self.ui.config('web', 'baseurl') + (path or self.root) - def node(self, ctx): - '''format one changeset.''' + def node(self, ctx, **props): + '''format one changeset, unless it is a suppressed merge.''' + if not self.merge and len(ctx.parents()) > 1: + return False self.t.show(ctx, changes=ctx.changeset(), baseurl=self.ui.config('web', 'baseurl'), - root=self.repo.root, webroot=self.root) + root=self.repo.root, webroot=self.root, **props) + return True def skipsource(self, source): '''true if incoming changes from this source should be skipped.''' @@ -276,23 +281,36 @@ ctx = repo[node] if not n.subs: - ui.debug(_('notify: no subscribers to repository %s\n') % n.root) + ui.debug('notify: no subscribers to repository %s\n' % n.root) return if n.skipsource(source): - ui.debug(_('notify: changes have source "%s" - skipping\n') % source) + ui.debug('notify: changes have source "%s" - skipping\n' % source) return ui.pushbuffer() + data = '' + count = 0 if hooktype == 'changegroup': start, end = ctx.rev(), len(repo) - count = end - start for rev in xrange(start, end): - n.node(repo[rev]) - n.diff(ctx, repo['tip']) + if n.node(repo[rev]): + count += 1 + else: + data += ui.popbuffer() + ui.note(_('notify: suppressing notification for merge %d:%s\n') % + (rev, repo[rev].hex()[:12])) + ui.pushbuffer() + if count: + n.diff(ctx, repo['tip']) else: - count = 1 - n.node(ctx) + if not n.node(ctx): + ui.popbuffer() + ui.note(_('notify: suppressing notification for merge %d:%s\n') % + (ctx.rev(), ctx.hex()[:12])) + return + count += 1 n.diff(ctx) - data = ui.popbuffer() - n.send(ctx, count, data) + data += ui.popbuffer() + if count: + n.send(ctx, count, data) diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/rebase.py --- a/hgext/rebase.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/rebase.py Thu Oct 08 01:16:32 2009 -0500 @@ -35,7 +35,7 @@ if not first: ancestor.ancestor = newancestor else: - repo.ui.debug(_("first revision, do not change ancestor\n")) + repo.ui.debug("first revision, do not change ancestor\n") stats = merge.update(repo, rev, True, True, False) return stats @@ -149,7 +149,7 @@ """Skip commit if collapsing has been required and rev is not the last revision, commit otherwise """ - repo.ui.debug(_(" set parents\n")) + repo.ui.debug(" set parents\n") if collapse and not last: repo.dirstate.setparents(repo[p1].node()) return None @@ -187,23 +187,23 @@ def rebasenode(repo, rev, target, state, skipped, targetancestors, collapse, extrafn): 'Rebase a single revision' - repo.ui.debug(_("rebasing %d:%s\n") % (rev, repo[rev])) + repo.ui.debug("rebasing %d:%s\n" % (rev, repo[rev])) p1, p2 = defineparents(repo, rev, target, state, targetancestors) - repo.ui.debug(_(" future parents are %d and %d\n") % (repo[p1].rev(), + repo.ui.debug(" future parents are %d and %d\n" % (repo[p1].rev(), repo[p2].rev())) # Merge phase if len(repo.parents()) != 2: # Update to target and merge it with local if repo['.'].rev() != repo[p1].rev(): - repo.ui.debug(_(" update to %d:%s\n") % (repo[p1].rev(), repo[p1])) + repo.ui.debug(" update to %d:%s\n" % (repo[p1].rev(), repo[p1])) merge.update(repo, p1, False, True, False) else: - repo.ui.debug(_(" already in target\n")) + repo.ui.debug(" already in target\n") repo.dirstate.write() - repo.ui.debug(_(" merge against %d:%s\n") % (repo[rev].rev(), repo[rev])) + repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev])) first = repo[rev].rev() == repo[min(state)].rev() stats = rebasemerge(repo, rev, first) @@ -211,7 +211,7 @@ raise util.Abort(_('fix unresolved conflicts with hg resolve then ' 'run hg rebase --continue')) else: # we have an interrupted rebase - repo.ui.debug(_('resuming interrupted rebase\n')) + repo.ui.debug('resuming interrupted rebase\n') # Keep track of renamed files in the revision that is going to be rebased # Here we simulate the copies and renames in the source changeset @@ -234,7 +234,7 @@ else: if not collapse: repo.ui.note(_('no changes, revision %d skipped\n') % rev) - repo.ui.debug(_('next revision set to %s\n') % p1) + repo.ui.debug('next revision set to %s\n' % p1) skipped.add(rev) state[rev] = p1 @@ -280,7 +280,7 @@ mqrebase = {} for p in repo.mq.applied: if repo[p.rev].rev() in state: - repo.ui.debug(_('revision %d is an mq patch (%s), finalize it.\n') % + repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' % (repo[p.rev].rev(), p.name)) mqrebase[repo[p.rev].rev()] = (p.name, isagitpatch(repo, p.name)) @@ -290,7 +290,7 @@ # We must start import from the newest revision for rev in sorted(mqrebase, reverse=True): if rev not in skipped: - repo.ui.debug(_('import mq patch %d (%s)\n') + repo.ui.debug('import mq patch %d (%s)\n' % (state[rev], mqrebase[rev][0])) repo.mq.qimport(repo, (), patchname=mqrebase[rev][0], git=mqrebase[rev][1],rev=[str(state[rev])]) @@ -311,7 +311,7 @@ newrev = repo[v].hex() f.write("%s:%s\n" % (oldrev, newrev)) f.close() - repo.ui.debug(_('rebase status stored\n')) + repo.ui.debug('rebase status stored\n') def clearstatus(repo): 'Remove the status files' @@ -342,7 +342,7 @@ else: oldrev, newrev = l.split(':') state[repo[oldrev].rev()] = repo[newrev].rev() - repo.ui.debug(_('rebase status resumed\n')) + repo.ui.debug('rebase status resumed\n') return originalwd, target, state, collapse, keep, keepbranches, external except IOError, err: if err.errno != errno.ENOENT: @@ -392,12 +392,12 @@ cwd = repo['.'].rev() if cwd == dest: - repo.ui.debug(_('already working on current\n')) + repo.ui.debug('already working on current\n') return None targetancestors = set(repo.changelog.ancestors(dest)) if cwd in targetancestors: - repo.ui.debug(_('already working on the current branch\n')) + repo.ui.debug('already working on the current branch\n') return None cwdancestors = set(repo.changelog.ancestors(cwd)) @@ -405,7 +405,7 @@ rebasingbranch = cwdancestors - targetancestors source = min(rebasingbranch) - repo.ui.debug(_('rebase onto %d starting from %d\n') % (dest, source)) + repo.ui.debug('rebase onto %d starting from %d\n' % (dest, source)) state = dict.fromkeys(repo.changelog.descendants(source), nullrev) external = nullrev if collapse: @@ -429,8 +429,8 @@ if opts.get('rebase'): if opts.get('update'): del opts['update'] - ui.debug(_('--update and --rebase are not compatible, ignoring ' - 'the update flag\n')) + ui.debug('--update and --rebase are not compatible, ignoring ' + 'the update flag\n') cmdutil.bail_if_changed(repo) revsprepull = len(repo) diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/record.py --- a/hgext/record.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/record.py Thu Oct 08 01:16:32 2009 -0500 @@ -463,7 +463,7 @@ fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.', dir=backupdir) os.close(fd) - ui.debug(_('backup %r as %r\n') % (f, tmpname)) + ui.debug('backup %r as %r\n' % (f, tmpname)) util.copyfile(repo.wjoin(f), tmpname) backups[f] = tmpname @@ -481,7 +481,7 @@ # 3b. (apply) if dopatch: try: - ui.debug(_('applying patch\n')) + ui.debug('applying patch\n') ui.debug(fp.getvalue()) pfiles = {} patch.internalpatch(fp, ui, 1, repo.root, files=pfiles, @@ -512,7 +512,7 @@ # 5. finally restore backed-up files try: for realname, tmpname in backups.iteritems(): - ui.debug(_('restoring %r to %r\n') % (tmpname, realname)) + ui.debug('restoring %r to %r\n' % (tmpname, realname)) util.copyfile(tmpname, repo.wjoin(realname)) os.unlink(tmpname) os.rmdir(backupdir) diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/win32mbcs.py --- a/hgext/win32mbcs.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/win32mbcs.py Thu Oct 08 01:16:32 2009 -0500 @@ -142,6 +142,6 @@ for f in funcs.split(): wrapname(f, wrapper) wrapname("mercurial.osutil.listdir", wrapperforlistdir) - ui.debug(_("[win32mbcs] activated with encoding: %s\n") + ui.debug("[win32mbcs] activated with encoding: %s\n" % encoding.encoding) diff -r 620d6b20ef85 -r ceb0f59e1327 hgext/zeroconf/__init__.py --- a/hgext/zeroconf/__init__.py Tue Oct 06 11:18:58 2009 +0300 +++ b/hgext/zeroconf/__init__.py Thu Oct 08 01:16:32 2009 -0500 @@ -109,12 +109,13 @@ def __init__(self, conf, baseui=None): super(hgwebdirzc, self).__init__(conf, baseui) prefix = self.ui.config("web", "prefix", "").strip('/') + '/' - for r, p in self.repos: + for repo, path in self.repos: u = self.ui.copy() - u.readconfig(os.path.join(p, '.hg', 'hgrc')) - n = os.path.basename(r) - path = (prefix + r).strip('/') - publish(n, "hgweb", path, int(u.config("web", "port", 8000))) + u.readconfig(os.path.join(path, '.hg', 'hgrc')) + name = os.path.basename(repo) + path = (prefix + repo).strip('/') + desc = u.config('web', 'description', name) + publish(name, desc, path, int(u.config("web", "port", 8000))) # listen @@ -136,25 +137,24 @@ Zeroconf.ServiceBrowser(server, "_hg._tcp.local.", l) time.sleep(1) server.close() - for v in l.found.values(): - n = v.name[:v.name.index('.')] - n.replace(" ", "-") - u = "http://%s:%s%s" % (socket.inet_ntoa(v.address), v.port, - v.properties.get("path", "/")) - yield "zc-" + n, u + for value in l.found.values(): + name = value.name[:value.name.index('.')] + url = "http://%s:%s%s" % (socket.inet_ntoa(value.address), value.port, + value.properties.get("path", "/")) + yield "zc-" + name, url def config(orig, self, section, key, default=None, untrusted=False): if section == "paths" and key.startswith("zc-"): - for n, p in getzcpaths(): - if n == key: - return p + for name, path in getzcpaths(): + if name == key: + return path return orig(self, section, key, default, untrusted) def configitems(orig, self, section, untrusted=False): - r = orig(self, section, untrusted) + repos = orig(self, section, untrusted) if section == "paths": - r += getzcpaths() - return r + repos += getzcpaths() + return repos extensions.wrapfunction(ui.ui, 'config', config) extensions.wrapfunction(ui.ui, 'configitems', configitems) diff -r 620d6b20ef85 -r ceb0f59e1327 i18n/hggettext --- a/i18n/hggettext Tue Oct 06 11:18:58 2009 +0300 +++ b/i18n/hggettext Thu Oct 08 01:16:32 2009 -0500 @@ -112,6 +112,11 @@ print poentry(path, lineno, func.__doc__) +def rawtext(path): + src = open(path).read() + print poentry(path, 1, src) + + if __name__ == "__main__": # It is very important that we import the Mercurial modules from # the source tree where hggettext is executed. Otherwise we might @@ -120,4 +125,7 @@ sys.path.insert(0, os.getcwd()) from mercurial import demandimport; demandimport.enable() for path in sys.argv[1:]: - docstrings(path) + if path.endswith('.txt'): + rawtext(path) + else: + docstrings(path) diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/bdiff.c --- a/mercurial/bdiff.c Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/bdiff.c Thu Oct 08 01:16:32 2009 -0500 @@ -151,7 +151,7 @@ } /* compute popularity threshold */ - t = (bn >= 4000) ? bn / 1000 : bn + 1; + t = (bn >= 31000) ? bn / 1000 : 1000000 / (bn + 1); /* match items in a to their equivalence class in b */ for (i = 0; i < an; i++) { diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/cmdutil.py --- a/mercurial/cmdutil.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/cmdutil.py Thu Oct 08 01:16:32 2009 -0500 @@ -546,24 +546,26 @@ return errors -def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None): +def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None, + runargs=None): '''Run a command as a service.''' if opts['daemon'] and not opts['daemon_pipefds']: rfd, wfd = os.pipe() - args = sys.argv[:] - args.append('--daemon-pipefds=%d,%d' % (rfd, wfd)) + if not runargs: + runargs = sys.argv[:] + runargs.append('--daemon-pipefds=%d,%d' % (rfd, wfd)) # Don't pass --cwd to the child process, because we've already # changed directory. - for i in xrange(1,len(args)): - if args[i].startswith('--cwd='): - del args[i] + for i in xrange(1,len(runargs)): + if runargs[i].startswith('--cwd='): + del runargs[i] break - elif args[i].startswith('--cwd'): - del args[i:i+2] + elif runargs[i].startswith('--cwd'): + del runargs[i:i+2] break pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0), - args[0], args) + runargs[0], runargs) os.close(wfd) os.read(rfd, 1) if parentfn: @@ -650,9 +652,8 @@ return log = self.repo.changelog - changes = log.read(changenode) - date = util.datestr(changes[2]) - extra = changes[5] + date = util.datestr(ctx.date()) + extra = ctx.extra() branch = extra.get("branch") hexfunc = self.ui.debugflag and hex or short @@ -672,9 +673,10 @@ self.ui.write(_("parent: %d:%s\n") % parent) if self.ui.debugflag: + mnode = ctx.manifestnode() self.ui.write(_("manifest: %d:%s\n") % - (self.repo.manifest.rev(changes[0]), hex(changes[0]))) - self.ui.write(_("user: %s\n") % changes[1]) + (self.repo.manifest.rev(mnode), hex(mnode))) + self.ui.write(_("user: %s\n") % ctx.user()) self.ui.write(_("date: %s\n") % date) if self.ui.debugflag: @@ -683,8 +685,8 @@ files): if value: self.ui.write("%-12s %s\n" % (key, " ".join(value))) - elif changes[3] and self.ui.verbose: - self.ui.write(_("files: %s\n") % " ".join(changes[3])) + elif ctx.files() and self.ui.verbose: + self.ui.write(_("files: %s\n") % " ".join(ctx.files())) if copies and self.ui.verbose: copies = ['%s (%s)' % c for c in copies] self.ui.write(_("copies: %s\n") % ' '.join(copies)) @@ -694,7 +696,7 @@ self.ui.write(_("extra: %s=%s\n") % (key, value.encode('string_escape'))) - description = changes[4].strip() + description = ctx.description().strip() if description: if self.ui.verbose: self.ui.write(_("description:\n")) @@ -743,6 +745,9 @@ 'parent': '{rev}:{node|formatnode} ', 'manifest': '{rev}:{node|formatnode}', 'filecopy': '{name} ({source})'}) + # Cache mapping from rev to a tuple with tag date, tag + # distance and tag name + self._latesttagcache = {-1: (0, 0, 'null')} def use_template(self, t): '''set template string to use''' @@ -760,6 +765,30 @@ return [] return parents + def _latesttaginfo(self, rev): + '''return date, distance and name for the latest tag of rev''' + todo = [rev] + while todo: + rev = todo.pop() + if rev in self._latesttagcache: + continue + ctx = self.repo[rev] + tags = [t for t in ctx.tags() if self.repo.tagtype(t) == 'global'] + if tags: + self._latesttagcache[rev] = ctx.date()[0], 0, ':'.join(sorted(tags)) + continue + try: + # The tuples are laid out so the right one can be found by comparison. + pdate, pdist, ptag = max( + self._latesttagcache[p.rev()] for p in ctx.parents()) + except KeyError: + # Cache miss - recurse + todo.append(rev) + todo.extend(p.rev() for p in ctx.parents()) + continue + self._latesttagcache[rev] = pdate, pdist + 1, ptag + return self._latesttagcache[rev] + def _show(self, ctx, copies, props): '''show a single changeset or file revision''' @@ -877,6 +906,11 @@ removes += i[2] return '%s: +%s/-%s' % (files, adds, removes) + def showlatesttag(**args): + return self._latesttaginfo(ctx.rev())[2] + def showlatesttagdistance(**args): + return self._latesttaginfo(ctx.rev())[1] + defprops = { 'author': ctx.user(), 'branches': showbranches, @@ -894,6 +928,8 @@ 'tags': showtags, 'extras': showextras, 'diffstat': showdiffstat, + 'latesttag': showlatesttag, + 'latesttagdistance': showlatesttagdistance, } props = props.copy() props.update(defprops) diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/commands.py --- a/mercurial/commands.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/commands.py Thu Oct 08 01:16:32 2009 -0500 @@ -1548,7 +1548,7 @@ doc = doc() ui.write("%s\n\n" % header) - ui.write("%s\n" % minirst.format(doc, textwidth)) + ui.write("%s\n" % minirst.format(doc, textwidth, indent=4)) def helpext(name): try: @@ -1619,9 +1619,7 @@ ui.write(_("\nadditional help topics:\n\n")) topics = [] for names, header, doc in help.helptable: - names = [(-len(name), name) for name in names] - names.sort() - topics.append((names[0][1], header)) + topics.append((sorted(names, key=len, reverse=True)[0], header)) topics_len = max([len(s[0]) for s in topics]) for t, desc in topics: ui.write(" %-*s %s\n" % (topics_len, t, desc)) @@ -1791,7 +1789,7 @@ else: # launch the editor message = None - ui.debug(_('message:\n%s\n') % message) + ui.debug('message:\n%s\n' % message) wp = repo.parents() if opts.get('exact'): @@ -3095,7 +3093,7 @@ globalopts = [ ('R', 'repository', '', - _('repository root directory or symbolic path name')), + _('repository root directory or name of overlay bundle file')), ('', 'cwd', '', _('change working directory')), ('y', 'noninteractive', None, _('do not prompt, assume \'yes\' for any required answers')), diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/context.py --- a/mercurial/context.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/context.py Thu Oct 08 01:16:32 2009 -0500 @@ -299,6 +299,7 @@ def files(self): return self._changectx.files() def description(self): return self._changectx.description() def branch(self): return self._changectx.branch() + def extra(self): return self._changectx.extra() def manifest(self): return self._changectx.manifest() def changectx(self): return self._changectx diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/copies.py --- a/mercurial/copies.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/copies.py Thu Oct 08 01:16:32 2009 -0500 @@ -144,16 +144,16 @@ elif of in ma: diverge.setdefault(of, []).append(f) - repo.ui.debug(_(" searching for copies back to rev %d\n") % limit) + repo.ui.debug(" searching for copies back to rev %d\n" % limit) u1 = _nonoverlap(m1, m2, ma) u2 = _nonoverlap(m2, m1, ma) if u1: - repo.ui.debug(_(" unmatched files in local:\n %s\n") + repo.ui.debug(" unmatched files in local:\n %s\n" % "\n ".join(u1)) if u2: - repo.ui.debug(_(" unmatched files in other:\n %s\n") + repo.ui.debug(" unmatched files in other:\n %s\n" % "\n ".join(u2)) for f in u1: @@ -169,7 +169,7 @@ diverge2.update(fl) # reverse map for below if fullcopy: - repo.ui.debug(_(" all copies found (* = to merge, ! = divergent):\n")) + repo.ui.debug(" all copies found (* = to merge, ! = divergent):\n") for f in fullcopy: note = "" if f in copy: note += "*" @@ -180,7 +180,7 @@ if not fullcopy or not checkdirs: return copy, diverge - repo.ui.debug(_(" checking for directory renames\n")) + repo.ui.debug(" checking for directory renames\n") # generate a directory move map d1, d2 = _dirs(m1), _dirs(m2) @@ -216,7 +216,7 @@ return copy, diverge for d in dirmove: - repo.ui.debug(_(" dir %s -> %s\n") % (d, dirmove[d])) + repo.ui.debug(" dir %s -> %s\n" % (d, dirmove[d])) # check unaccounted nonoverlapping files against directory moves for f in u1 + u2: @@ -227,7 +227,7 @@ df = dirmove[d] + f[len(d):] if df not in copy: copy[f] = df - repo.ui.debug(_(" file %s -> %s\n") % (f, copy[f])) + repo.ui.debug(" file %s -> %s\n" % (f, copy[f])) break return copy, diverge diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/demandimport.py --- a/mercurial/demandimport.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/demandimport.py Thu Oct 08 01:16:32 2009 -0500 @@ -127,6 +127,8 @@ # imported by profile, itself imported by hotshot.stats, # not available under Windows 'resource', + # this trips up many extension authors + 'gtk', ] def enable(): diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/dirstate.py --- a/mercurial/dirstate.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/dirstate.py Thu Oct 08 01:16:32 2009 -0500 @@ -38,6 +38,9 @@ class dirstate(object): def __init__(self, opener, ui, root): + '''Create a new dirstate object. opener is an open()-like callable + that can be used to open the dirstate file; root is the root of the + directory tracked by the dirstate.''' self._opener = opener self._root = root self._rootdir = os.path.join(root, '') @@ -47,6 +50,8 @@ @propertycache def _map(self): + '''Return the dirstate contents as a map from filename to + (state, mode, size, time).''' self._read() return self._map @@ -169,12 +174,14 @@ return path def __getitem__(self, key): - ''' current states: - n normal - m needs merging - r marked for removal - a marked for addition - ? not tracked''' + '''Return the current state of key (a filename) in the dirstate. + States are: + n normal + m needs merging + r marked for removal + a marked for addition + ? not tracked + ''' return self._map.get(key, ("?",))[0] def __contains__(self, key): @@ -373,13 +380,9 @@ return st = self._opener("dirstate", "w", atomictemp=True) - try: - gran = int(self._ui.config('dirstate', 'granularity', 1)) - except ValueError: - gran = 1 - if gran > 0: - hlimit = util.fstat(st).st_mtime - llimit = hlimit - gran + # use the modification time of the newly created temporary file as the + # filesystem's notion of 'now' + now = int(util.fstat(st).st_mtime) cs = cStringIO.StringIO() copymap = self._copymap @@ -389,9 +392,19 @@ for f, e in self._map.iteritems(): if f in copymap: f = "%s\0%s" % (f, copymap[f]) - 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) + + if e[0] == 'n' and e[3] == now: + # The file was last modified "simultaneously" with the current + # write to dirstate (i.e. within the same second for file- + # systems with a granularity of 1 sec). This commonly happens + # for at least a couple of files on 'update'. + # The user could change the file without changing its size + # within the same second. Invalidate the file's stat data in + # dirstate, forcing future 'status' calls to compare the + # contents of the file. This prevents mistakenly treating such + # files as clean. + e = (e[0], 0, -1, -1) # mark entry as 'unset' + e = pack(_format, e[0], e[1], e[2], e[3], len(f)) write(e) write(f) @@ -411,11 +424,11 @@ def walk(self, match, unknown, ignored): ''' - walk recursively through the directory tree, finding all files - matched by the match function + Walk recursively through the directory tree, finding all files + matched by match. - results are yielded in a tuple (filename, stat), where stat - and st is the stat result if the file was found in the directory. + Return a dict mapping filename to stat-like object (either + mercurial.osutil.stat instance or return value of os.stat()). ''' def fwarn(f, msg): @@ -553,12 +566,38 @@ return results def status(self, match, ignored, clean, unknown): + '''Determine the status of the working copy relative to the + dirstate and return a tuple of lists (unsure, modified, added, + removed, deleted, unknown, ignored, clean), where: + + unsure: + files that might have been modified since the dirstate was + written, but need to be read to be sure (size is the same + but mtime differs) + modified: + files that have definitely been modified since the dirstate + was written (different size or mode) + added: + files that have been explicitly added with hg add + removed: + files that have been explicitly removed with hg remove + deleted: + files that have been deleted through other means ("missing") + unknown: + files not in the dirstate that are not ignored + ignored: + files not in the dirstate that are ignored + (by _dirignore()) + clean: + files that have definitely not been modified since the + dirstate was written + ''' listignored, listclean, listunknown = ignored, clean, unknown lookup, modified, added, unknown, ignored = [], [], [], [], [] removed, deleted, clean = [], [], [] dmap = self._map - ladd = lookup.append + ladd = lookup.append # aka "unsure" madd = modified.append aadd = added.append uadd = unknown.append diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/dispatch.py --- a/mercurial/dispatch.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/dispatch.py Thu Oct 08 01:16:32 2009 -0500 @@ -217,7 +217,7 @@ def __call__(self, ui, *args, **opts): if self.shadows: - ui.debug(_("alias '%s' shadows command\n") % self.name) + ui.debug("alias '%s' shadows command\n" % self.name) return self.fn(ui, *args, **opts) diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/filemerge.py --- a/mercurial/filemerge.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/filemerge.py Thu Oct 08 01:16:32 2009 -0500 @@ -140,7 +140,7 @@ binary = isbin(fcd) or isbin(fco) or isbin(fca) symlink = 'l' in fcd.flags() + fco.flags() tool, toolpath = _picktool(repo, ui, fd, binary, symlink) - ui.debug(_("picked tool '%s' for %s (binary %s symlink %s)\n") % + ui.debug("picked tool '%s' for %s (binary %s symlink %s)\n" % (tool, fd, binary, symlink)) if not tool or tool == 'internal:prompt': @@ -170,13 +170,13 @@ else: ui.status(_("merging %s\n") % fd) - ui.debug(_("my %s other %s ancestor %s\n") % (fcd, fco, fca)) + ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca)) # do we attempt to simplemerge first? if _toolbool(ui, tool, "premerge", not (binary or symlink)): r = simplemerge.simplemerge(ui, a, b, c, quiet=True) if not r: - ui.debug(_(" premerge successful\n")) + ui.debug(" premerge successful\n") os.unlink(back) os.unlink(b) os.unlink(c) diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/help.py --- a/mercurial/help.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/help.py Thu Oct 08 01:16:32 2009 -0500 @@ -5,7 +5,8 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2, incorporated herein by reference. -from i18n import _ +from i18n import gettext, _ +import sys, os import extensions, util @@ -49,41 +50,7 @@ return result def extshelp(): - doc = _(r''' - Mercurial has the ability to add new features through the use of - extensions. Extensions may add new commands, add options to - existing commands, change the default behavior of commands, or - implement hooks. - - Extensions are not loaded by default for a variety of reasons: - they can increase startup overhead; they may be meant for advanced - usage only; they may provide potentially dangerous abilities (such - as letting you destroy or modify history); they might not be ready - for prime time; or they may alter some usual behaviors of stock - Mercurial. It is thus up to the user to activate extensions as - needed. - - To enable the "foo" extension, either shipped with Mercurial or in - the Python search path, create an entry for it in your hgrc, like - this:: - - [extensions] - foo = - - You may also specify the full path to an extension:: - - [extensions] - myfeature = ~/.hgext/myfeature.py - - To explicitly disable an extension enabled in an hgrc of broader - scope, prepend its path with !:: - - [extensions] - # disabling extension bar residing in /path/to/extension/bar.py - hgext.bar = !/path/to/extension/bar.py - # ditto, but no path was supplied for extension baz - hgext.baz = ! - ''') + doc = loaddoc('extensions')() exts, maxlength = extensions.enabled() doc += listexts(_('enabled extensions:'), exts, maxlength) @@ -93,441 +60,33 @@ return doc -helptable = ( - (["dates"], _("Date Formats"), - _(r''' - Some commands allow the user to specify a date, e.g.: - - - backout, commit, import, tag: Specify the commit date. - - log, revert, update: Select revision(s) by date. - - Many date formats are valid. Here are some examples:: - - "Wed Dec 6 13:18:29 2006" (local timezone assumed) - "Dec 6 13:18 -0600" (year assumed, time offset provided) - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000) - "Dec 6" (midnight) - "13:18" (today assumed) - "3:39" (3:39AM assumed) - "3:39pm" (15:39) - "2006-12-06 13:18:29" (ISO 8601 format) - "2006-12-6 13:18" - "2006-12-6" - "12-6" - "12/6" - "12/6/6" (Dec 6 2006) - - Lastly, there is Mercurial's internal format:: - - "1165432709 0" (Wed Dec 6 13:18:29 2006 UTC) - - This is the internal representation format for dates. unixtime is - the number of seconds since the epoch (1970-01-01 00:00 UTC). - offset is the offset of the local timezone, in seconds west of UTC - (negative if the timezone is east of UTC). - - The log command also accepts date ranges:: - - "<{datetime}" - at or before a given date/time - ">{datetime}" - on or after a given date/time - "{datetime} to {datetime}" - a date range, inclusive - "-{days}" - within a given number of days of today - ''')), - - (["patterns"], _("File Name Patterns"), - _(r''' - Mercurial accepts several notations for identifying one or more - files at a time. - - By default, Mercurial treats filenames as shell-style extended - glob patterns. - - Alternate pattern notations must be specified explicitly. - - To use a plain path name without any pattern matching, start it - with "path:". These path names must completely match starting at - the current repository root. - - To use an extended glob, start a name with "glob:". Globs are - rooted at the current directory; a glob such as "``*.c``" will - only match files in the current directory ending with ".c". - - The supported glob syntax extensions are "``**``" to match any - string across path separators and "{a,b}" to mean "a or b". - - To use a Perl/Python regular expression, start a name with "re:". - Regexp pattern matching is anchored at the root of the repository. - - Plain examples:: - - path:foo/bar a name bar in a directory named foo in the root - of the repository - path:path:name a file or directory named "path:name" - - Glob examples:: - - glob:*.c any name ending in ".c" in the current directory - *.c any name ending in ".c" in the current directory - **.c any name ending in ".c" in any subdirectory of the - current directory including itself. - foo/*.c any name ending in ".c" in the directory foo - foo/**.c any name ending in ".c" in any subdirectory of foo - including itself. - - Regexp examples:: - - re:.*\.c$ any name ending in ".c", anywhere in the repository - - ''')), - - (['environment', 'env'], _('Environment Variables'), - _(r''' -HG - Path to the 'hg' executable, automatically passed when running - hooks, extensions or external tools. If unset or empty, this is - the hg executable's name if it's frozen, or an executable named - 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on - Windows) is searched. - -HGEDITOR - This is the name of the editor to run when committing. See EDITOR. - - (deprecated, use .hgrc) - -HGENCODING - This overrides the default locale setting detected by Mercurial. - This setting is used to convert data including usernames, - changeset descriptions, tag names, and branches. This setting can - be overridden with the --encoding command-line option. +def loaddoc(topic): + """Return a delayed loader for help/topic.txt.""" -HGENCODINGMODE - This sets Mercurial's behavior for handling unknown characters - while transcoding user input. The default is "strict", which - causes Mercurial to abort if it can't map a character. Other - settings include "replace", which replaces unknown characters, and - "ignore", which drops them. This setting can be overridden with - the --encodingmode command-line option. - -HGMERGE - An executable to use for resolving merge conflicts. The program - will be executed with three arguments: local file, remote file, - ancestor file. - - (deprecated, use .hgrc) - -HGRCPATH - A list of files or directories to search for hgrc files. Item - separator is ":" on Unix, ";" on Windows. If HGRCPATH is not set, - platform default search path is used. If empty, only the .hg/hgrc - from the current repository is read. - - For each element in HGRCPATH: - - - if it's a directory, all files ending with .rc are added - - otherwise, the file itself will be added - -HGUSER - This is the string used as the author of a commit. If not set, - available values will be considered in this order: - - - HGUSER (deprecated) - - hgrc files from the HGRCPATH - - EMAIL - - interactive prompt - - LOGNAME (with '@hostname' appended) - - (deprecated, use .hgrc) - -EMAIL - May be used as the author of a commit; see HGUSER. - -LOGNAME - May be used as the author of a commit; see HGUSER. - -VISUAL - This is the name of the editor to use when committing. See EDITOR. - -EDITOR - Sometimes Mercurial needs to open a text file in an editor for a - user to modify, for example when writing commit messages. The - editor it uses is determined by looking at the environment - variables HGEDITOR, VISUAL and EDITOR, in that order. The first - non-empty one is chosen. If all of them are empty, the editor - defaults to 'vi'. - -PYTHONPATH - This is used by Python to find imported modules and may need to be - set appropriately if this Mercurial is not installed system-wide. - ''')), - - (['revs', 'revisions'], _('Specifying Single Revisions'), - _(r''' - Mercurial supports several ways to specify individual revisions. - - A plain integer is treated as a revision number. Negative integers - are treated as sequential offsets from the tip, with -1 denoting - the tip, -2 denoting the revision prior to the tip, and so forth. - - A 40-digit hexadecimal string is treated as a unique revision - identifier. - - A hexadecimal string less than 40 characters long is treated as a - unique revision identifier and is referred to as a short-form - identifier. A short-form identifier is only valid if it is the - prefix of exactly one full-length identifier. - - Any other string is treated as a tag or branch name. A tag name is - a symbolic name associated with a revision identifier. A branch - name denotes the tipmost revision of that branch. Tag and branch - names must not contain the ":" character. - - The reserved name "tip" is a special tag that always identifies - the most recent revision. - - The reserved name "null" indicates the null revision. This is the - revision of an empty repository, and the parent of revision 0. - - The reserved name "." indicates the working directory parent. If - no working directory is checked out, it is equivalent to null. If - an uncommitted merge is in progress, "." is the revision of the - first parent. - ''')), - - (['mrevs', 'multirevs'], _('Specifying Multiple Revisions'), - _(r''' - When Mercurial accepts more than one revision, they may be - specified individually, or provided as a topologically continuous - range, separated by the ":" character. - - The syntax of range notation is [BEGIN]:[END], where BEGIN and END - are revision identifiers. Both BEGIN and END are optional. If - BEGIN is not specified, it defaults to revision number 0. If END - is not specified, it defaults to the tip. The range ":" thus means - "all revisions". - - If BEGIN is greater than END, revisions are treated in reverse - order. + def loader(): + if hasattr(sys, 'frozen'): + module = sys.executable + else: + module = __file__ + base = os.path.dirname(module) - A range acts as a closed interval. This means that a range of 3:5 - gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6. - ''')), - - (['diffs'], _('Diff Formats'), - _(r''' - Mercurial's default format for showing changes between two - versions of a file is compatible with the unified format of GNU - diff, which can be used by GNU patch and many other standard - tools. - - While this standard format is often enough, it does not encode the - following information: - - - executable status and other permission bits - - copy or rename information - - changes in binary files - - creation or deletion of empty files - - Mercurial also supports the extended diff format from the git VCS - which addresses these limitations. The git diff format is not - produced by default because a few widespread tools still do not - understand this format. - - This means that when generating diffs from a Mercurial repository - (e.g. with "hg export"), you should be careful about things like - file copies and renames or other things mentioned above, because - when applying a standard diff to a different repository, this - extra information is lost. Mercurial's internal operations (like - push and pull) are not affected by this, because they use an - internal binary format for communicating changes. - - To make Mercurial produce the git extended diff format, use the - --git option available for many commands, or set 'git = True' in - the [diff] section of your hgrc. You do not need to set this - option when importing diffs in this format or using them in the mq - extension. - ''')), - (['templating', 'templates'], _('Template Usage'), - _(r''' - Mercurial allows you to customize output of commands through - templates. You can either pass in a template from the command - line, via the --template option, or select an existing - template-style (--style). - - You can customize output for any "log-like" command: log, - outgoing, incoming, tip, parents, heads and glog. + for dir in ('.', '..'): + docdir = os.path.join(base, dir, 'help') + if os.path.isdir(docdir): + break - Three styles are packaged with Mercurial: default (the style used - when no explicit preference is passed), compact and changelog. - Usage:: - - $ hg log -r1 --style changelog - - A template is a piece of text, with markup to invoke variable - expansion:: - - $ hg log -r1 --template "{node}\n" - b56ce7b07c52de7d5fd79fb89701ea538af65746 - - Strings in curly braces are called keywords. The availability of - keywords depends on the exact context of the templater. These - keywords are usually available for templating a log-like command: - - :author: String. The unmodified author of the changeset. - :branches: String. The name of the branch on which the changeset - was committed. Will be empty if the branch name was - default. - :date: Date information. The date when the changeset was - committed. - :desc: String. The text of the changeset description. - :diffstat: String. Statistics of changes with the following - format: "modified files: +added/-removed lines" - :files: List of strings. All files modified, added, or removed - by this changeset. - :file_adds: List of strings. Files added by this changeset. - :file_mods: List of strings. Files modified by this changeset. - :file_dels: List of strings. Files removed by this changeset. - :node: String. The changeset identification hash, as a - 40-character hexadecimal string. - :parents: List of strings. The parents of the changeset. - :rev: Integer. The repository-local changeset revision - number. - :tags: List of strings. Any tags associated with the - changeset. - - The "date" keyword does not produce human-readable output. If you - want to use a date in your output, you can use a filter to process - it. Filters are functions which return a string based on the input - variable. You can also use a chain of filters to get the desired - output:: - - $ hg tip --template "{date|isodate}\n" - 2008-08-21 18:22 +0000 - - List of filters: + path = os.path.join(docdir, topic + ".txt") + return gettext(open(path).read()) + return loader - :addbreaks: Any text. Add an XHTML "
" tag before the end of - every line except the last. - :age: Date. Returns a human-readable date/time difference - between the given date/time and the current - date/time. - :basename: Any text. Treats the text as a path, and returns the - last component of the path after splitting by the - path separator (ignoring trailing separators). For - example, "foo/bar/baz" becomes "baz" and "foo/bar//" - becomes "bar". - :stripdir: Treat the text as path and strip a directory level, - if possible. For example, "foo" and "foo/bar" becomes - "foo". - :date: Date. Returns a date in a Unix date format, including - the timezone: "Mon Sep 04 15:13:13 2006 0700". - :domain: Any text. Finds the first string that looks like an - email address, and extracts just the domain - component. Example: 'User ' becomes - 'example.com'. - :email: Any text. Extracts the first string that looks like - an email address. Example: 'User ' - becomes 'user@example.com'. - :escape: Any text. Replaces the special XML/XHTML characters - "&", "<" and ">" with XML entities. - :fill68: Any text. Wraps the text to fit in 68 columns. - :fill76: Any text. Wraps the text to fit in 76 columns. - :firstline: Any text. Returns the first line of text. - :nonempty: Any text. Returns '(none)' if the string is empty. - :hgdate: Date. Returns the date as a pair of numbers: - "1157407993 25200" (Unix timestamp, timezone offset). - :isodate: Date. Returns the date in ISO 8601 format: - "2009-08-18 13:00 +0200". - :isodatesec: Date. Returns the date in ISO 8601 format, including - seconds: "2009-08-18 13:00:13 +0200". See also the - rfc3339date filter. - :localdate: Date. Converts a date to local date. - :obfuscate: Any text. Returns the input text rendered as a - sequence of XML entities. - :person: Any text. Returns the text before an email address. - :rfc822date: Date. Returns a date using the same format used in - email headers: "Tue, 18 Aug 2009 13:00:13 +0200". - :rfc3339date: Date. Returns a date using the Internet date format - specified in RFC 3339: "2009-08-18T13:00:13+02:00". - :short: Changeset hash. Returns the short form of a changeset - hash, i.e. a 12-byte hexadecimal string. - :shortdate: Date. Returns a date like "2006-09-18". - :strip: Any text. Strips all leading and trailing whitespace. - :tabindent: Any text. Returns the text, with every line except - the first starting with a tab character. - :urlescape: Any text. Escapes all "special" characters. For - example, "foo bar" becomes "foo%20bar". - :user: Any text. Returns the user portion of an email - address. - ''')), - - (['urls'], _('URL Paths'), - _(r''' - Valid URLs are of the form:: - - local/filesystem/path[#revision] - file://local/filesystem/path[#revision] - http://[user[:pass]@]host[:port]/[path][#revision] - https://[user[:pass]@]host[:port]/[path][#revision] - ssh://[user[:pass]@]host[:port]/[path][#revision] - - Paths in the local filesystem can either point to Mercurial - repositories or to bundle files (as created by 'hg bundle' or 'hg - incoming --bundle'). - - An optional identifier after # indicates a particular branch, tag, - or changeset to use from the remote repository. See also 'hg help - revisions'. - - Some features, such as pushing to http:// and https:// URLs are - only possible if the feature is explicitly enabled on the remote - Mercurial server. - - Some notes about using SSH with Mercurial: - - - SSH requires an accessible shell account on the destination - machine and a copy of hg in the remote path or specified with as - remotecmd. - - path is relative to the remote user's home directory by default. - Use an extra slash at the start of a path to specify an absolute - path:: - - ssh://example.com//tmp/repository - - - Mercurial doesn't use its own compression via SSH; the right - thing to do is to configure it in your ~/.ssh/config, e.g.:: - - Host *.mylocalnetwork.example.com - Compression no - Host * - Compression yes - - Alternatively specify "ssh -C" as your ssh command in your hgrc - or with the --ssh command line option. - - These URLs can all be stored in your hgrc with path aliases under - the [paths] section like so:: - - [paths] - alias1 = URL1 - alias2 = URL2 - ... - - You can then use the alias for any command that uses a URL (for - example 'hg pull alias1' would pull from the 'alias1' path). - - Two path aliases are special because they are used as defaults - when you do not provide the URL to a command: - - default: - When you create a repository with hg clone, the clone command - saves the location of the source repository as the new - repository's 'default' path. This is then used when you omit - path from push- and pull-like commands (including incoming and - outgoing). - - default-push: - The push command will look for a path named 'default-push', and - prefer it over 'default' if both are defined. - ''')), +helptable = ( + (["dates"], _("Date Formats"), loaddoc('dates')), + (["patterns"], _("File Name Patterns"), loaddoc('patterns')), + (['environment', 'env'], _('Environment Variables'), loaddoc('environment')), + (['revs', 'revisions'], _('Specifying Single Revisions'), loaddoc('revisions')), + (['mrevs', 'multirevs'], _('Specifying Multiple Revisions'), loaddoc('multirevs')), + (['diffs'], _('Diff Formats'), loaddoc('diffs')), + (['templating', 'templates'], _('Template Usage'), loaddoc('templates')), + (['urls'], _('URL Paths'), loaddoc('urls')), (["extensions"], _("Using additional features"), extshelp), ) diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/hg.py --- a/mercurial/hg.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/hg.py Thu Oct 08 01:16:32 2009 -0500 @@ -327,12 +327,8 @@ dir_cleanup.cleanup() def _showstats(repo, stats): - stats = ((stats[0], _("updated")), - (stats[1], _("merged")), - (stats[2], _("removed")), - (stats[3], _("unresolved"))) - note = ", ".join([_("%d files %s") % s for s in stats]) - repo.ui.status("%s\n" % note) + repo.ui.status(_("%d files updated, %d files merged, " + "%d files removed, %d files unresolved\n") % stats) def update(repo, node): """update the working directory to node, merging linear changes""" @@ -357,7 +353,7 @@ _showstats(repo, stats) if stats[3]: repo.ui.status(_("use 'hg resolve' to retry unresolved file merges " - "or 'hg up --clean' to abandon\n")) + "or 'hg update -C' to abandon\n")) elif remind: repo.ui.status(_("(branch merge, don't forget to commit)\n")) return stats[3] > 0 diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/httprepo.py --- a/mercurial/httprepo.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/httprepo.py Thu Oct 08 01:16:32 2009 -0500 @@ -35,7 +35,7 @@ self._url, authinfo = url.getauthinfo(path) self.ui = ui - self.ui.debug(_('using %s\n') % self._url) + self.ui.debug('using %s\n' % self._url) self.urlopener = url.opener(ui, authinfo) @@ -56,7 +56,7 @@ self.caps = set(self.do_read('capabilities').split()) except error.RepoError: self.caps = set() - self.ui.debug(_('capabilities: %s\n') % + self.ui.debug('capabilities: %s\n' % (' '.join(self.caps or ['none']))) return self.caps @@ -68,21 +68,21 @@ def do_cmd(self, cmd, **args): data = args.pop('data', None) headers = args.pop('headers', {}) - self.ui.debug(_("sending %s command\n") % cmd) + self.ui.debug("sending %s command\n" % cmd) q = {"cmd": cmd} q.update(args) qs = '?%s' % urllib.urlencode(q) cu = "%s%s" % (self._url, qs) try: if data: - self.ui.debug(_("sending %s bytes\n") % len(data)) + self.ui.debug("sending %s bytes\n" % len(data)) resp = self.urlopener.open(urllib2.Request(cu, data, headers)) except urllib2.HTTPError, inst: if inst.code == 401: raise util.Abort(_('authorization failed')) raise except httplib.HTTPException, inst: - self.ui.debug(_('http error while sending %s command\n') % cmd) + self.ui.debug('http error while sending %s command\n' % cmd) self.ui.traceback() raise IOError(None, inst) except IndexError: @@ -105,7 +105,7 @@ if not (proto.startswith('application/mercurial-') or proto.startswith('text/plain') or proto.startswith('application/hg-changegroup')): - self.ui.debug(_("requested URL: '%s'\n") % url.hidepassword(cu)) + self.ui.debug("requested URL: '%s'\n" % url.hidepassword(cu)) raise error.RepoError(_("'%s' does not appear to be an hg repository") % safeurl) diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/i18n.py --- a/mercurial/i18n.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/i18n.py Thu Oct 08 01:16:32 2009 -0500 @@ -16,7 +16,7 @@ base = os.path.dirname(module) for dir in ('.', '..'): - localedir = os.path.normpath(os.path.join(base, dir, 'locale')) + localedir = os.path.join(base, dir, 'locale') if os.path.isdir(localedir): break diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/localrepo.py --- a/mercurial/localrepo.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/localrepo.py Thu Oct 08 01:16:32 2009 -0500 @@ -527,7 +527,7 @@ for mf, fn, cmd in self.filterpats[filter]: if mf(filename): - self.ui.debug(_("filtering %s through %s\n") % (filename, cmd)) + self.ui.debug("filtering %s through %s\n" % (filename, cmd)) data = fn(data, cmd, ui=self.ui, repo=self, filename=filename) break @@ -724,14 +724,14 @@ # find source in nearest ancestor if we've lost track if not crev: - self.ui.debug(_(" %s: searching for copy revision for %s\n") % + self.ui.debug(" %s: searching for copy revision for %s\n" % (fname, cfname)) for ancestor in self['.'].ancestors(): if cfname in ancestor: crev = ancestor[cfname].filenode() break - self.ui.debug(_(" %s: copy %s:%s\n") % (fname, cfname, hex(crev))) + self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(crev))) meta["copy"] = cfname meta["copyrev"] = hex(crev) fparent1, fparent2 = nullid, newfparent @@ -1294,22 +1294,22 @@ if n[0] in seen: continue - self.ui.debug(_("examining %s:%s\n") + self.ui.debug("examining %s:%s\n" % (short(n[0]), short(n[1]))) if n[0] == nullid: # found the end of the branch pass elif n in seenbranch: - self.ui.debug(_("branch already found\n")) + self.ui.debug("branch already found\n") continue elif n[1] and n[1] in m: # do we know the base? - self.ui.debug(_("found incomplete branch %s:%s\n") + self.ui.debug("found incomplete branch %s:%s\n" % (short(n[0]), short(n[1]))) search.append(n[0:2]) # schedule branch range for scanning seenbranch.add(n) else: if n[1] not in seen and n[1] not in fetch: if n[2] in m and n[3] in m: - self.ui.debug(_("found new changeset %s\n") % + self.ui.debug("found new changeset %s\n" % short(n[1])) fetch.add(n[1]) # earliest unknown for p in n[2:4]: @@ -1324,11 +1324,11 @@ if r: reqcnt += 1 - self.ui.debug(_("request %d: %s\n") % + self.ui.debug("request %d: %s\n" % (reqcnt, " ".join(map(short, r)))) for p in xrange(0, len(r), 10): for b in remote.branches(r[p:p+10]): - self.ui.debug(_("received %s:%s\n") % + self.ui.debug("received %s:%s\n" % (short(b[0]), short(b[1]))) unknown.append(b) @@ -1341,15 +1341,15 @@ p = n[0] f = 1 for i in l: - self.ui.debug(_("narrowing %d:%d %s\n") % (f, len(l), short(i))) + self.ui.debug("narrowing %d:%d %s\n" % (f, len(l), short(i))) if i in m: if f <= 2: - self.ui.debug(_("found new branch changeset %s\n") % + self.ui.debug("found new branch changeset %s\n" % short(p)) fetch.add(p) base[i] = 1 else: - self.ui.debug(_("narrowed branch search to %s:%s\n") + self.ui.debug("narrowed branch search to %s:%s\n" % (short(p), short(i))) newsearch.append((p, i)) break @@ -1368,10 +1368,10 @@ else: raise util.Abort(_("repository is unrelated")) - self.ui.debug(_("found new changesets starting at ") + + self.ui.debug("found new changesets starting at " + " ".join([short(f) for f in fetch]) + "\n") - self.ui.debug(_("%d total queries\n") % reqcnt) + self.ui.debug("%d total queries\n" % reqcnt) return base.keys(), list(fetch), heads @@ -1388,7 +1388,7 @@ base = {} self.findincoming(remote, base, heads, force=force) - self.ui.debug(_("common changesets up to ") + self.ui.debug("common changesets up to " + " ".join(map(short, base.keys())) + "\n") remain = set(self.changelog.nodemap) @@ -1608,7 +1608,7 @@ if self.ui.verbose or source == 'bundle': self.ui.status(_("%d changesets found\n") % len(nodes)) if self.ui.debugflag: - self.ui.debug(_("list of changesets:\n")) + self.ui.debug("list of changesets:\n") for node in nodes: self.ui.debug("%s\n" % hex(node)) @@ -1994,7 +1994,7 @@ - number of heads stays the same: 1 """ def csmap(x): - self.ui.debug(_("add changeset %s\n") % short(x)) + self.ui.debug("add changeset %s\n" % short(x)) return len(cl) def revmap(x): @@ -2040,7 +2040,7 @@ f = changegroup.getchunk(source) if not f: break - self.ui.debug(_("adding %s revisions\n") % f) + self.ui.debug("adding %s revisions\n" % f) fl = self.file(f) o = len(fl) chunkiter = changegroup.chunkiter(source) @@ -2073,7 +2073,7 @@ if changesets > 0: # forcefully update the on-disk branch cache - self.ui.debug(_("updating the branch cache\n")) + self.ui.debug("updating the branch cache\n") self.branchtags() self.hook("changegroup", node=hex(cl.node(clstart)), source=srctype, url=url) @@ -2122,7 +2122,7 @@ except (ValueError, TypeError): raise error.ResponseError( _('Unexpected response from remote server:'), l) - self.ui.debug(_('adding %s (%s)\n') % (name, util.bytecount(size))) + self.ui.debug('adding %s (%s)\n' % (name, util.bytecount(size))) # for backwards compat, name was partially encoded ofp = self.sopener(store.decodedir(name), 'w') for chunk in util.filechunkiter(fp, limit=size): diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/merge.py --- a/mercurial/merge.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/merge.py Thu Oct 08 01:16:32 2009 -0500 @@ -161,8 +161,8 @@ act("divergent renames", "dr", of, fl) repo.ui.note(_("resolving manifests\n")) - repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial))) - repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2)) + repo.ui.debug(" overwrite %s partial %s\n" % (overwrite, bool(partial))) + repo.ui.debug(" ancestor %s local %s remote %s\n" % (pa, p1, p2)) m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest() copied = set(copy.values()) @@ -252,7 +252,7 @@ f2, fd, flags, move = a[2:] if f == '.hgsubstate': # merged internally continue - repo.ui.debug(_("preserving %s for resolve of %s\n") % (f, fd)) + repo.ui.debug("preserving %s for resolve of %s\n" % (f, fd)) fcl = wctx[f] fco = mctx[f2] fca = fcl.ancestor(fco) or repo.filectx(f, fileid=nullrev) @@ -263,7 +263,7 @@ # remove renamed files after safely stored for f in moves: if util.lexists(repo.wjoin(f)): - repo.ui.debug(_("removing %s\n") % f) + repo.ui.debug("removing %s\n" % f) os.unlink(repo.wjoin(f)) audit_path = util.path_auditor(repo.root) @@ -299,7 +299,7 @@ merged += 1 util.set_flags(repo.wjoin(fd), 'l' in flags, 'x' in flags) if f != fd and move and util.lexists(repo.wjoin(f)): - repo.ui.debug(_("removing %s\n") % f) + repo.ui.debug("removing %s\n" % f) os.unlink(repo.wjoin(f)) elif m == "g": # get flags = a[2] diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/minirst.py --- a/mercurial/minirst.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/minirst.py Thu Oct 08 01:16:32 2009 -0500 @@ -310,9 +310,11 @@ subsequent_indent=subindent) -def format(text, width): +def format(text, width, indent=0): """Parse and format the text according to width.""" blocks = findblocks(text) + for b in blocks: + b['indent'] += indent blocks = findliteralblocks(blocks) blocks = findsections(blocks) blocks = findbulletlists(blocks) diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/patch.py --- a/mercurial/patch.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/patch.py Thu Oct 08 01:16:32 2009 -0500 @@ -93,12 +93,12 @@ hgpatch = False ignoretext = False - ui.debug(_('found patch at byte %d\n') % m.start(0)) + ui.debug('found patch at byte %d\n' % m.start(0)) diffs_seen += 1 cfp = cStringIO.StringIO() for line in payload[:m.start(0)].splitlines(): if line.startswith('# HG changeset patch'): - ui.debug(_('patch generated by hg export\n')) + ui.debug('patch generated by hg export\n') hgpatch = True # drop earlier commit message content cfp.seek(0) @@ -1155,7 +1155,7 @@ return internalpatch(patchname, ui, strip, cwd, files, eolmode) except NoHunks: patcher = util.find_exe('gpatch') or util.find_exe('patch') or 'patch' - ui.debug(_('no valid hunks found; trying with %r instead\n') % + ui.debug('no valid hunks found; trying with %r instead\n' % patcher) if util.needbinarypatch(): args.append('--binary') diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/posix.py --- a/mercurial/posix.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/posix.py Thu Oct 08 01:16:32 2009 -0500 @@ -13,6 +13,7 @@ nulldev = '/dev/null' normpath = os.path.normpath samestat = os.path.samestat +rename = os.rename expandglobs = False umask = os.umask(0) @@ -165,17 +166,11 @@ return inst.errno != errno.ESRCH def explain_exit(code): - """return a 2-tuple (desc, code) describing a process's status""" - if os.WIFEXITED(code): - val = os.WEXITSTATUS(code) - return _("exited with status %d") % val, val - elif os.WIFSIGNALED(code): - val = os.WTERMSIG(code) - return _("killed by signal %d") % val, val - elif os.WIFSTOPPED(code): - val = os.WSTOPSIG(code) - return _("stopped by signal %d") % val, val - raise ValueError(_("invalid exit code")) + """return a 2-tuple (desc, code) describing a subprocess status + (codes from kill are negative - not os.system/wait encoding)""" + if code >= 0: + return _("exited with status %d") % code, code + return _("killed by signal %d") % -code, -code def isowner(st): """Return True if the stat object st is from the current user.""" diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/sshrepo.py --- a/mercurial/sshrepo.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/sshrepo.py Thu Oct 08 01:16:32 2009 -0500 @@ -75,7 +75,7 @@ if lines[-1] == "1\n" and l == "\n": break if l: - ui.debug(_("remote: "), l) + ui.debug("remote: ", l) lines.append(l) max_noise -= 1 else: @@ -113,7 +113,7 @@ __del__ = cleanup def do_cmd(self, cmd, **args): - self.ui.debug(_("sending %s command\n") % cmd) + self.ui.debug("sending %s command\n" % cmd) self.pipeo.write("%s\n" % cmd) for k, v in args.iteritems(): self.pipeo.write("%s %d\n" % (k, len(v))) diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/streamclone.py --- a/mercurial/streamclone.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/streamclone.py Thu Oct 08 01:16:32 2009 -0500 @@ -46,10 +46,9 @@ # get consistent snapshot of repo, lock during scan lock = repo.lock() try: - repo.ui.debug(_('scanning\n')) + repo.ui.debug('scanning\n') for name, ename, size in repo.store.walk(): - # for backwards compat, name was partially encoded - entries.append((store.encodedir(name), size)) + entries.append((name, size)) total_bytes += size finally: lock.release() @@ -57,11 +56,12 @@ raise StreamException(2) yield '0\n' - repo.ui.debug(_('%d files, %d bytes to transfer\n') % + repo.ui.debug('%d files, %d bytes to transfer\n' % (len(entries), total_bytes)) yield '%d %d\n' % (len(entries), total_bytes) for name, size in entries: - repo.ui.debug(_('sending %s (%d bytes)\n') % (name, size)) - yield '%s\0%d\n' % (name, size) + repo.ui.debug('sending %s (%d bytes)\n' % (name, size)) + # partially encode name over the wire for backwards compat + yield '%s\0%d\n' % (store.encodedir(name), size) for chunk in util.filechunkiter(repo.sopener(name), limit=size): yield chunk diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/subrepo.py --- a/mercurial/subrepo.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/subrepo.py Thu Oct 08 01:16:32 2009 -0500 @@ -167,7 +167,7 @@ self._repo.ui.note(_('removing subrepo %s\n') % self._path) hg.clean(self._repo, node.nullid, False) - def get(self, state): + def _get(self, state): source, revision = state try: self._repo.lookup(revision) @@ -178,9 +178,13 @@ other = hg.repository(self._repo.ui, srcurl) self._repo.pull(other) + def get(self, state): + self._get(state) + source, revision = state hg.clean(self._repo, revision, False) def merge(self, state): + self._get(state) hg.merge(self._repo, state[1], remind=False) def push(self, force): diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/url.py --- a/mercurial/url.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/url.py Thu Oct 08 01:16:32 2009 -0500 @@ -197,7 +197,7 @@ proxyuser, proxypasswd or ''), proxypath, proxyquery, proxyfrag)) proxies = {'http': proxyurl, 'https': proxyurl} - ui.debug(_('proxying through http://%s:%s\n') % + ui.debug('proxying through http://%s:%s\n' % (proxyhost, proxyport)) else: proxies = {} @@ -504,7 +504,7 @@ if authinfo is not None: passmgr.add_password(*authinfo) user, passwd = authinfo[2:4] - ui.debug(_('http auth: user %s, password %s\n') % + ui.debug('http auth: user %s, password %s\n' % (user, passwd and '*' * len(passwd) or 'not set')) handlers.extend((urllib2.HTTPBasicAuthHandler(passmgr), diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/util.py --- a/mercurial/util.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/util.py Thu Oct 08 01:16:32 2009 -0500 @@ -16,7 +16,7 @@ from i18n import _ import error, osutil, encoding import cStringIO, errno, re, shutil, sys, tempfile, traceback -import os, stat, time, calendar, random, textwrap +import os, stat, time, calendar, textwrap import imp # Python compatibility @@ -357,41 +357,26 @@ if val is True: return '1' return str(val) - oldenv = {} - for k in environ: - oldenv[k] = os.environ.get(k) - if cwd is not None: - oldcwd = os.getcwd() origcmd = cmd if os.name == 'nt': cmd = '"%s"' % cmd - try: - for k, v in environ.iteritems(): - os.environ[k] = py2shell(v) - os.environ['HG'] = hgexecutable() - if cwd is not None and oldcwd != cwd: - os.chdir(cwd) - rc = os.system(cmd) - if sys.platform == 'OpenVMS' and rc & 1: - rc = 0 - if rc and onerr: - errmsg = '%s %s' % (os.path.basename(origcmd.split(None, 1)[0]), - explain_exit(rc)[0]) - if errprefix: - errmsg = '%s: %s' % (errprefix, errmsg) - try: - onerr.warn(errmsg + '\n') - except AttributeError: - raise onerr(errmsg) - return rc - finally: - for k, v in oldenv.iteritems(): - if v is None: - del os.environ[k] - else: - os.environ[k] = v - if cwd is not None and oldcwd != cwd: - os.chdir(oldcwd) + env = dict(os.environ) + env.update((k, py2shell(v)) for k, v in environ.iteritems()) + env['HG'] = hgexecutable() + rc = subprocess.call(cmd, shell=True, close_fds=closefds, + env=env, cwd=cwd) + if sys.platform == 'OpenVMS' and rc & 1: + rc = 0 + if rc and onerr: + errmsg = '%s %s' % (os.path.basename(origcmd.split(None, 1)[0]), + explain_exit(rc)[0]) + if errprefix: + errmsg = '%s: %s' % (errprefix, errmsg) + try: + onerr.warn(errmsg + '\n') + except AttributeError: + raise onerr(errmsg) + return rc def checksignature(func): '''wrap a function with code to check for calling errors''' @@ -414,37 +399,6 @@ return False return True -def rename(src, dst): - """forcibly rename a file""" - try: - os.rename(src, dst) - except OSError, err: # FIXME: check err (EEXIST ?) - - # On windows, rename to existing file is not allowed, so we - # must delete destination first. But if a file is open, unlink - # schedules it for delete but does not delete it. Rename - # happens immediately even for open files, so we rename - # destination to a temporary name, then delete that. Then - # rename is safe to do. - # The temporary name is chosen at random to avoid the situation - # where a file is left lying around from a previous aborted run. - # The usual race condition this introduces can't be avoided as - # we need the name to rename into, and not the file itself. Due - # to the nature of the operation however, any races will at worst - # lead to the rename failing and the current operation aborting. - - def tempname(prefix): - for tries in xrange(10): - temp = '%s-%08x' % (prefix, random.randint(0, 0xffffffff)) - if not os.path.exists(temp): - return temp - raise IOError, (errno.EEXIST, "No usable temporary filename found") - - temp = tempname(dst) - os.rename(dst, temp) - os.unlink(temp) - os.rename(src, dst) - def unlink(f): """unlink and remove the directory if it is empty""" os.unlink(f) @@ -1267,6 +1221,11 @@ return array.array('h', arri)[1] except ValueError: pass + except IOError, e: + if e[0] == errno.EINVAL: + pass + else: + raise except ImportError: pass return 80 diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/verify.py --- a/mercurial/verify.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/verify.py Thu Oct 08 01:16:32 2009 -0500 @@ -173,6 +173,7 @@ elif size > 0: storefiles.add(f) + lrugetctx = util.lrucachefunc(repo.changectx) files = sorted(set(filenodes) | set(filelinkrevs)) for f in files: try: @@ -224,6 +225,16 @@ # check renames try: if rp: + if lr is not None and ui.verbose: + ctx = lrugetctx(lr) + found = False + for pctx in ctx.parents(): + if rp[0] in pctx: + found = True + break + if not found: + warn(_("warning: copy source of '%s' not" + " in parents of %s") % (f, ctx)) fl2 = repo.file(rp[0]) if not len(fl2): err(lr, _("empty or missing copy source revlog %s:%s") diff -r 620d6b20ef85 -r ceb0f59e1327 mercurial/windows.py --- a/mercurial/windows.py Tue Oct 06 11:18:58 2009 +0300 +++ b/mercurial/windows.py Thu Oct 08 01:16:32 2009 -0500 @@ -7,7 +7,7 @@ from i18n import _ import osutil, error -import errno, msvcrt, os, re, sys +import errno, msvcrt, os, re, sys, random nulldev = 'NUL:' umask = 002 @@ -283,6 +283,44 @@ except OSError: pass +def rename(src, dst): + '''atomically rename file src to dst, replacing dst if it exists''' + try: + os.rename(src, dst) + except OSError, err: # FIXME: check err (EEXIST ?) + + # On windows, rename to existing file is not allowed, so we + # must delete destination first. But if a file is open, unlink + # schedules it for delete but does not delete it. Rename + # happens immediately even for open files, so we rename + # destination to a temporary name, then delete that. Then + # rename is safe to do. + # The temporary name is chosen at random to avoid the situation + # where a file is left lying around from a previous aborted run. + # The usual race condition this introduces can't be avoided as + # we need the name to rename into, and not the file itself. Due + # to the nature of the operation however, any races will at worst + # lead to the rename failing and the current operation aborting. + + def tempname(prefix): + for tries in xrange(10): + temp = '%s-%08x' % (prefix, random.randint(0, 0xffffffff)) + if not os.path.exists(temp): + return temp + raise IOError, (errno.EEXIST, "No usable temporary filename found") + + temp = tempname(dst) + os.rename(dst, temp) + try: + os.unlink(temp) + except: + # Some rude AV-scanners on Windows may cause the unlink to + # fail. Not aborting here just leaks the temp file, whereas + # aborting at this point may leave serious inconsistencies. + # Ideally, we would notify the user here. + pass + os.rename(src, dst) + try: # override functions with win32 versions if possible from win32 import * diff -r 620d6b20ef85 -r ceb0f59e1327 setup.py --- a/setup.py Tue Oct 06 11:18:58 2009 +0300 +++ b/setup.py Thu Oct 08 01:16:32 2009 -0500 @@ -246,7 +246,7 @@ packages.extend(['hgext.inotify', 'hgext.inotify.linux']) datafiles = [] -for root in ('templates', 'i18n'): +for root in ('templates', 'i18n', 'help'): for dir, dirs, files in os.walk(root): dirs[:] = [x for x in dirs if not x.startswith('.')] files = [x for x in files if not x.startswith('.')] diff -r 620d6b20ef85 -r ceb0f59e1327 tests/hghave --- a/tests/hghave Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/hghave Thu Oct 08 01:16:32 2009 -0500 @@ -47,9 +47,6 @@ re = r'Concurrent Versions System.*?server' return matchoutput('cvs --version 2>&1', re) -def has_cvsps(): - return matchoutput('cvsps -h -q 2>&1', r'cvsps version', True) - def has_darcs(): return matchoutput('darcs --version', r'2\.[2-9]', True) @@ -128,8 +125,10 @@ matchoutput('rst2html.py --version', r'^rst2html.py \(Docutils') def has_svn(): - return matchoutput('svn --version 2>&1', r'^svn, version') and \ - matchoutput('svnadmin --version 2>&1', r'^svnadmin, version') + #return matchoutput('svn --version 2>&1', r'^svn, version') and \ + #matchoutput('svnadmin --version 2>&1', r'^svnadmin, version') + # disabled until licensing issue is resolved + return False def has_svn_bindings(): try: @@ -184,7 +183,6 @@ "bzr": (has_bzr, "Canonical's Bazaar client"), "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"), "cvs": (has_cvs, "cvs client/server"), - "cvsps": (has_cvsps, "cvsps utility"), "darcs": (has_darcs, "darcs client"), "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"), "execbit": (has_executablebit, "executable bit"), diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-add.out --- a/tests/test-add.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-add.out Thu Oct 08 01:16:32 2009 -0500 @@ -20,7 +20,7 @@ warning: conflicts during merge. merging a failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon M a ? a.orig % should fail diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-command-template --- a/tests/test-command-template Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-command-template Thu Oct 08 01:16:32 2009 -0500 @@ -127,4 +127,49 @@ echo 'x = "f' >> t hg log +cd .. + +echo '# latesttag' +hg init latesttag +cd latesttag + +echo a > file +hg ci -Am a -d '0 0' + +echo b >> file +hg ci -m b -d '1 0' + +echo c >> head1 +hg ci -Am h1c -d '2 0' + +hg update -q 1 +echo d >> head2 +hg ci -Am h2d -d '3 0' + +echo e >> head2 +hg ci -m h2e -d '4 0' + +hg merge -q +hg ci -m merge -d '5 0' + +echo '# No tag set' +hg log --template '{rev}: {latesttag}+{latesttagdistance}\n' + +echo '# one common tag: longuest path wins' +hg tag -r 1 -m t1 -d '6 0' t1 +hg log --template '{rev}: {latesttag}+{latesttagdistance}\n' + +echo '# one ancestor tag: more recent wins' +hg tag -r 2 -m t2 -d '7 0' t2 +hg log --template '{rev}: {latesttag}+{latesttagdistance}\n' + +echo '# two branch tags: more recent wins' +hg tag -r 3 -m t3 -d '8 0' t3 +hg log --template '{rev}: {latesttag}+{latesttagdistance}\n' + +echo '# merged tag overrides' +hg tag -r 5 -m t5 -d '9 0' t5 +hg tag -r 3 -m at3 -d '10 0' at3 +hg log --template '{rev}: {latesttag}+{latesttagdistance}\n' + echo '# done' diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-command-template.out --- a/tests/test-command-template.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-command-template.out Thu Oct 08 01:16:32 2009 -0500 @@ -672,4 +672,55 @@ 1e4e1b8f71e05681d422154f5421e385fec3454f # error on syntax abort: t:3: unmatched quotes +# latesttag +adding file +adding head1 +adding head2 +created new head +# No tag set +5: null+5 +4: null+4 +3: null+3 +2: null+3 +1: null+2 +0: null+1 +# one common tag: longuest path wins +6: t1+4 +5: t1+3 +4: t1+2 +3: t1+1 +2: t1+1 +1: t1+0 +0: null+1 +# one ancestor tag: more recent wins +7: t2+3 +6: t2+2 +5: t2+1 +4: t1+2 +3: t1+1 +2: t2+0 +1: t1+0 +0: null+1 +# two branch tags: more recent wins +8: t3+5 +7: t3+4 +6: t3+3 +5: t3+2 +4: t3+1 +3: t3+0 +2: t2+0 +1: t1+0 +0: null+1 +# merged tag overrides +10: t5+5 +9: t5+4 +8: t5+3 +7: t5+2 +6: t5+1 +5: t5+0 +4: at3:t3+1 +3: at3:t3+0 +2: t2+0 +1: t1+0 +0: null+1 # done diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-commit-unresolved.out --- a/tests/test-commit-unresolved.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-commit-unresolved.out Thu Oct 08 01:16:32 2009 -0500 @@ -6,7 +6,7 @@ warning: conflicts during merge. merging A failed! 1 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon % Correct the conflict without marking the file as resolved abort: unresolved merge conflicts (see hg resolve) diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-conflict.out --- a/tests/test-conflict.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-conflict.out Thu Oct 08 01:16:32 2009 -0500 @@ -4,7 +4,7 @@ warning: conflicts during merge. merging a failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon e7fe8eb3e180+0d24b7662d3e+ tip <<<<<<< local something else diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-cvs --- a/tests/test-convert-cvs Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-cvs Thu Oct 08 01:16:32 2009 -0500 @@ -1,10 +1,10 @@ #!/bin/sh -"$TESTDIR/hghave" cvs cvsps || exit 80 +"$TESTDIR/hghave" cvs || exit 80 cvscall() { - cvs -f $@ + cvs -f "$@" } hgcat() @@ -12,12 +12,9 @@ hg --cwd src-hg cat -r tip "$1" } -# Test legacy configuration with external cvsps echo "[extensions]" >> $HGRCPATH echo "convert = " >> $HGRCPATH echo "graphlog = " >> $HGRCPATH -echo "[convert]" >> $HGRCPATH -echo "cvsps=cvsps -A -u --cvs-direct -q" >> $HGRCPATH echo % create cvs repository mkdir cvsrepo @@ -95,11 +92,29 @@ echo % convert again hg convert src src-hg | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g' -hgcat a hgcat b/c echo % convert again with --filemap hg convert --filemap filemap src src-filemap | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g' hgcat b/c hg -R src-filemap log --template '{rev} {desc} files: {files}\n' + +echo % commit a new revision with funny log message +cd src +sleep 1 +echo e >> a +cvscall -q commit -m'funny +---------------------------- +log message' . | grep '<--' |\ + sed -e 's:.*src/\(.*\),v.*:checking in src/\1,v:g' +cd .. + +echo % convert again +hg convert src src-hg | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g' + +echo "graphlog = " >> $HGRCPATH hg -R src-hg glog --template '{rev} ({branches}) {desc} files: {files}\n' + +echo % testing debugcvsps +cd src +hg debugcvsps | sed -e 's/Author:.*/Author:/' -e 's/Date:.*/Date:/' diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-cvs-branch --- a/tests/test-convert-cvs-branch Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-cvs-branch Thu Oct 08 01:16:32 2009 -0500 @@ -14,7 +14,6 @@ echo "convert = " >> $HGRCPATH echo "graphlog = " >> $HGRCPATH echo "[convert]" >> $HGRCPATH -echo "cvsps=builtin" >> $HGRCPATH echo "cvsps.cache=0" >> $HGRCPATH echo % create cvs repository diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-cvs-branch.out --- a/tests/test-convert-cvs-branch.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-cvs-branch.out Thu Oct 08 01:16:32 2009 -0500 @@ -25,7 +25,6 @@ initializing destination src-hg repository connecting to cvsrepo scanning source... -using builtin cvsps collecting CVS rlog 7 log entries creating changesets diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-cvs-builtincvsps --- a/tests/test-convert-cvs-builtincvsps Tue Oct 06 11:18:58 2009 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -#!/bin/sh - -"$TESTDIR/hghave" cvs || exit 80 - -cvscall() -{ - cvs -f "$@" -} - -hgcat() -{ - hg --cwd src-hg cat -r tip "$1" -} - -echo "[extensions]" >> $HGRCPATH -echo "convert = " >> $HGRCPATH -echo "graphlog = " >> $HGRCPATH -echo "[convert]" >> $HGRCPATH -echo "cvsps=builtin" >> $HGRCPATH - -echo % create cvs repository -mkdir cvsrepo -cd cvsrepo -CVSROOT=`pwd` -export CVSROOT -CVS_OPTIONS=-f -export CVS_OPTIONS -cd .. - -cvscall -q -d "$CVSROOT" init - -echo % create source directory -mkdir src-temp -cd src-temp -echo a > a -mkdir b -cd b -echo c > c -cd .. - -echo % import source directory -cvscall -q import -m import src INITIAL start -cd .. - -echo % checkout source directory -cvscall -q checkout src - -echo % commit a new revision changing b/c -cd src -sleep 1 -echo c >> b/c -cvscall -q commit -mci0 . | grep '<--' |\ - sed -e 's:.*src/\(.*\),v.*:checking in src/\1,v:g' -cd .. - -echo % convert fresh repo -hg convert src src-hg | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g' -hgcat a -hgcat b/c - -echo % convert fresh repo with --filemap -echo include b/c > filemap -hg convert --filemap filemap src src-filemap | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g' -hgcat b/c -hg -R src-filemap log --template '{rev} {desc} files: {files}\n' - -echo % commit new file revisions -cd src -echo a >> a -echo c >> b/c -cvscall -q commit -mci1 . | grep '<--' |\ - sed -e 's:.*src/\(.*\),v.*:checking in src/\1,v:g' -cd .. - -echo % convert again -hg convert src src-hg | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g' -hgcat a -hgcat b/c - -echo % convert again with --filemap -hg convert --filemap filemap src src-filemap | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g' -hgcat b/c -hg -R src-filemap log --template '{rev} {desc} files: {files}\n' - -echo % commit branch -cd src -cvs -q update -r1.1 b/c -cvs -q tag -b branch -cvs -q update -r branch > /dev/null -echo d >> b/c -cvs -q commit -mci2 . | grep '<--' |\ - sed -e 's:.*src/\(.*\),v.*:checking in src/\1,v:g' -cd .. - -echo % convert again -hg convert src src-hg | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g' -hgcat b/c - -echo % convert again with --filemap -hg convert --filemap filemap src src-filemap | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g' -hgcat b/c -hg -R src-filemap log --template '{rev} {desc} files: {files}\n' - -echo % commit a new revision with funny log message -cd src -sleep 1 -echo e >> a -cvscall -q commit -m'funny ----------------------------- -log message' . | grep '<--' |\ - sed -e 's:.*src/\(.*\),v.*:checking in src/\1,v:g' -cd .. - -echo % convert again -hg convert src src-hg | sed -e 's/connecting to.*cvsrepo/connecting to cvsrepo/g' - -echo "graphlog = " >> $HGRCPATH -hg -R src-hg glog --template '{rev} ({branches}) {desc} files: {files}\n' - -echo % testing debugcvsps -cd src -hg debugcvsps | sed -e 's/Author:.*/Author:/' -e 's/Date:.*/Date:/' diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-cvs-builtincvsps.out --- a/tests/test-convert-cvs-builtincvsps.out Tue Oct 06 11:18:58 2009 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,261 +0,0 @@ -% create cvs repository -% create source directory -% import source directory -N src/a -N src/b/c - -No conflicts created by this import - -% checkout source directory -U src/a -U src/b/c -% commit a new revision changing b/c -checking in src/b/c,v -% convert fresh repo -initializing destination src-hg repository -connecting to cvsrepo -scanning source... -using builtin cvsps -collecting CVS rlog -5 log entries -creating changesets -3 changeset entries -sorting... -converting... -2 Initial revision -1 import -0 ci0 -updating tags -a -c -c -% convert fresh repo with --filemap -initializing destination src-filemap repository -connecting to cvsrepo -scanning source... -using builtin cvsps -collecting CVS rlog -5 log entries -creating changesets -3 changeset entries -sorting... -converting... -2 Initial revision -1 import -filtering out empty revision -rolling back last transaction -0 ci0 -updating tags -c -c -2 update tags files: .hgtags -1 ci0 files: b/c -0 Initial revision files: b/c -% commit new file revisions -checking in src/a,v -checking in src/b/c,v -% convert again -connecting to cvsrepo -scanning source... -using builtin cvsps -collecting CVS rlog -7 log entries -creating changesets -4 changeset entries -sorting... -converting... -0 ci1 -a -a -c -c -c -% convert again with --filemap -connecting to cvsrepo -scanning source... -using builtin cvsps -collecting CVS rlog -7 log entries -creating changesets -4 changeset entries -sorting... -converting... -0 ci1 -c -c -c -3 ci1 files: b/c -2 update tags files: .hgtags -1 ci0 files: b/c -0 Initial revision files: b/c -% commit branch -U b/c -T a -T b/c -checking in src/b/c,v -% convert again -connecting to cvsrepo -scanning source... -using builtin cvsps -collecting CVS rlog -8 log entries -creating changesets -5 changeset entries -sorting... -converting... -0 ci2 -c -d -% convert again with --filemap -connecting to cvsrepo -scanning source... -using builtin cvsps -collecting CVS rlog -8 log entries -creating changesets -5 changeset entries -sorting... -converting... -0 ci2 -c -d -4 ci2 files: b/c -3 ci1 files: b/c -2 update tags files: .hgtags -1 ci0 files: b/c -0 Initial revision files: b/c -% commit a new revision with funny log message -checking in src/a,v -% convert again -connecting to cvsrepo -scanning source... -using builtin cvsps -collecting CVS rlog -9 log entries -creating changesets -6 changeset entries -sorting... -converting... -0 funny -o 6 (branch) funny -| ---------------------------- -| log message files: a -o 5 (branch) ci2 files: b/c - -o 4 () ci1 files: a b/c -| -o 3 () update tags files: .hgtags -| -o 2 () ci0 files: b/c -| -| o 1 (INITIAL) import files: -|/ -o 0 () Initial revision files: a b/c - -% testing debugcvsps -collecting CVS rlog -9 log entries -creating changesets -8 changeset entries ---------------------- -PatchSet 1 -Date: -Author: -Branch: HEAD -Tag: (none) -Branchpoints: INITIAL -Log: -Initial revision - -Members: - a:INITIAL->1.1 - ---------------------- -PatchSet 2 -Date: -Author: -Branch: HEAD -Tag: (none) -Branchpoints: INITIAL, branch -Log: -Initial revision - -Members: - b/c:INITIAL->1.1 - ---------------------- -PatchSet 3 -Date: -Author: -Branch: INITIAL -Tag: start -Log: -import - -Members: - a:1.1->1.1.1.1 - b/c:1.1->1.1.1.1 - ---------------------- -PatchSet 4 -Date: -Author: -Branch: HEAD -Tag: (none) -Log: -ci0 - -Members: - b/c:1.1->1.2 - ---------------------- -PatchSet 5 -Date: -Author: -Branch: HEAD -Tag: (none) -Branchpoints: branch -Log: -ci1 - -Members: - a:1.1->1.2 - ---------------------- -PatchSet 6 -Date: -Author: -Branch: HEAD -Tag: (none) -Log: -ci1 - -Members: - b/c:1.2->1.3 - ---------------------- -PatchSet 7 -Date: -Author: -Branch: branch -Tag: (none) -Log: -ci2 - -Members: - b/c:1.1->1.1.2.1 - ---------------------- -PatchSet 8 -Date: -Author: -Branch: branch -Tag: (none) -Log: -funny ----------------------------- -log message - -Members: - a:1.2->1.2.2.1 - diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-cvs-detectmerge --- a/tests/test-convert-cvs-detectmerge Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-cvs-detectmerge Thu Oct 08 01:16:32 2009 -0500 @@ -34,7 +34,6 @@ echo "convert = " >> $HGRCPATH echo "graphlog = " >> $HGRCPATH echo "[convert]" >> $HGRCPATH -echo "cvsps=builtin" >> $HGRCPATH echo "cvsps.cache=0" >> $HGRCPATH echo "cvsps.mergefrom=\[MERGE from (\S+)\]" >> $HGRCPATH diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-cvs-detectmerge.out --- a/tests/test-convert-cvs-detectmerge.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-cvs-detectmerge.out Thu Oct 08 01:16:32 2009 -0500 @@ -77,7 +77,6 @@ initializing destination proj.hg repository connecting to *REPO* scanning source... -using builtin cvsps collecting CVS rlog 12 log entries creating changesets diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-cvs-synthetic --- a/tests/test-convert-cvs-synthetic Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-cvs-synthetic Thu Oct 08 01:16:32 2009 -0500 @@ -8,8 +8,6 @@ echo "[extensions]" >> $HGRCPATH echo "convert = " >> $HGRCPATH echo "graphlog = " >> $HGRCPATH -echo "[convert]" >> $HGRCPATH -echo "cvsps=builtin" >> $HGRCPATH echo % create cvs repository with one project mkdir cvsrepo diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-cvs-synthetic.out --- a/tests/test-convert-cvs-synthetic.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-cvs-synthetic.out Thu Oct 08 01:16:32 2009 -0500 @@ -66,7 +66,6 @@ initializing destination proj.hg repository connecting to *REPO* scanning source... -using builtin cvsps collecting CVS rlog 15 log entries creating changesets @@ -102,7 +101,6 @@ initializing destination proj.hg2 repository connecting to *REPO* scanning source... -using builtin cvsps collecting CVS rlog 15 log entries creating changesets diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-cvs.out --- a/tests/test-convert-cvs.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-cvs.out Thu Oct 08 01:16:32 2009 -0500 @@ -12,10 +12,13 @@ % commit a new revision changing b/c checking in src/b/c,v % convert fresh repo -warning: support for external cvsps is deprecated and will be removed in Mercurial 1.4 initializing destination src-hg repository connecting to cvsrepo scanning source... +collecting CVS rlog +5 log entries +creating changesets +3 changeset entries sorting... converting... 2 Initial revision @@ -26,10 +29,13 @@ c c % convert fresh repo with --filemap -warning: support for external cvsps is deprecated and will be removed in Mercurial 1.4 initializing destination src-filemap repository connecting to cvsrepo scanning source... +collecting CVS rlog +5 log entries +creating changesets +3 changeset entries sorting... converting... 2 Initial revision @@ -47,9 +53,12 @@ checking in src/a,v checking in src/b/c,v % convert again -warning: support for external cvsps is deprecated and will be removed in Mercurial 1.4 connecting to cvsrepo scanning source... +collecting CVS rlog +7 log entries +creating changesets +4 changeset entries sorting... converting... 0 ci1 @@ -59,9 +68,12 @@ c c % convert again with --filemap -warning: support for external cvsps is deprecated and will be removed in Mercurial 1.4 connecting to cvsrepo scanning source... +collecting CVS rlog +7 log entries +creating changesets +4 changeset entries sorting... converting... 0 ci1 @@ -78,19 +90,24 @@ T b/c checking in src/b/c,v % convert again -warning: support for external cvsps is deprecated and will be removed in Mercurial 1.4 connecting to cvsrepo scanning source... +collecting CVS rlog +8 log entries +creating changesets +5 changeset entries sorting... converting... 0 ci2 -a c d % convert again with --filemap -warning: support for external cvsps is deprecated and will be removed in Mercurial 1.4 connecting to cvsrepo scanning source... +collecting CVS rlog +8 log entries +creating changesets +5 changeset entries sorting... converting... 0 ci2 @@ -101,15 +118,137 @@ 2 update tags files: .hgtags 1 ci0 files: b/c 0 Initial revision files: b/c +% commit a new revision with funny log message +checking in src/a,v +% convert again +connecting to cvsrepo +scanning source... +collecting CVS rlog +9 log entries +creating changesets +6 changeset entries +sorting... +converting... +0 funny +o 6 (branch) funny +| ---------------------------- +| log message files: a o 5 (branch) ci2 files: b/c + +o 4 () ci1 files: a b/c | -| o 4 () ci1 files: a b/c -| | -| o 3 () update tags files: .hgtags -| | -| o 2 () ci0 files: b/c -|/ +o 3 () update tags files: .hgtags +| +o 2 () ci0 files: b/c +| | o 1 (INITIAL) import files: |/ o 0 () Initial revision files: a b/c +% testing debugcvsps +collecting CVS rlog +9 log entries +creating changesets +8 changeset entries +--------------------- +PatchSet 1 +Date: +Author: +Branch: HEAD +Tag: (none) +Branchpoints: INITIAL +Log: +Initial revision + +Members: + a:INITIAL->1.1 + +--------------------- +PatchSet 2 +Date: +Author: +Branch: HEAD +Tag: (none) +Branchpoints: INITIAL, branch +Log: +Initial revision + +Members: + b/c:INITIAL->1.1 + +--------------------- +PatchSet 3 +Date: +Author: +Branch: INITIAL +Tag: start +Log: +import + +Members: + a:1.1->1.1.1.1 + b/c:1.1->1.1.1.1 + +--------------------- +PatchSet 4 +Date: +Author: +Branch: HEAD +Tag: (none) +Log: +ci0 + +Members: + b/c:1.1->1.2 + +--------------------- +PatchSet 5 +Date: +Author: +Branch: HEAD +Tag: (none) +Branchpoints: branch +Log: +ci1 + +Members: + a:1.1->1.2 + +--------------------- +PatchSet 6 +Date: +Author: +Branch: HEAD +Tag: (none) +Log: +ci1 + +Members: + b/c:1.2->1.3 + +--------------------- +PatchSet 7 +Date: +Author: +Branch: branch +Tag: (none) +Log: +ci2 + +Members: + b/c:1.1->1.1.2.1 + +--------------------- +PatchSet 8 +Date: +Author: +Branch: branch +Tag: (none) +Log: +funny +---------------------------- +log message + +Members: + a:1.2->1.2.2.1 + diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-cvsnt-mergepoints --- a/tests/test-convert-cvsnt-mergepoints Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-cvsnt-mergepoints Thu Oct 08 01:16:32 2009 -0500 @@ -29,8 +29,6 @@ echo "[extensions]" >> $HGRCPATH echo "convert = " >> $HGRCPATH echo "graphlog = " >> $HGRCPATH -echo "[convert]" >> $HGRCPATH -echo "cvsps=builtin" >> $HGRCPATH echo "% create cvs repository" mkdir cvsmaster diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-darcs --- a/tests/test-convert-darcs Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-darcs Thu Oct 08 01:16:32 2009 -0500 @@ -43,7 +43,19 @@ darcs pull -a ../darcs-clone sleep 1 echo e > a +echo f > f +mkdir dir +echo d > dir/d +echo d > dir/d2 darcs record -a -l -m p2 + +echo % test file and directory move +darcs mv f ff +# Test remove + move +darcs remove dir/d2 +rm dir/d2 +darcs mv dir dir2 +darcs record -a -l -m p3 cd .. glog() diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-darcs.out --- a/tests/test-convert-darcs.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-darcs.out Thu Oct 08 01:16:32 2009 -0500 @@ -10,15 +10,20 @@ ./a Finished pulling and applying. Finished recording patch 'p2' +% test file and directory move +Finished recording patch 'p3' initializing destination darcs-repo-hg repository scanning source... sorting... converting... -3 p0 -2 p1.2 -1 p1.1 -0 p2 -o 3 "p2" files: a +4 p0 +3 p1.2 +2 p1.1 +1 p2 +0 p3 +o 4 "p3" files: dir/d dir/d2 dir2/d f ff +| +o 3 "p2" files: a dir/d dir/d2 f | o 2 "p1.1" files: | @@ -28,3 +33,5 @@ 7225b30cdf38257d5cc7780772c051b6f33e6d6b 644 a 1e88685f5ddec574a34c70af492f95b6debc8741 644 b +d278f41640da5fc303a4cf9894af31c2983fc11d 644 dir2/d +ef5c76581d78340f568d5f48d679bf307452cbc9 644 ff diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-hg-source --- a/tests/test-convert-hg-source Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-hg-source Thu Oct 08 01:16:32 2009 -0500 @@ -38,6 +38,25 @@ hg out ../orig cd .. +echo '% check shamap LF and CRLF handling' +cat > rewrite.py <> foo +hg ci -qm 'change foo again' +hg up -qC 2 +echo foo >> foo +hg ci -qm 'change foo again again' +cd .. +hg convert --datesort orig new 2>&1 | grep -v 'subversion python bindings could not be loaded' + echo % init broken repository hg init broken cd broken diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-hg-source.out --- a/tests/test-convert-hg-source.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-hg-source.out Thu Oct 08 01:16:32 2009 -0500 @@ -20,6 +20,12 @@ comparing with ../orig searching for changes no changes found +% check shamap LF and CRLF handling +scanning source... +sorting... +converting... +1 change foo again again +0 change foo again % init broken repository created new head % break it diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert-svn-sink.out --- a/tests/test-convert-svn-sink.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert-svn-sink.out Thu Oct 08 01:16:32 2009 -0500 @@ -265,7 +265,7 @@ warning: conflicts during merge. merging b failed! 2 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon assuming destination b-hg initializing svn repo 'b-hg' initializing svn wc 'b-hg-wc' diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-convert.out --- a/tests/test-convert.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-convert.out Thu Oct 08 01:16:32 2009 -0500 @@ -117,23 +117,8 @@ starting directory will be converted, and that any directory reorganization in the CVS sandbox is ignored. - Because CVS does not have changesets, it is necessary to collect - individual commits to CVS and merge them into changesets. CVS source uses - its internal changeset merging code by default but can be configured to - call the external 'cvsps' program by setting: - - --config convert.cvsps='cvsps -A -u --cvs-direct -q' - - This option is deprecated and will be removed in Mercurial 1.4. - The options shown are the defaults. - Internal cvsps is selected by setting - - --config convert.cvsps=builtin - - and has a few more configurable options: - --config convert.cvsps.cache=True (boolean) Set to False to disable remote log caching, for testing and debugging purposes. @@ -153,9 +138,10 @@ recent revision on the branch indicated in the regex as the second parent of the changeset. - The hgext/convert/cvsps wrapper script allows the builtin changeset + An additional "debugcvsps" Mercurial command allows the builtin changeset merging code to be run without doing a conversion. Its parameters and - output are similar to that of cvsps 2.1. + output are similar to that of cvsps 2.1. Please see the command help for + more details. Subversion Source ----------------- diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-encoding --- a/tests/test-encoding Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-encoding Thu Oct 08 01:16:32 2009 -0500 @@ -29,30 +29,31 @@ HGENCODING=latin-1 hg ci -d "1000000 0" -m 'latin1 branch' rm .hg/branch -echo % ascii +echo "% hg log (ascii)" hg --encoding ascii log -echo % latin-1 +echo "% hg log (latin-1)" hg --encoding latin-1 log -echo % utf-8 +echo "% hg log (utf-8)" hg --encoding utf-8 log -echo % ascii +echo "% hg tags (ascii)" HGENCODING=ascii hg tags -echo % latin-1 +echo "% hg tags (latin-1)" HGENCODING=latin-1 hg tags -echo % utf-8 +echo "% hg tags (utf-8)" HGENCODING=utf-8 hg tags -echo % ascii +echo "% hg branches (ascii)" HGENCODING=ascii hg branches -echo % latin-1 +echo "% hg branches (latin-1)" HGENCODING=latin-1 hg branches -echo % utf-8 +echo "% hg branches (utf-8)" HGENCODING=utf-8 hg branches echo '[ui]' >> .hg/hgrc echo 'fallbackencoding = koi8-r' >> .hg/hgrc -echo % utf-8 +echo "% hg log (utf-8)" HGENCODING=utf-8 hg log +echo "% hg log (dolphin)" HGENCODING=dolphin hg log HGENCODING=ascii hg branch `cat latin-1-tag` diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-encoding.out --- a/tests/test-encoding.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-encoding.out Thu Oct 08 01:16:32 2009 -0500 @@ -14,7 +14,7 @@ abort: decoding near ' encoded: é': 'ascii' codec can't decode byte 0xe9 in position 20: ordinal not in range(128)! % these should work marked working directory as branch é -% ascii +% hg log (ascii) changeset: 5:db5520b4645f branch: ? tag: tip @@ -48,7 +48,7 @@ date: Mon Jan 12 13:46:40 1970 +0000 summary: latin-1 e': ? = u'\xe9' -% latin-1 +% hg log (latin-1) changeset: 5:db5520b4645f branch: é tag: tip @@ -82,7 +82,7 @@ date: Mon Jan 12 13:46:40 1970 +0000 summary: latin-1 e': é = u'\xe9' -% utf-8 +% hg log (utf-8) changeset: 5:db5520b4645f branch: é tag: tip @@ -116,25 +116,25 @@ date: Mon Jan 12 13:46:40 1970 +0000 summary: latin-1 e': é = u'\xe9' -% ascii +% hg tags (ascii) tip 5:db5520b4645f ? 3:770b9b11621d -% latin-1 +% hg tags (latin-1) tip 5:db5520b4645f é 3:770b9b11621d -% utf-8 +% hg tags (utf-8) tip 5:db5520b4645f é 3:770b9b11621d -% ascii +% hg branches (ascii) ? 5:db5520b4645f default 4:9cff3c980b58 (inactive) -% latin-1 +% hg branches (latin-1) é 5:db5520b4645f default 4:9cff3c980b58 (inactive) -% utf-8 +% hg branches (utf-8) é 5:db5520b4645f default 4:9cff3c980b58 (inactive) -% utf-8 +% hg log (utf-8) changeset: 5:db5520b4645f branch: é tag: tip @@ -168,6 +168,7 @@ date: Mon Jan 12 13:46:40 1970 +0000 summary: latin-1 e': И = u'\xe9' +% hg log (dolphin) abort: unknown encoding: dolphin, please check your locale settings abort: decoding near 'é': 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)! abort: branch name not in UTF-8! diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-extension.out --- a/tests/test-extension.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-extension.out Thu Oct 08 01:16:32 2009 -0500 @@ -44,7 +44,7 @@ debugextension only debugcommands global options: - -R --repository repository root directory or symbolic path name + -R --repository repository root directory or name of overlay bundle file --cwd change working directory -y --noninteractive do not prompt, assume 'yes' for any required answers -q --quiet suppress output @@ -74,7 +74,7 @@ debugextension only debugcommands global options: - -R --repository repository root directory or symbolic path name + -R --repository repository root directory or name of overlay bundle file --cwd change working directory -y --noninteractive do not prompt, assume 'yes' for any required answers -q --quiet suppress output diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-gendoc --- a/tests/test-gendoc Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-gendoc Thu Oct 08 01:16:32 2009 -0500 @@ -3,10 +3,19 @@ "$TESTDIR/hghave" rst2html || exit 80 RST2HTML=$(which rst2html 2> /dev/null || which rst2html.py) -echo "checking for syntax errors in gendoc.py" -python $TESTDIR/../doc/gendoc.py > gendoc.txt || exit +HGENCODING=UTF-8 +export HGENCODING -# We run rst2html over the file without adding "--halt warning" to -# make it report all errors instead of stopping on the first one. -echo "checking for parse errors with rst2html" -$RST2HTML gendoc.txt /dev/null +for PO in C $TESTDIR/../i18n/*.po; do + LOCALE=$(basename $PO .po) + echo + echo "% extracting documentation from $LOCALE" + echo ".. -*- coding: utf-8 -*-" > gendoc-$LOCALE.txt + echo "" >> gendoc-$LOCALE.txt + LC_ALL=$LOCALE python $TESTDIR/../doc/gendoc.py >> gendoc-$LOCALE.txt || exit + + # We run rst2html over the file without adding "--halt warning" to + # make it report all errors instead of stopping on the first one. + echo "checking for parse errors with rst2html" + $RST2HTML gendoc-$LOCALE.txt /dev/null +done diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-gendoc.out --- a/tests/test-gendoc.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-gendoc.out Thu Oct 08 01:16:32 2009 -0500 @@ -1,2 +1,30 @@ -checking for syntax errors in gendoc.py + +% extracting documentation from C +checking for parse errors with rst2html + +% extracting documentation from da +checking for parse errors with rst2html + +% extracting documentation from de +checking for parse errors with rst2html + +% extracting documentation from el +checking for parse errors with rst2html + +% extracting documentation from fr checking for parse errors with rst2html + +% extracting documentation from it +checking for parse errors with rst2html + +% extracting documentation from ja +checking for parse errors with rst2html + +% extracting documentation from pt_BR +checking for parse errors with rst2html + +% extracting documentation from zh_CN +checking for parse errors with rst2html + +% extracting documentation from zh_TW +checking for parse errors with rst2html diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-http --- a/tests/test-http Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-http Thu Oct 08 01:16:32 2009 -0500 @@ -5,6 +5,11 @@ hg init test cd test echo foo>foo +mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg +echo foo>foo.d/foo +echo bar>foo.d/bAr.hg.d/BaR +echo bar>foo.d/baR.d.hg/bAR + hg commit -A -m 1 hg --config server.uncompressed=True serve -p $HGPORT -d --pid-file=../hg1.pid hg serve -p $HGPORT1 -d --pid-file=../hg2.pid diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-http.out --- a/tests/test-http.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-http.out Thu Oct 08 01:16:32 2009 -0500 @@ -1,4 +1,7 @@ adding foo +adding foo.d/bAr.hg.d/BaR +adding foo.d/baR.d.hg/bAR +adding foo.d/foo abort: cannot start server at ':20060': % clone via stream streaming all changes @@ -10,31 +13,31 @@ checking manifests crosschecking files in changesets and manifests checking files -1 files, 1 changesets, 1 total revisions +4 files, 1 changesets, 4 total revisions % try to clone via stream, should use pull instead requesting all changes adding changesets adding manifests adding file changes -added 1 changesets with 1 changes to 1 files +added 1 changesets with 4 changes to 4 files updating working directory -1 files updated, 0 files merged, 0 files removed, 0 files unresolved +4 files updated, 0 files merged, 0 files removed, 0 files unresolved % clone via pull requesting all changes adding changesets adding manifests adding file changes -added 1 changesets with 1 changes to 1 files +added 1 changesets with 4 changes to 4 files updating working directory -1 files updated, 0 files merged, 0 files removed, 0 files unresolved +4 files updated, 0 files merged, 0 files removed, 0 files unresolved checking changesets checking manifests crosschecking files in changesets and manifests checking files -1 files, 1 changesets, 1 total revisions +4 files, 1 changesets, 4 total revisions adding bar % pull -changegroup hook: HG_NODE=cfbd11a1fa315300a080c3de8fe36b0fc5820acf HG_SOURCE=pull HG_URL=http://localhost/ +changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_URL=http://localhost/ pulling from http://localhost/ searching for changes adding changesets diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-inotify-issue1208.out --- a/tests/test-inotify-issue1208.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-inotify-issue1208.out Thu Oct 08 01:16:32 2009 -0500 @@ -1,5 +1,5 @@ % fail -could not talk to new inotify server: No such file or directory +abort: could not start server: File exists abort: could not start server: File exists % inserve % status diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-keyword --- a/tests/test-keyword Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-keyword Thu Oct 08 01:16:32 2009 -0500 @@ -48,6 +48,11 @@ echo % cat cat a b +echo % no kwfiles +hg kwfiles +echo % untracked candidates +hg -v kwfiles --unknown + echo % addremove hg addremove echo % status @@ -162,6 +167,10 @@ echo % kwfiles hg kwfiles +echo % ignored files +hg -v kwfiles --ignore +echo % all files +hg kwfiles --all echo % diff --rev hg diff --rev 1 | grep -v 'b/c' diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-keyword.out --- a/tests/test-keyword.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-keyword.out Thu Oct 08 01:16:32 2009 -0500 @@ -42,6 +42,9 @@ do not process $Id: xxx $ ignore $Id$ +% no kwfiles +% untracked candidates +k a % addremove adding a adding b @@ -181,6 +184,14 @@ % kwfiles a c +% ignored files +I b +I sym +% all files +K a +K c +I b +I sym % diff --rev diff -r ef63ca68695b c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -400,7 +411,7 @@ warning: conflicts during merge. merging m failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon % keyword stays outside conflict zone $Id$ <<<<<<< local diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-merge-internal-tools-pattern.out --- a/tests/test-merge-internal-tools-pattern.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-merge-internal-tools-pattern.out Thu Oct 08 01:16:32 2009 -0500 @@ -9,7 +9,7 @@ created new head # merge using internal:fail tool 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon line 1 line 2 third line diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-merge-tools.out --- a/tests/test-merge-tools.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-merge-tools.out Thu Oct 08 01:16:32 2009 -0500 @@ -17,7 +17,7 @@ warning: conflicts during merge. merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f <<<<<<< local revision 1 @@ -37,7 +37,7 @@ merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space @@ -69,7 +69,7 @@ merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space @@ -86,7 +86,7 @@ merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space @@ -103,7 +103,7 @@ merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space @@ -120,7 +120,7 @@ merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space @@ -185,7 +185,7 @@ merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space @@ -204,7 +204,7 @@ merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space @@ -223,7 +223,7 @@ merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space @@ -244,7 +244,7 @@ merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space @@ -260,7 +260,7 @@ # hg update -C 1 # hg merge -r 2 --config ui.merge=internal:fail 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space @@ -323,7 +323,7 @@ # hg merge -r 2 --config ui.merge=internal:dump merging f 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space @@ -354,7 +354,7 @@ merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space @@ -518,7 +518,7 @@ was merge successful (yn)? n merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon # cat f revision 1 space diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-merge7.out --- a/tests/test-merge7.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-merge7.out Thu Oct 08 01:16:32 2009 -0500 @@ -11,7 +11,7 @@ warning: conflicts during merge. merging test.txt failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon pulling from ../test-a searching for changes adding changesets @@ -31,7 +31,7 @@ warning: conflicts during merge. merging test.txt failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon one <<<<<<< local two-point-five diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-merge9.out --- a/tests/test-merge9.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-merge9.out Thu Oct 08 01:16:32 2009 -0500 @@ -7,7 +7,7 @@ merging bar failed! merging foo and baz to baz 1 files updated, 1 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon U bar R baz 3 files updated, 0 files merged, 1 files removed, 0 files unresolved @@ -15,7 +15,7 @@ merging bar failed! merging baz and foo to baz 1 files updated, 1 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon % show unresolved U bar R baz diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-notify.out --- a/tests/test-notify.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-notify.out Thu Oct 08 01:16:32 2009 -0500 @@ -35,6 +35,7 @@ diffstat = True # add a diffstat before the diff content sources = serve # notify if source of incoming changes in this list # (serve == ssh or http, push, pull, bundle) + merge = False # send notification for merges (default True) [email] from = user@host.com # email address to send as if none given [web] diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-resolve.out --- a/tests/test-resolve.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-resolve.out Thu Oct 08 01:16:32 2009 -0500 @@ -4,5 +4,5 @@ created new head % failing merge 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon % resolve -l, should be empty diff -r 620d6b20ef85 -r ceb0f59e1327 tests/test-subrepo.out --- a/tests/test-subrepo.out Tue Oct 06 11:18:58 2009 +0300 +++ b/tests/test-subrepo.out Thu Oct 08 01:16:32 2009 -0500 @@ -87,7 +87,7 @@ warning: conflicts during merge. merging t failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved -use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon +use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) % should conflict