--- a/contrib/check-code.py Tue Sep 03 18:05:11 2013 -0500
+++ b/contrib/check-code.py Tue Sep 03 18:08:27 2013 -0500
@@ -61,11 +61,13 @@
(r'pushd|popd', "don't use 'pushd' or 'popd', use 'cd'"),
(r'\W\$?\(\([^\)\n]*\)\)', "don't use (()) or $(()), use 'expr'"),
(r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"),
+ (r'(?<!hg )grep.*-a', "don't use 'grep -a', use in-line python"),
(r'sed.*-i', "don't use 'sed -i', use a temporary file"),
(r'\becho\b.*\\n', "don't use 'echo \\n', use printf"),
(r'echo -n', "don't use 'echo -n', use printf"),
(r'(^| )wc[^|]*$\n(?!.*\(re\))', "filter wc output"),
(r'head -c', "don't use 'head -c', use 'dd'"),
+ (r'tail -n', "don't use the '-n' option to tail, just use '-<num>'"),
(r'sha1sum', "don't use sha1sum, use $TESTDIR/md5sum.py"),
(r'ls.*-\w*R', "don't use 'ls -R', use 'find'"),
(r'printf.*[^\\]\\([1-9]|0\d)', "don't use 'printf \NNN', use Python"),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/plan9/9mail Tue Sep 03 18:08:27 2013 -0500
@@ -0,0 +1,26 @@
+#!/bin/rc
+# 9mail - Mercurial email wrapper for upas/marshal
+
+fn usage {
+ echo >[1=2] usage: mercurial/9mail -f from to [cc]
+ exit usage
+}
+
+from=()
+cc=()
+to=()
+
+switch($1){
+case -f
+ from=$2
+case *
+ usage
+}
+
+to=($3)
+if(~ $#* 4)
+ cc=(-C $4)
+
+upasname=$from
+upas/marshal $cc $to
+
--- a/contrib/plan9/hgrc.d/9diff.rc Tue Sep 03 18:05:11 2013 -0500
+++ b/contrib/plan9/hgrc.d/9diff.rc Tue Sep 03 18:08:27 2013 -0500
@@ -4,4 +4,4 @@
extdiff =
[extdiff]
-9diff = 9diff -cm $parent $child $root
+9diff = /bin/mercurial/9diff -cm $parent $child $root
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/plan9/hgrc.d/9mail.rc Tue Sep 03 18:08:27 2013 -0500
@@ -0,0 +1,4 @@
+# The 9mail to support patchbomb and other email wrappers
+[email]
+method = /bin/mercurial/9mail
+
--- a/hgext/factotum.py Tue Sep 03 18:05:11 2013 -0500
+++ b/hgext/factotum.py Tue Sep 03 18:08:27 2013 -0500
@@ -101,7 +101,7 @@
user, passwd = auth.get('username'), auth.get('password')
if not user or not passwd:
if not prefix:
- prefix = '*'
+ prefix = realm.split(' ')[0].lower()
params = 'service=%s prefix=%s' % (_service, prefix)
if user:
params = '%s user=%s' % (params, user)
--- a/hgext/histedit.py Tue Sep 03 18:05:11 2013 -0500
+++ b/hgext/histedit.py Tue Sep 03 18:08:27 2013 -0500
@@ -419,10 +419,6 @@
if revs:
revs = [repo.lookup(rev) for rev in revs]
- # hexlify nodes from outgoing, because we're going to parse
- # parent[0] using revsingle below, and if the binary hash
- # contains special revset characters like ":" the revset
- # parser can choke.
outgoing = discovery.findcommonoutgoing(repo, other, revs, force=force)
if not outgoing.missing:
raise util.Abort(_('no outgoing ancestors'))
--- a/hgext/largefiles/reposetup.py Tue Sep 03 18:05:11 2013 -0500
+++ b/hgext/largefiles/reposetup.py Tue Sep 03 18:08:27 2013 -0500
@@ -10,8 +10,7 @@
import copy
import os
-from mercurial import context, error, manifest, match as match_, util, \
- discovery
+from mercurial import error, manifest, match as match_, util, discovery
from mercurial import node as node_
from mercurial.i18n import _
from mercurial import localrepo
@@ -92,14 +91,8 @@
else:
# some calls in this function rely on the old version of status
self.lfstatus = False
- if isinstance(node1, context.changectx):
- ctx1 = node1
- else:
- ctx1 = self[node1]
- if isinstance(node2, context.changectx):
- ctx2 = node2
- else:
- ctx2 = self[node2]
+ ctx1 = self[node1]
+ ctx2 = self[node2]
working = ctx2.rev() is None
parentworking = working and ctx1 == self['.']
--- a/hgext/mq.py Tue Sep 03 18:05:11 2013 -0500
+++ b/hgext/mq.py Tue Sep 03 18:08:27 2013 -0500
@@ -66,6 +66,7 @@
from mercurial import repair, extensions, error, phases
from mercurial import patch as patchmod
from mercurial import localrepo
+from mercurial import subrepo
import os, re, errno, shutil
commands.norepo += " qclone"
@@ -800,6 +801,14 @@
p1, p2 = repo.dirstate.parents()
repo.setparents(p1, merge)
+ if all_files and '.hgsubstate' in all_files:
+ wctx = repo['.']
+ mctx = actx = repo[None]
+ overwrite = False
+ mergedsubstate = subrepo.submerge(repo, wctx, mctx, actx,
+ overwrite)
+ files += mergedsubstate.keys()
+
match = scmutil.matchfiles(repo, files or [])
oldtip = repo['tip']
n = newcommit(repo, None, message, ph.user, ph.date, match=match,
@@ -975,11 +984,20 @@
else:
raise util.Abort(_("local changes found"))
+ def localchangedsubreposfound(self, refresh=True):
+ if refresh:
+ raise util.Abort(_("local changed subrepos found, refresh first"))
+ else:
+ raise util.Abort(_("local changed subrepos found"))
+
def checklocalchanges(self, repo, force=False, refresh=True):
cmdutil.checkunfinished(repo)
m, a, r, d = repo.status()[:4]
- if (m or a or r or d) and not force:
- self.localchangesfound(refresh)
+ if not force:
+ if (m or a or r or d):
+ self.localchangesfound(refresh)
+ if self.checksubstate(repo):
+ self.localchangedsubreposfound(refresh)
return m, a, r, d
_reserved = ('series', 'status', 'guards', '.', '..')
@@ -1450,6 +1468,8 @@
self.ui.status(_("popping %s\n") % patch.name)
del self.applied[start:end]
self.strip(repo, [rev], update=False, backup='strip')
+ for s, state in repo['.'].substate.items():
+ repo['.'].sub(s).get(state)
if self.applied:
self.ui.write(_("now at: %s\n") % self.applied[-1].name)
else:
--- a/hgext/progress.py Tue Sep 03 18:05:11 2013 -0500
+++ b/hgext/progress.py Tue Sep 03 18:08:27 2013 -0500
@@ -239,6 +239,13 @@
# this one are also closed
if topic in self.topics:
self.topics = self.topics[:self.topics.index(topic)]
+ # reset the last topic to the one we just unwound to,
+ # so that higher-level topics will be stickier than
+ # lower-level topics
+ if self.topics:
+ self.lasttopic = self.topics[-1]
+ else:
+ self.lasttopic = None
else:
if topic not in self.topics:
self.starttimes[topic] = now
--- a/mercurial/bundlerepo.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/bundlerepo.py Tue Sep 03 18:08:27 2013 -0500
@@ -120,7 +120,7 @@
chain.append(iterrev)
iterrev = self.index[iterrev][3]
if text is None:
- text = revlog.revlog.revision(self, iterrev)
+ text = self.baserevision(iterrev)
while chain:
delta = self._chunk(chain.pop())
@@ -130,6 +130,12 @@
self._cache = (node, rev, text)
return text
+ def baserevision(self, nodeorrev):
+ # Revlog subclasses may override 'revision' method to modify format of
+ # content retrieved from revlog. To use bundlerevlog with such class one
+ # needs to override 'baserevision' and make more specific call here.
+ return revlog.revlog.revision(self, nodeorrev)
+
def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
raise NotImplementedError
def addgroup(self, revs, linkmapper, transaction):
@@ -146,12 +152,21 @@
bundlerevlog.__init__(self, opener, self.indexfile, bundle,
linkmapper)
+ def baserevision(self, nodeorrev):
+ # Although changelog doesn't override 'revision' method, some extensions
+ # may replace this class with another that does. Same story with
+ # manifest and filelog classes.
+ return changelog.changelog.revision(self, nodeorrev)
+
class bundlemanifest(bundlerevlog, manifest.manifest):
def __init__(self, opener, bundle, linkmapper):
manifest.manifest.__init__(self, opener)
bundlerevlog.__init__(self, opener, self.indexfile, bundle,
linkmapper)
+ def baserevision(self, nodeorrev):
+ return manifest.manifest.revision(self, nodeorrev)
+
class bundlefilelog(bundlerevlog, filelog.filelog):
def __init__(self, opener, path, bundle, linkmapper, repo):
filelog.filelog.__init__(self, opener, path)
@@ -159,6 +174,9 @@
linkmapper)
self._repo = repo
+ def baserevision(self, nodeorrev):
+ return filelog.filelog.revision(self, nodeorrev)
+
def _file(self, f):
self._repo.file(f)
--- a/mercurial/commands.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/commands.py Tue Sep 03 18:08:27 2013 -0500
@@ -1923,6 +1923,7 @@
util.writefile('.debugfsinfo', '')
ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
+ ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
and 'yes' or 'no'))
os.unlink('.debugfsinfo')
--- a/mercurial/context.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/context.py Tue Sep 03 18:08:27 2013 -0500
@@ -16,11 +16,150 @@
propertycache = util.propertycache
-class changectx(object):
+class basectx(object):
+ """A basectx object represents the common logic for its children:
+ changectx: read-only context that is already present in the repo,
+ workingctx: a context that represents the working directory and can
+ be committed,
+ memctx: a context that represents changes in-memory and can also
+ be committed."""
+ def __new__(cls, repo, changeid='', *args, **kwargs):
+ if isinstance(changeid, basectx):
+ return changeid
+
+ o = super(basectx, cls).__new__(cls)
+
+ o._repo = repo
+ o._rev = nullrev
+ o._node = nullid
+
+ return o
+
+ def __str__(self):
+ return short(self.node())
+
+ def __int__(self):
+ return self.rev()
+
+ def __repr__(self):
+ return "<%s %s>" % (type(self).__name__, str(self))
+
+ def __eq__(self, other):
+ try:
+ return type(self) == type(other) and self._rev == other._rev
+ except AttributeError:
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __contains__(self, key):
+ return key in self._manifest
+
+ def __getitem__(self, key):
+ return self.filectx(key)
+
+ def __iter__(self):
+ for f in sorted(self._manifest):
+ yield f
+
+ @propertycache
+ def substate(self):
+ return subrepo.state(self, self._repo.ui)
+
+ def rev(self):
+ return self._rev
+ def node(self):
+ return self._node
+ def hex(self):
+ return hex(self.node())
+ def manifest(self):
+ return self._manifest
+ def phasestr(self):
+ return phases.phasenames[self.phase()]
+ def mutable(self):
+ return self.phase() > phases.public
+
+ def parents(self):
+ """return contexts for each parent changeset"""
+ return self._parents
+
+ def p1(self):
+ return self._parents[0]
+
+ def p2(self):
+ if len(self._parents) == 2:
+ return self._parents[1]
+ return changectx(self._repo, -1)
+
+ def _fileinfo(self, path):
+ if '_manifest' in self.__dict__:
+ try:
+ return self._manifest[path], self._manifest.flags(path)
+ except KeyError:
+ raise error.ManifestLookupError(self._node, path,
+ _('not found in manifest'))
+ if '_manifestdelta' in self.__dict__ or path in self.files():
+ if path in self._manifestdelta:
+ return (self._manifestdelta[path],
+ self._manifestdelta.flags(path))
+ node, flag = self._repo.manifest.find(self._changeset[0], path)
+ if not node:
+ raise error.ManifestLookupError(self._node, path,
+ _('not found in manifest'))
+
+ return node, flag
+
+ def filenode(self, path):
+ return self._fileinfo(path)[0]
+
+ def flags(self, path):
+ try:
+ return self._fileinfo(path)[1]
+ except error.LookupError:
+ return ''
+
+ def sub(self, path):
+ return subrepo.subrepo(self, path)
+
+ def match(self, pats=[], include=None, exclude=None, default='glob'):
+ r = self._repo
+ return matchmod.match(r.root, r.getcwd(), pats,
+ include, exclude, default,
+ auditor=r.auditor, ctx=self)
+
+ def diff(self, ctx2=None, match=None, **opts):
+ """Returns a diff generator for the given contexts and matcher"""
+ if ctx2 is None:
+ ctx2 = self.p1()
+ if ctx2 is not None:
+ ctx2 = self._repo[ctx2]
+ diffopts = patch.diffopts(self._repo.ui, opts)
+ return patch.diff(self._repo, ctx2.node(), self.node(),
+ match=match, opts=diffopts)
+
+ @propertycache
+ def _dirs(self):
+ return scmutil.dirs(self._manifest)
+
+ def dirs(self):
+ return self._dirs
+
+ def dirty(self):
+ return False
+
+class changectx(basectx):
"""A changecontext object makes access to data related to a particular
- changeset convenient."""
+ changeset convenient. It represents a read-only context already presnt in
+ the repo."""
def __init__(self, repo, changeid=''):
"""changeid is a revision number, node, or tag"""
+
+ # since basectx.__new__ already took care of copying the object, we
+ # don't need to do anything in __init__, so we just exit here
+ if isinstance(changeid, basectx):
+ return
+
if changeid == '':
changeid = '.'
self._repo = repo
@@ -114,30 +253,12 @@
raise error.RepoLookupError(
_("unknown revision '%s'") % changeid)
- def __str__(self):
- return short(self.node())
-
- def __int__(self):
- return self.rev()
-
- def __repr__(self):
- return "<changectx %s>" % str(self)
-
def __hash__(self):
try:
return hash(self._rev)
except AttributeError:
return id(self)
- def __eq__(self, other):
- try:
- return self._rev == other._rev
- except AttributeError:
- return False
-
- def __ne__(self, other):
- return not (self == other)
-
def __nonzero__(self):
return self._rev != nullrev
@@ -160,33 +281,11 @@
p = p[:-1]
return [changectx(self._repo, x) for x in p]
- @propertycache
- def substate(self):
- return subrepo.state(self, self._repo.ui)
-
- def __contains__(self, key):
- return key in self._manifest
-
- def __getitem__(self, key):
- return self.filectx(key)
-
- def __iter__(self):
- for f in sorted(self._manifest):
- yield f
-
def changeset(self):
return self._changeset
- def manifest(self):
- return self._manifest
def manifestnode(self):
return self._changeset[0]
- def rev(self):
- return self._rev
- def node(self):
- return self._node
- def hex(self):
- return hex(self._node)
def user(self):
return self._changeset[1]
def date(self):
@@ -207,25 +306,9 @@
return self._repo.nodebookmarks(self._node)
def phase(self):
return self._repo._phasecache.phase(self._repo, self._rev)
- def phasestr(self):
- return phases.phasenames[self.phase()]
- def mutable(self):
- return self.phase() > phases.public
def hidden(self):
return self._rev in repoview.filterrevs(self._repo, 'visible')
- def parents(self):
- """return contexts for each parent changeset"""
- return self._parents
-
- def p1(self):
- return self._parents[0]
-
- def p2(self):
- if len(self._parents) == 2:
- return self._parents[1]
- return changectx(self._repo, -1)
-
def children(self):
"""return contexts for each child changeset"""
c = self._repo.changelog.children(self._node)
@@ -286,33 +369,6 @@
troubles.append('divergent')
return troubles
- def _fileinfo(self, path):
- if '_manifest' in self.__dict__:
- try:
- return self._manifest[path], self._manifest.flags(path)
- except KeyError:
- raise error.ManifestLookupError(self._node, path,
- _('not found in manifest'))
- if '_manifestdelta' in self.__dict__ or path in self.files():
- if path in self._manifestdelta:
- return (self._manifestdelta[path],
- self._manifestdelta.flags(path))
- node, flag = self._repo.manifest.find(self._changeset[0], path)
- if not node:
- raise error.ManifestLookupError(self._node, path,
- _('not found in manifest'))
-
- return node, flag
-
- def filenode(self, path):
- return self._fileinfo(path)[0]
-
- def flags(self, path):
- try:
- return self._fileinfo(path)[1]
- except error.LookupError:
- return ''
-
def filectx(self, path, fileid=None, filelog=None):
"""get a file context from this changeset"""
if fileid is None:
@@ -353,83 +409,15 @@
if match.bad(fn, _('no such file in rev %s') % self) and match(fn):
yield fn
- def sub(self, path):
- return subrepo.subrepo(self, path)
-
- def match(self, pats=[], include=None, exclude=None, default='glob'):
- r = self._repo
- return matchmod.match(r.root, r.getcwd(), pats,
- include, exclude, default,
- auditor=r.auditor, ctx=self)
-
- def diff(self, ctx2=None, match=None, **opts):
- """Returns a diff generator for the given contexts and matcher"""
- if ctx2 is None:
- ctx2 = self.p1()
- if ctx2 is not None and not isinstance(ctx2, changectx):
- ctx2 = self._repo[ctx2]
- diffopts = patch.diffopts(self._repo.ui, opts)
- return patch.diff(self._repo, ctx2.node(), self.node(),
- match=match, opts=diffopts)
-
- @propertycache
- def _dirs(self):
- return scmutil.dirs(self._manifest)
-
- def dirs(self):
- return self._dirs
-
- def dirty(self):
- return False
-
-class filectx(object):
- """A filecontext object makes access to data related to a particular
- filerevision convenient."""
- def __init__(self, repo, path, changeid=None, fileid=None,
- filelog=None, changectx=None):
- """changeid can be a changeset revision, node, or tag.
- fileid can be a file revision or node."""
- self._repo = repo
- self._path = path
-
- assert (changeid is not None
- or fileid is not None
- or changectx is not None), \
- ("bad args: changeid=%r, fileid=%r, changectx=%r"
- % (changeid, fileid, changectx))
-
- if filelog is not None:
- self._filelog = filelog
-
- if changeid is not None:
- self._changeid = changeid
- if changectx is not None:
- self._changectx = changectx
- if fileid is not None:
- self._fileid = fileid
-
- @propertycache
- def _changectx(self):
- try:
- return changectx(self._repo, self._changeid)
- except error.RepoLookupError:
- # Linkrev may point to any revision in the repository. When the
- # repository is filtered this may lead to `filectx` trying to build
- # `changectx` for filtered revision. In such case we fallback to
- # creating `changectx` on the unfiltered version of the reposition.
- # This fallback should not be an issue because `changectx` from
- # `filectx` are not used in complex operations that care about
- # filtering.
- #
- # This fallback is a cheap and dirty fix that prevent several
- # crashes. It does not ensure the behavior is correct. However the
- # behavior was not correct before filtering either and "incorrect
- # behavior" is seen as better as "crash"
- #
- # Linkrevs have several serious troubles with filtering that are
- # complicated to solve. Proper handling of the issue here should be
- # considered when solving linkrev issue are on the table.
- return changectx(self._repo.unfiltered(), self._changeid)
+class basefilectx(object):
+ """A filecontext object represents the common logic for its children:
+ filectx: read-only access to a filerevision that is already present
+ in the repo,
+ workingfilectx: a filecontext that represents files from the working
+ directory,
+ memfilectx: a filecontext that represents files in-memory."""
+ def __new__(cls, repo, path, *args, **kwargs):
+ return super(basefilectx, cls).__new__(cls)
@propertycache
def _filelog(self):
@@ -471,7 +459,7 @@
return "%s@%s" % (self.path(), short(self.node()))
def __repr__(self):
- return "<filectx %s>" % str(self)
+ return "<%s %s>" % (type(self).__name__, str(self))
def __hash__(self):
try:
@@ -481,7 +469,7 @@
def __eq__(self, other):
try:
- return (self._path == other._path
+ return (type(self) == type(other) and self._path == other._path
and self._filenode == other._filenode)
except AttributeError:
return False
@@ -489,12 +477,6 @@
def __ne__(self, other):
return not (self == other)
- def filectx(self, fileid):
- '''opens an arbitrary revision of the file without
- opening a new filelog'''
- return filectx(self._repo, self._path, fileid=fileid,
- filelog=self._filelog)
-
def filerev(self):
return self._filerev
def filenode(self):
@@ -510,7 +492,7 @@
def node(self):
return self._changectx.node()
def hex(self):
- return hex(self.node())
+ return self._changectx.hex()
def user(self):
return self._changectx.user()
def date(self):
@@ -532,12 +514,8 @@
def changectx(self):
return self._changectx
- def data(self):
- return self._filelog.read(self._filenode)
def path(self):
return self._path
- def size(self):
- return self._filelog.size(self._filerev)
def isbinary(self):
try:
@@ -560,31 +538,6 @@
return True
- def renamed(self):
- """check if file was actually renamed in this changeset revision
-
- If rename logged in file revision, we report copy for changeset only
- if file revisions linkrev points back to the changeset in question
- or both changeset parents contain different file revisions.
- """
-
- renamed = self._filelog.renamed(self._filenode)
- if not renamed:
- return renamed
-
- if self.rev() == self.linkrev():
- return renamed
-
- name = self.path()
- fnode = self._filenode
- for p in self._changectx.parents():
- try:
- if fnode == p.filenode(name):
- return None
- except error.LookupError:
- pass
- return renamed
-
def parents(self):
p = self._path
fl = self._filelog
@@ -606,12 +559,6 @@
return p[1]
return filectx(self._repo, self._path, fileid=-1, filelog=self._filelog)
- def children(self):
- # hard for renames
- c = self._filelog.children(self._filenode)
- return [filectx(self._repo, self._path, fileid=x,
- filelog=self._filelog) for x in c]
-
def annotate(self, follow=False, linenumber=None, diffopts=None):
'''returns a list of tuples of (ctx, line) for each line
in the file, where ctx is the filectx of the node where
@@ -783,7 +730,98 @@
self._copycache[sc2] = copies.pathcopies(c2)
return self._copycache[sc2]
-class workingctx(changectx):
+class filectx(basefilectx):
+ """A filecontext object makes access to data related to a particular
+ filerevision convenient."""
+ def __init__(self, repo, path, changeid=None, fileid=None,
+ filelog=None, changectx=None):
+ """changeid can be a changeset revision, node, or tag.
+ fileid can be a file revision or node."""
+ self._repo = repo
+ self._path = path
+
+ assert (changeid is not None
+ or fileid is not None
+ or changectx is not None), \
+ ("bad args: changeid=%r, fileid=%r, changectx=%r"
+ % (changeid, fileid, changectx))
+
+ if filelog is not None:
+ self._filelog = filelog
+
+ if changeid is not None:
+ self._changeid = changeid
+ if changectx is not None:
+ self._changectx = changectx
+ if fileid is not None:
+ self._fileid = fileid
+
+ @propertycache
+ def _changectx(self):
+ try:
+ return changectx(self._repo, self._changeid)
+ except error.RepoLookupError:
+ # Linkrev may point to any revision in the repository. When the
+ # repository is filtered this may lead to `filectx` trying to build
+ # `changectx` for filtered revision. In such case we fallback to
+ # creating `changectx` on the unfiltered version of the reposition.
+ # This fallback should not be an issue because `changectx` from
+ # `filectx` are not used in complex operations that care about
+ # filtering.
+ #
+ # This fallback is a cheap and dirty fix that prevent several
+ # crashes. It does not ensure the behavior is correct. However the
+ # behavior was not correct before filtering either and "incorrect
+ # behavior" is seen as better as "crash"
+ #
+ # Linkrevs have several serious troubles with filtering that are
+ # complicated to solve. Proper handling of the issue here should be
+ # considered when solving linkrev issue are on the table.
+ return changectx(self._repo.unfiltered(), self._changeid)
+
+ def filectx(self, fileid):
+ '''opens an arbitrary revision of the file without
+ opening a new filelog'''
+ return filectx(self._repo, self._path, fileid=fileid,
+ filelog=self._filelog)
+
+ def data(self):
+ return self._filelog.read(self._filenode)
+ def size(self):
+ return self._filelog.size(self._filerev)
+
+ def renamed(self):
+ """check if file was actually renamed in this changeset revision
+
+ If rename logged in file revision, we report copy for changeset only
+ if file revisions linkrev points back to the changeset in question
+ or both changeset parents contain different file revisions.
+ """
+
+ renamed = self._filelog.renamed(self._filenode)
+ if not renamed:
+ return renamed
+
+ if self.rev() == self.linkrev():
+ return renamed
+
+ name = self.path()
+ fnode = self._filenode
+ for p in self._changectx.parents():
+ try:
+ if fnode == p.filenode(name):
+ return None
+ except error.LookupError:
+ pass
+ return renamed
+
+ def children(self):
+ # hard for renames
+ c = self._filelog.children(self._filenode)
+ return [filectx(self._repo, self._path, fileid=x,
+ filelog=self._filelog) for x in c]
+
+class workingctx(basectx):
"""A workingctx object makes access to data related to
the current working directory convenient.
date - any valid date string or (unixtime, offset), or None.
@@ -1148,7 +1186,7 @@
def dirs(self):
return self._repo.dirstate.dirs()
-class workingfilectx(filectx):
+class workingfilectx(basefilectx):
"""A workingfilectx object makes access to data related to a particular
file in the working directory convenient."""
def __init__(self, repo, path, filelog=None, workingctx=None):
--- a/mercurial/dispatch.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/dispatch.py Tue Sep 03 18:08:27 2013 -0500
@@ -88,11 +88,47 @@
try:
try:
+ debugger = 'pdb'
+ debugtrace = {
+ 'pdb' : pdb.set_trace
+ }
+ debugmortem = {
+ 'pdb' : pdb.post_mortem
+ }
+
+ # read --config before doing anything else
+ # (e.g. to change trust settings for reading .hg/hgrc)
+ cfgs = _parseconfig(req.ui, _earlygetopt(['--config'], req.args))
+
+ if req.repo:
+ # copy configs that were passed on the cmdline (--config) to
+ # the repo ui
+ for cfg in cfgs:
+ req.repo.ui.setconfig(*cfg)
+
+ debugger = ui.config("ui", "debugger")
+ if not debugger:
+ debugger = 'pdb'
+
+ try:
+ debugmod = __import__(debugger)
+ except ImportError:
+ debugmod = pdb
+
+ debugtrace[debugger] = debugmod.set_trace
+ debugmortem[debugger] = debugmod.post_mortem
+
# enter the debugger before command execution
if '--debugger' in req.args:
ui.warn(_("entering debugger - "
"type c to continue starting hg or h for help\n"))
- pdb.set_trace()
+
+ if (debugger != 'pdb' and
+ debugtrace[debugger] == debugtrace['pdb']):
+ ui.warn(_("%s debugger specified "
+ "but its module was not found\n") % debugger)
+
+ debugtrace[debugger]()
try:
return _dispatch(req)
finally:
@@ -101,7 +137,7 @@
# enter the debugger when we hit an exception
if '--debugger' in req.args:
traceback.print_exc()
- pdb.post_mortem(sys.exc_info()[2])
+ debugmortem[debugger](sys.exc_info()[2])
ui.traceback()
raise
@@ -619,10 +655,6 @@
args = req.args
ui = req.ui
- # read --config before doing anything else
- # (e.g. to change trust settings for reading .hg/hgrc)
- cfgs = _parseconfig(ui, _earlygetopt(['--config'], args))
-
# check for cwd
cwd = _earlygetopt(['--cwd'], args)
if cwd:
@@ -699,10 +731,6 @@
if req.repo:
uis.add(req.repo.ui)
- # copy configs that were passed on the cmdline (--config) to the repo ui
- for cfg in cfgs:
- req.repo.ui.setconfig(*cfg)
-
if options['verbose'] or options['debug'] or options['quiet']:
for opt in ('verbose', 'debug', 'quiet'):
val = str(bool(options[opt]))
--- a/mercurial/hgweb/webcommands.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/hgweb/webcommands.py Tue Sep 03 18:08:27 2013 -0500
@@ -110,8 +110,10 @@
def _search(web, req, tmpl):
- def changelist(**map):
- count = 0
+ def revsearch(ctx):
+ yield ctx
+
+ def keywordsearch(query):
lower = encoding.lower
qw = lower(query).split()
@@ -137,6 +139,25 @@
if miss:
continue
+ yield ctx
+
+ searchfuncs = {
+ 'rev': revsearch,
+ 'keyword': keywordsearch,
+ }
+
+ def getsearchmode(query):
+ try:
+ ctx = web.repo[query]
+ except (error.RepoError, error.LookupError):
+ return 'keyword', query
+ else:
+ return 'rev', ctx
+
+ def changelist(**map):
+ count = 0
+
+ for ctx in searchfunc(funcarg):
count += 1
n = ctx.node()
showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
@@ -176,6 +197,9 @@
morevars['revcount'] = revcount * 2
morevars['rev'] = query
+ mode, funcarg = getsearchmode(query)
+ searchfunc = searchfuncs[mode]
+
tip = web.repo['tip']
parity = paritygen(web.stripecount)
@@ -188,16 +212,10 @@
query = ''
if 'node' in req.form:
ctx = webutil.changectx(web.repo, req)
+ elif 'rev' in req.form:
+ return _search(web, req, tmpl)
else:
- if 'rev' in req.form:
- query = req.form['rev'][0]
- hi = query
- else:
- hi = 'tip'
- try:
- ctx = web.repo[hi]
- except (error.RepoError, error.LookupError):
- return _search(web, req, tmpl) # XXX redirect to 404 page?
+ ctx = web.repo['tip']
def changelist(latestonly, **map):
revs = []
--- a/mercurial/httpclient/__init__.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/httpclient/__init__.py Tue Sep 03 18:08:27 2013 -0500
@@ -495,6 +495,10 @@
else:
raise BadRequestData('body has no __len__() nor read()')
+ # If we're reusing the underlying socket, there are some
+ # conditions where we'll want to retry, so make a note of the
+ # state of self.sock
+ fresh_socket = self.sock is None
self._connect()
outgoing_headers = self._buildheaders(
method, path, hdrs, self.http_version)
@@ -640,6 +644,26 @@
# the whole request
if response is None:
response = self.response_class(self.sock, self.timeout, method)
+ if not fresh_socket:
+ if not response._select():
+ # This means the response failed to get any response
+ # data at all, and in all probability the socket was
+ # closed before the server even saw our request. Try
+ # the request again on a fresh socket.
+ logging.debug('response._select() failed during request().'
+ ' Assuming request needs to be retried.')
+ self.sock = None
+ # Call this method explicitly to re-try the
+ # request. We don't use self.request() because
+ # some tools (notably Mercurial) expect to be able
+ # to subclass and redefine request(), and they
+ # don't have the same argspec as we do.
+ #
+ # TODO restructure sending of requests to avoid
+ # this recursion
+ return HTTPConnection.request(
+ self, method, path, body=body, headers=headers,
+ expect_continue=expect_continue)
data_left = bool(outgoing_headers or body)
if data_left:
logger.info('stopped sending request early, '
--- a/mercurial/localrepo.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/localrepo.py Tue Sep 03 18:08:27 2013 -0500
@@ -39,6 +39,8 @@
"""propertycache that apply to unfiltered repo only"""
def __get__(self, repo, type=None):
+ if hasunfilteredcache(repo, self.name):
+ return getattr(repo.unfiltered(), self.name)
return super(unfilteredpropertycache, self).__get__(repo.unfiltered())
class filteredpropertycache(propertycache):
@@ -1457,14 +1459,8 @@
del mf[fn]
return mf
- if isinstance(node1, context.changectx):
- ctx1 = node1
- else:
- ctx1 = self[node1]
- if isinstance(node2, context.changectx):
- ctx2 = node2
- else:
- ctx2 = self[node2]
+ ctx1 = self[node1]
+ ctx2 = self[node2]
working = ctx2.rev() is None
parentworking = working and ctx1 == self['.']
--- a/mercurial/obsolete.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/obsolete.py Tue Sep 03 18:08:27 2013 -0500
@@ -371,7 +371,7 @@
lock.release()
def syncpush(repo, remote):
- """utility function to push bookmark to a remote
+ """utility function to push obsolete markers to a remote
Exist mostly to allow overridding for experimentation purpose"""
if (_enabled and repo.obsstore and
@@ -387,7 +387,7 @@
repo.ui.warn(msg)
def syncpull(repo, remote, gettransaction):
- """utility function to pull bookmark to a remote
+ """utility function to pull obsolete markers from a remote
The `gettransaction` is function that return the pull transaction, creating
one if necessary. We return the transaction to inform the calling code that
--- a/mercurial/revlog.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/revlog.py Tue Sep 03 18:08:27 2013 -0500
@@ -14,7 +14,7 @@
# import stuff from node for others to import from revlog
from node import bin, hex, nullid, nullrev
from i18n import _
-import ancestor, mdiff, parsers, error, util
+import ancestor, mdiff, parsers, error, util, templatefilters
import struct, zlib, errno
_pack = struct.pack
@@ -943,10 +943,16 @@
def _checkhash(self, text, node, rev):
p1, p2 = self.parents(node)
+ self.checkhash(text, p1, p2, node, rev)
+ return text
+
+ def checkhash(self, text, p1, p2, node, rev=None):
if node != hash(text, p1, p2):
- raise RevlogError(_("integrity check failed on %s:%d")
- % (self.indexfile, rev))
- return text
+ revornode = rev
+ if revornode is None:
+ revornode = templatefilters.short(hex(node))
+ raise RevlogError(_("integrity check failed on %s:%s")
+ % (self.indexfile, revornode))
def checkinlinesize(self, tr, fp=None):
if not self._inline or (self.start(-2) + self.length(-2)) < _maxinline:
@@ -987,7 +993,8 @@
tr.replace(self.indexfile, trindex * self._io.size)
self._chunkclear()
- def addrevision(self, text, transaction, link, p1, p2, cachedelta=None):
+ def addrevision(self, text, transaction, link, p1, p2, cachedelta=None,
+ node=None):
"""add a revision to the log
text - the revision data to add
@@ -995,11 +1002,14 @@
link - the linkrev data to add
p1, p2 - the parent nodeids of the revision
cachedelta - an optional precomputed delta
+ node - nodeid of revision; typically node is not specified, and it is
+ computed by default as hash(text, p1, p2), however subclasses might
+ use different hashing method (and override checkhash() in such case)
"""
if link == nullrev:
raise RevlogError(_("attempted to add linkrev -1 to %s")
% self.indexfile)
- node = hash(text, p1, p2)
+ node = node or hash(text, p1, p2)
if node in self.nodemap:
return node
@@ -1063,9 +1073,7 @@
ifh.flush()
basetext = self.revision(self.node(cachedelta[0]))
btext[0] = mdiff.patch(basetext, cachedelta[1])
- chk = hash(btext[0], p1, p2)
- if chk != node:
- raise RevlogError(_("consistency error in delta"))
+ self.checkhash(btext[0], p1, p2, node)
return btext[0]
def builddelta(rev):
--- a/mercurial/subrepo.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/subrepo.py Tue Sep 03 18:08:27 2013 -0500
@@ -237,6 +237,7 @@
# record merged .hgsubstate
writestate(repo, sm)
+ return sm
def _updateprompt(ui, sub, dirty, local, remote):
if dirty:
--- a/mercurial/templates/paper/fileannotate.tmpl Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/templates/paper/fileannotate.tmpl Tue Sep 03 18:08:27 2013 -0500
@@ -65,7 +65,6 @@
<th class="author">children</th>
<td class="author">{child%filerevchild}</td>
</tr>
-{changesettag}
</table>
<div class="overflow">
--- a/mercurial/templates/paper/filecomparison.tmpl Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/templates/paper/filecomparison.tmpl Tue Sep 03 18:08:27 2013 -0500
@@ -64,7 +64,6 @@
<th>children</th>
<td>{child%filerevchild}</td>
</tr>
-{changesettag}
</table>
<div class="overflow">
--- a/mercurial/templates/paper/filediff.tmpl Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/templates/paper/filediff.tmpl Tue Sep 03 18:08:27 2013 -0500
@@ -64,7 +64,6 @@
<th>children</th>
<td>{child%filerevchild}</td>
</tr>
-{changesettag}
</table>
<div class="overflow">
--- a/mercurial/templates/paper/filerevision.tmpl Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/templates/paper/filerevision.tmpl Tue Sep 03 18:08:27 2013 -0500
@@ -63,7 +63,6 @@
<th class="author">children</th>
<td class="author">{child%filerevchild}</td>
</tr>
-{changesettag}
</table>
<div class="overflow">
--- a/mercurial/templates/paper/shortlogentry.tmpl Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/templates/paper/shortlogentry.tmpl Tue Sep 03 18:08:27 2013 -0500
@@ -1,5 +1,5 @@
<tr>
<td class="age">{date|rfc822date}</td>
<td class="author">{author|person}</td>
- <td class="description"><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags % '<span class="tag">{name|escape}</span> '}{bookmarks % '<span class="tag">{name|escape}</span> '}</td>
+ <td class="description"><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags%changelogtag}{bookmarks%changelogtag}</td>
</tr>
--- a/mercurial/templates/static/mercurial.js Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/templates/static/mercurial.js Tue Sep 03 18:08:27 2013 -0500
@@ -23,7 +23,7 @@
];
function Graph() {
-
+
this.canvas = document.getElementById('graph');
if (window.G_vmlCanvasManager) this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);
this.ctx = this.canvas.getContext('2d');
@@ -35,13 +35,13 @@
this.cell = [2, 0];
this.columns = 0;
this.revlink = '';
-
+
this.scale = function(height) {
this.bg_height = height;
this.box_size = Math.floor(this.bg_height / 1.2);
this.cell_height = this.box_size;
}
-
+
function colorPart(num) {
num *= 255
num = num < 0 ? 0 : num;
@@ -55,7 +55,7 @@
}
this.setColor = function(color, bg, fg) {
-
+
// Set the colour.
//
// If color is a string, expect an hexadecimal RGB
@@ -81,11 +81,11 @@
this.ctx.strokeStyle = s;
this.ctx.fillStyle = s;
return s;
-
+
}
this.edge = function(x0, y0, x1, y1, color, width) {
-
+
this.setColor(color, 0.0, 0.65);
if(width >= 0)
this.ctx.lineWidth = width;
@@ -93,28 +93,28 @@
this.ctx.moveTo(x0, y0);
this.ctx.lineTo(x1, y1);
this.ctx.stroke();
-
+
}
this.render = function(data) {
-
+
var backgrounds = '';
var nodedata = '';
-
+
for (var i in data) {
-
+
var parity = i % 2;
this.cell[1] += this.bg_height;
this.bg[1] += this.bg_height;
-
+
var cur = data[i];
var node = cur[1];
var edges = cur[2];
var fold = false;
-
+
var prevWidth = this.ctx.lineWidth;
for (var j in edges) {
-
+
line = edges[j];
start = line[0];
end = line[1];
@@ -125,44 +125,44 @@
var branchcolor = line[4];
if(branchcolor)
color = branchcolor;
-
+
if (end > this.columns || start > this.columns) {
this.columns += 1;
}
-
+
if (start == this.columns && start > end) {
var fold = true;
}
-
+
x0 = this.cell[0] + this.box_size * start + this.box_size / 2;
y0 = this.bg[1] - this.bg_height / 2;
x1 = this.cell[0] + this.box_size * end + this.box_size / 2;
y1 = this.bg[1] + this.bg_height / 2;
-
+
this.edge(x0, y0, x1, y1, color, width);
-
+
}
this.ctx.lineWidth = prevWidth;
-
+
// Draw the revision node in the right column
-
+
column = node[0]
color = node[1]
-
+
radius = this.box_size / 8;
x = this.cell[0] + this.box_size * column + this.box_size / 2;
y = this.bg[1] - this.bg_height / 2;
var add = this.vertex(x, y, color, parity, cur);
backgrounds += add[0];
nodedata += add[1];
-
+
if (fold) this.columns -= 1;
-
+
}
-
+
document.getElementById('nodebgs').innerHTML += backgrounds;
document.getElementById('graphnodes').innerHTML += nodedata;
-
+
}
}
@@ -258,6 +258,7 @@
// We want both: date + (age)
node.textContent += ' ('+agevalue+')';
} else {
+ node.title = node.textContent;
node.textContent = agevalue;
}
}
--- a/mercurial/ui.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/ui.py Tue Sep 03 18:08:27 2013 -0500
@@ -176,7 +176,7 @@
alternates = [name]
for n in alternates:
- value = self._data(untrusted).get(section, name, None)
+ value = self._data(untrusted).get(section, n, None)
if value is not None:
name = n
break
@@ -184,10 +184,11 @@
value = default
if self.debugflag and not untrusted and self._reportuntrusted:
- uvalue = self._ucfg.get(section, name)
- if uvalue is not None and uvalue != value:
- self.debug("ignoring untrusted configuration option "
- "%s.%s = %s\n" % (section, name, uvalue))
+ for n in alternates:
+ uvalue = self._ucfg.get(section, n)
+ if uvalue is not None and uvalue != value:
+ self.debug("ignoring untrusted configuration option "
+ "%s.%s = %s\n" % (section, n, uvalue))
return value
def configpath(self, section, name, default=None, untrusted=False):
--- a/mercurial/unionrepo.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/unionrepo.py Tue Sep 03 18:08:27 2013 -0500
@@ -70,7 +70,7 @@
self.revlog2.rev(self.node(rev1)),
self.revlog2.rev(self.node(rev2)))
elif rev1 <= self.repotiprev and rev2 <= self.repotiprev:
- return revlog.revlog.revdiff(self, rev1, rev2)
+ return self.baserevdiff(rev1, rev2)
return mdiff.textdiff(self.revision(self.node(rev1)),
self.revision(self.node(rev2)))
@@ -93,10 +93,20 @@
text = self.revlog2.revision(node)
self._cache = (node, rev, text)
else:
- text = revlog.revlog.revision(self, rev)
+ text = self.baserevision(rev)
# already cached
return text
+ def baserevision(self, nodeorrev):
+ # Revlog subclasses may override 'revision' method to modify format of
+ # content retrieved from revlog. To use unionrevlog with such class one
+ # needs to override 'baserevision' and make more specific call here.
+ return revlog.revlog.revision(self, nodeorrev)
+
+ def baserevdiff(self, rev1, rev2):
+ # Exists for the same purpose as baserevision.
+ return revlog.revlog.revdiff(self, rev1, rev2)
+
def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
raise NotImplementedError
def addgroup(self, revs, linkmapper, transaction):
@@ -114,6 +124,15 @@
unionrevlog.__init__(self, opener, self.indexfile, changelog2,
linkmapper)
+ def baserevision(self, nodeorrev):
+ # Although changelog doesn't override 'revision' method, some extensions
+ # may replace this class with another that does. Same story with
+ # manifest and filelog classes.
+ return changelog.changelog.revision(self, nodeorrev)
+
+ def baserevdiff(self, rev1, rev2):
+ return changelog.changelog.revdiff(self, rev1, rev2)
+
class unionmanifest(unionrevlog, manifest.manifest):
def __init__(self, opener, opener2, linkmapper):
manifest.manifest.__init__(self, opener)
@@ -121,6 +140,12 @@
unionrevlog.__init__(self, opener, self.indexfile, manifest2,
linkmapper)
+ def baserevision(self, nodeorrev):
+ return manifest.manifest.revision(self, nodeorrev)
+
+ def baserevdiff(self, rev1, rev2):
+ return manifest.manifest.revdiff(self, rev1, rev2)
+
class unionfilelog(unionrevlog, filelog.filelog):
def __init__(self, opener, path, opener2, linkmapper, repo):
filelog.filelog.__init__(self, opener, path)
@@ -129,6 +154,12 @@
linkmapper)
self._repo = repo
+ def baserevision(self, nodeorrev):
+ return filelog.filelog.revision(self, nodeorrev)
+
+ def baserevdiff(self, rev1, rev2):
+ return filelog.filelog.revdiff(self, rev1, rev2)
+
def _file(self, f):
self._repo.file(f)
--- a/mercurial/url.py Tue Sep 03 18:05:11 2013 -0500
+++ b/mercurial/url.py Tue Sep 03 18:08:27 2013 -0500
@@ -108,8 +108,13 @@
def proxy_open(self, req, proxy, type_):
host = req.get_host().split(':')[0]
- if host in self.no_list:
- return None
+ for e in self.no_list:
+ if host == e:
+ return None
+ if e.startswith('*.') and host.endswith(e[2:]):
+ return None
+ if e.startswith('.') and host.endswith(e[1:]):
+ return None
# work around a bug in Python < 2.4.2
# (it leaves a "\n" at the end of Proxy-authorization headers)
--- a/tests/run-tests.py Tue Sep 03 18:05:11 2013 -0500
+++ b/tests/run-tests.py Tue Sep 03 18:08:27 2013 -0500
@@ -921,8 +921,10 @@
else:
return ignore("doesn't match keyword")
+ if not lctest.startswith("test-"):
+ return skip("not a test file")
for ext, func, out in testtypes:
- if lctest.startswith("test-") and lctest.endswith(ext):
+ if lctest.endswith(ext):
runner = func
ref = os.path.join(TESTDIR, test + out)
break
--- a/tests/test-hgweb-commands.t Tue Sep 03 18:05:11 2013 -0500
+++ b/tests/test-hgweb-commands.t Tue Sep 03 18:08:27 2013 -0500
@@ -537,6 +537,8 @@
</body>
</html>
+ $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'log?rev=stable&style=raw' | grep 'revision:'
+ revision: 2
File-related
@@ -637,7 +639,6 @@
<th class="author">children</th>
<td class="author"><a href="/file/1d22e65f027e/foo">1d22e65f027e</a> </td>
</tr>
-
</table>
<div class="overflow">
@@ -1256,8 +1257,10 @@
Graph json escape of multibyte character
- $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'graph/' \
- > | grep -a '^var data ='
+ $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'graph/' > out
+ >>> for line in open("out"):
+ ... if line.startswith("var data ="):
+ ... print line,
var data = [["061dd13ba3c3", [0, 1], [[0, 0, 1, -1, ""]], "\\u80fd", "test", "1970-01-01", ["unstable", true], ["tip"], ["something"]], ["cad8025a2e87", [0, 1], [[0, 0, 1, 3, "FF0000"]], "branch commit with null character: \x00", "test", "1970-01-01", ["unstable", false], [], []], ["1d22e65f027e", [0, 1], [[0, 0, 1, 3, ""]], "branch", "test", "1970-01-01", ["stable", true], [], []], ["a4f92ed23982", [0, 1], [[0, 0, 1, 3, ""]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], ["anotherthing"]]]; (esc)
capabilities
--- a/tests/test-hgweb-diffs.t Tue Sep 03 18:05:11 2013 -0500
+++ b/tests/test-hgweb-diffs.t Tue Sep 03 18:08:27 2013 -0500
@@ -269,7 +269,6 @@
<th>children</th>
<td></td>
</tr>
-
</table>
<div class="overflow">
@@ -538,7 +537,6 @@
<th>children</th>
<td></td>
</tr>
-
</table>
<div class="overflow">
@@ -638,7 +636,6 @@
<th>children</th>
<td></td>
</tr>
-
</table>
<div class="overflow">
@@ -760,7 +757,6 @@
<th>children</th>
<td></td>
</tr>
-
</table>
<div class="overflow">
@@ -884,7 +880,6 @@
<th>children</th>
<td></td>
</tr>
-
</table>
<div class="overflow">
--- a/tests/test-hgweb-removed.t Tue Sep 03 18:05:11 2013 -0500
+++ b/tests/test-hgweb-removed.t Tue Sep 03 18:08:27 2013 -0500
@@ -213,7 +213,6 @@
<th>children</th>
<td></td>
</tr>
-
</table>
<div class="overflow">
--- a/tests/test-highlight.t Tue Sep 03 18:05:11 2013 -0500
+++ b/tests/test-highlight.t Tue Sep 03 18:08:27 2013 -0500
@@ -132,7 +132,6 @@
<th class="author">children</th>
<td class="author"></td>
</tr>
-
</table>
<div class="overflow">
@@ -264,7 +263,6 @@
<th class="author">children</th>
<td class="author"></td>
</tr>
-
</table>
<div class="overflow">
--- a/tests/test-import-merge.t Tue Sep 03 18:05:11 2013 -0500
+++ b/tests/test-import-merge.t Tue Sep 03 18:08:27 2013 -0500
@@ -129,7 +129,9 @@
$ echo a>>a
$ hg ci -m3
$ hg export 2 | head -7 > ../a.patch
- $ hg export tip | tail -n +8 >> ../a.patch
+ $ hg export tip > out
+ >>> apatch = open("../a.patch", "a")
+ >>> apatch.write("".join(open("out").readlines()[7:]))
$ cd ..
$ hg clone -qr0 repo3 repo3-clone
--- a/tests/test-mq-subrepo.t Tue Sep 03 18:05:11 2013 -0500
+++ b/tests/test-mq-subrepo.t Tue Sep 03 18:08:27 2013 -0500
@@ -213,6 +213,7 @@
handle subrepos safely on qpush/qpop
+(and we cannot qpop / qpush with a modified subrepo)
$ mkrepo repo-2499-qpush
$ mksubrepo sub
@@ -220,31 +221,56 @@
$ hg -R sub ci -m0sub
$ echo sub = sub > .hgsub
$ hg add .hgsub
- $ hg qnew -m0 0.diff
+ $ hg commit -m0
$ hg debugsub
path sub
source sub
revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
+ $ echo foo > ./sub/a
+ $ hg -R sub commit -m foo
+ $ hg commit -m1
+ $ hg qimport -r "0:tip"
+ $ hg -R sub id --id
+ aa037b301eba
qpop
+ $ hg -R sub update 0000
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg qpop
- popping 0.diff
- patch queue now empty
- $ hg status -AS
- $ hg debugsub
-
-qpush
- $ hg qpush
- applying 0.diff
+ abort: local changed subrepos found, refresh first
+ [255]
+ $ hg revert sub
+ reverting subrepo sub
+ adding sub/a
+ $ hg qpop
+ popping 1.diff
now at: 0.diff
$ hg status -AS
C .hgsub
C .hgsubstate
C sub/a
- $ hg debugsub
- path sub
- source sub
- revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
+ $ hg -R sub id --id
+ b2fdb12cd82b
+
+qpush
+ $ hg -R sub update 0000
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ hg qpush
+ abort: local changed subrepos found, refresh first
+ [255]
+ $ hg revert sub
+ reverting subrepo sub
+ adding sub/a
+ $ hg qpush
+ applying 1.diff
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ now at: 1.diff
+ $ hg status -AS
+ C .hgsub
+ C .hgsubstate
+ C sub/a
+ $ hg -R sub id --id
+ aa037b301eba
$ cd ..
--- a/tests/test-parse-date.t Tue Sep 03 18:05:11 2013 -0500
+++ b/tests/test-parse-date.t Tue Sep 03 18:08:27 2013 -0500
@@ -242,7 +242,7 @@
>>> yesterday = (datetime.date.today() - datetime.timedelta(days=1)).strftime("%b %d")
>>> dates = open('dates', 'w')
>>> dates.write(today + '\n')
- >>> dates.write(yesterday)
+ >>> dates.write(yesterday + '\n')
>>> dates.close()
$ hg ci -d "`sed -n '1p' dates`" -m "today is a good day to code"
$ hg log -d today --template '{desc}\n'
--- a/tests/test-progress.t Tue Sep 03 18:05:11 2013 -0500
+++ b/tests/test-progress.t Tue Sep 03 18:08:27 2013 -0500
@@ -1,6 +1,14 @@
$ cat > loop.py <<EOF
> from mercurial import commands
+ > import time
+ > class incrementingtime(object):
+ > def __init__(self):
+ > self._time = 0.0
+ > def __call__(self):
+ > self._time += 0.25
+ > return self._time
+ > time.time = incrementingtime()
>
> def loop(ui, loops, **opts):
> loops = int(loops)
@@ -19,9 +27,14 @@
> if opts.get('parallel'):
> ui.progress('other', i, 'other.%d' % i, 'othernum', total)
> if nested:
- > for j in range(2):
- > ui.progress('nested', j, 'nested.%d' % j, 'nestnum', 2)
- > ui.progress('nested', None, 'nested.done', 'nestnum', 2)
+ > nested_steps = 2
+ > if i and i % 4 == 0:
+ > nested_steps = 5
+ > for j in range(nested_steps):
+ > ui.progress(
+ > 'nested', j, 'nested.%d' % j, 'nestnum', nested_steps)
+ > ui.progress(
+ > 'nested', None, 'nested.done', 'nestnum', nested_steps)
> ui.progress('loop', None, 'loop.done', 'loopnum', total)
>
> commands.norepo += " loop"
@@ -69,6 +82,24 @@
loop [===============================> ] 2/3\r (no-eol) (esc)
\r (no-eol) (esc)
+Test nested long-lived topic which has the same name as a short-lived
+peer. We shouldn't get stuck showing the short-lived inner steps, and
+should go back to skipping the inner steps when the slow nested step
+finishes.
+
+ $ hg -y loop 7 --nested
+ \r (no-eol) (esc)
+ loop [ ] 0/7\r (no-eol) (esc)
+ loop [=====> ] 1/7\r (no-eol) (esc)
+ loop [============> ] 2/7\r (no-eol) (esc)
+ loop [===================> ] 3/7\r (no-eol) (esc)
+ loop [==========================> ] 4/7\r (no-eol) (esc)
+ nested [==========================> ] 3/5\r (no-eol) (esc)
+ nested [===================================> ] 4/5\r (no-eol) (esc)
+ loop [=================================> ] 5/7\r (no-eol) (esc)
+ loop [========================================> ] 6/7\r (no-eol) (esc)
+ \r (no-eol) (esc)
+
$ hg --config progress.changedelay=0 -y loop 3 --nested
\r (no-eol) (esc)