changeset 3353:69fe021cc23e

Merge with crew
author Matt Mackall <mpm@selenic.com>
date Wed, 11 Oct 2006 17:37:48 -0500
parents 04fa31a43b93 (diff) be8efb6e1cc6 (current diff)
children 6152c00245e5
files mercurial/context.py
diffstat 21 files changed, 363 insertions(+), 145 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/extdiff.py
+++ b/hgext/extdiff.py
@@ -65,6 +65,9 @@ def dodiff(ui, repo, diffcmd, diffopts, 
             ui.write_err(_('making snapshot of %d files from rev %s\n') %
                          (len(files), short(node)))
         for fn in files:
+            if not fn in mf:
+                # skipping new file after a merge ?
+                continue
             wfn = util.pconvert(fn)
             ui.note('  %s\n' % wfn)
             dest = os.path.join(base, wfn)
--- a/mercurial/base85.c
+++ b/mercurial/base85.c
@@ -35,7 +35,7 @@ b85encode(PyObject *self, PyObject *args
 	unsigned int acc, val, ch;
         int pad = 0;
 
-	if (!PyArg_ParseTuple(args, "s#|i", &text, &len, &pad))
+	if (!PyArg_ParseTuple(args, "t#|i", &text, &len, &pad))
 		return NULL;
 
         if (pad)
@@ -82,7 +82,7 @@ b85decode(PyObject *self, PyObject *args
 	int len, i, j, olen, c, cap;
 	unsigned int acc;
 
-	if (!PyArg_ParseTuple(args, "s#", &text, &len))
+	if (!PyArg_ParseTuple(args, "t#", &text, &len))
 		return NULL;
 
 	olen = len / 5 * 4;
--- a/mercurial/bdiff.c
+++ b/mercurial/bdiff.c
@@ -300,18 +300,19 @@ nomem:
 
 static PyObject *bdiff(PyObject *self, PyObject *args)
 {
-	PyObject *sa, *sb, *result = NULL;
+	char *sa, *sb;
+	PyObject *result = NULL;
 	struct line *al, *bl;
 	struct hunklist l = {NULL, NULL};
 	struct hunk *h;
 	char encode[12], *rb;
-	int an, bn, len = 0, la = 0, lb = 0;
+	int an, bn, len = 0, la, lb;
 
-	if (!PyArg_ParseTuple(args, "SS:bdiff", &sa, &sb))
+	if (!PyArg_ParseTuple(args, "t#t#:bdiff", &sa, &la, &sb, &lb))
 		return NULL;
 
-	an = splitlines(PyString_AsString(sa), PyString_Size(sa), &al);
-	bn = splitlines(PyString_AsString(sb), PyString_Size(sb), &bl);
+	an = splitlines(sa, la, &al);
+	bn = splitlines(sb, lb, &bl);
 	if (!al || !bl)
 		goto nomem;
 
@@ -320,6 +321,7 @@ static PyObject *bdiff(PyObject *self, P
 		goto nomem;
 
 	/* calculate length of output */
+	la = lb = 0;
 	for (h = l.base; h != l.head; h++) {
 		if (h->a1 != la || h->b1 != lb)
 			len += 12 + bl[h->b1].l - bl[lb].l;
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2463,7 +2463,7 @@ def serve(ui, repo, **opts):
                " accesslog errorlog webdir_conf")
     for o in optlist.split():
         if opts[o]:
-            ui.setconfig("web", o, opts[o])
+            ui.setconfig("web", o, str(opts[o]))
 
     if repo is None and not ui.config("web", "webdir_conf"):
         raise hg.RepoError(_("There is no Mercurial repository here"
@@ -3275,6 +3275,20 @@ def load_extensions(ui):
                 ui.warn(_("module %s overrides %s\n") % (name, t))
         table.update(cmdtable)
 
+def parseconfig(config):
+    """parse the --config options from the command line"""
+    parsed = []
+    for cfg in config:
+        try:
+            name, value = cfg.split('=', 1)
+            section, name = name.split('.', 1)
+            if not section or not name:
+                raise IndexError
+            parsed.append((section, name, value))
+        except (IndexError, ValueError):
+            raise util.Abort(_('malformed --config option: %s') % cfg)
+    return parsed
+
 def dispatch(args):
     for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
         num = getattr(signal, name, None)
@@ -3304,10 +3318,6 @@ def dispatch(args):
                     (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
             atexit.register(print_time)
 
-        u.updateopts(options["verbose"], options["debug"], options["quiet"],
-                     not options["noninteractive"], options["traceback"],
-                     options["config"])
-
         # enter the debugger before command execution
         if options['debugger']:
             pdb.set_trace()
@@ -3320,6 +3330,10 @@ def dispatch(args):
                     raise util.Abort('%s: %s' %
                                      (options['cwd'], inst.strerror))
 
+            u.updateopts(options["verbose"], options["debug"], options["quiet"],
+                         not options["noninteractive"], options["traceback"],
+                         parseconfig(options["config"]))
+
             path = u.expandpath(options["repository"]) or ""
             repo = path and hg.repository(u, path=path) or None
             if repo and not repo.local():
@@ -3349,11 +3363,6 @@ def dispatch(args):
             else:
                 d = lambda: func(u, *args, **cmdoptions)
 
-            # reupdate the options, repo/.hg/hgrc may have changed them
-            u.updateopts(options["verbose"], options["debug"], options["quiet"],
-                         not options["noninteractive"], options["traceback"],
-                         options["config"])
-
             try:
                 if options['profile']:
                     import hotshot, hotshot.stats
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -48,6 +48,10 @@ class changectx(object):
         elif name == '_manifest':
             self._manifest = self._repo.manifest.read(self._changeset[0])
             return self._manifest
+        elif name == '_manifestdelta':
+            md = self._repo.manifest.readdelta(self._changeset[0])
+            self._manifestdelta = md
+            return self._manifestdelta
         else:
             raise AttributeError, name
 
@@ -72,11 +76,14 @@ class changectx(object):
         return [ changectx(self._repo, x) for x in c ]
 
     def filenode(self, path):
-        if hasattr(self, "_manifest"):
+        if '_manifest' in self.__dict__:
             try:
                 return self._manifest[path]
             except KeyError:
                 raise repo.LookupError(_("'%s' not found in manifest") % path)
+        if '_manifestdelta' in self.__dict__ or path in self.files():
+            if path in self._manifestdelta:
+                return self._manifestdelta[path]
         node, flag = self._repo.manifest.find(self._changeset[0], path)
         if not node:
             raise repo.LookupError(_("'%s' not found in manifest") % path)
@@ -140,7 +147,7 @@ class filectx(object):
             return self._changeid
         elif name == '_filenode':
             try:
-                if hasattr(self, "_fileid"):
+                if '_fileid' in self.__dict__:
                     self._filenode = self._filelog.lookup(self._fileid)
                 else:
                     self._filenode = self._changectx.filenode(self._path)
@@ -176,7 +183,7 @@ class filectx(object):
     def filelog(self): return self._filelog
 
     def rev(self):
-        if hasattr(self, "_changectx"):
+        if '_changectx' in self.__dict__:
             return self._changectx.rev()
         return self._filelog.linkrev(self._filenode)
 
@@ -440,7 +447,7 @@ class workingfilectx(filectx):
                        filelog=self._filelog)
 
     def rev(self):
-        if hasattr(self, "_changectx"):
+        if '_changectx' in self.__dict__:
             return self._changectx.rev()
         return self._filelog.linkrev(self._filenode)
 
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -647,38 +647,31 @@ class hgweb(object):
                 def firstitem(query):
                     return query.split('&', 1)[0].split(';', 1)[0]
 
-                root = req.env.get('REQUEST_URI', '').split('?', 1)[0]
-                pi = req.env.get('PATH_INFO', '')
-                if pi:
-                    root = root[:-len(pi)]
-                
-                if req.env.has_key('REPO_NAME'):
-                    base = '/' + req.env['REPO_NAME']
-                else:
-                    base = root
+                def normurl(url):
+                    inner = '/'.join([x for x in url.split('/') if x])
+                    tl = len(url) > 1 and url.endswith('/') and '/' or ''
 
+                    return '%s%s%s' % (url.startswith('/') and '/' or '',
+                                       inner, tl)
+
+                root = normurl(req.env.get('REQUEST_URI', '').split('?', 1)[0])
+                pi = normurl(req.env.get('PATH_INFO', ''))
                 if pi:
-                    while pi.startswith('//'):
-                        pi = pi[1:]
-                    if pi.startswith(base):
-                        if len(pi) > len(base):
-                            base += '/'
-                            query = pi[len(base):]
-                        else:
-                            if req.env.has_key('REPO_NAME'):
-                                # We are using hgwebdir
-                                base += '/'
-                            else:
-                                base += '?'
-                            query = firstitem(req.env['QUERY_STRING'])
+                    # strip leading /
+                    pi = pi[1:]
+                    if pi:
+                        root = root[:-len(pi)]
+                    if req.env.has_key('REPO_NAME'):
+                        rn = req.env['REPO_NAME'] + '/'
+                        root += rn
+                        query = pi[len(rn):]
                     else:
-                        base += '/'
-                        query = pi[1:]
+                        query = pi
                 else:
-                    base += '?'
+                    root += '?'
                     query = firstitem(req.env['QUERY_STRING'])
 
-                return (root + base, query)
+                return (root, query)
 
             req.url, query = spliturl(req)
 
@@ -779,8 +772,11 @@ class hgweb(object):
     def changectx(self, req):
         if req.form.has_key('node'):
             changeid = req.form['node'][0]
+        elif req.form.has_key('manifest'):
+            changeid = req.form['manifest'][0]
         else:
-            changeid = req.form['manifest'][0]
+            changeid = self.repo.changelog.count() - 1
+
         try:
             ctx = self.repo.changectx(changeid)
         except hg.RepoError:
@@ -855,8 +851,7 @@ class hgweb(object):
         self.do_changelog(req, shortlog = True)
 
     def do_changeset(self, req):
-        ctx = self.repo.changectx(req.form['node'][0])
-        req.write(self.changeset(ctx))
+        req.write(self.changeset(self.changectx(req)))
 
     def do_manifest(self, req):
         req.write(self.manifest(self.changectx(req),
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -69,13 +69,18 @@ class hgwebdir(object):
         def footer(**map):
             yield tmpl("footer", motd=self.motd, **map)
 
+        url = req.env['REQUEST_URI'].split('?')[0]
+        if not url.endswith('/'):
+            url += '/'
+
         style = self.style
         if req.form.has_key('style'):
             style = req.form['style'][0]
         mapfile = style_map(templater.templatepath(), style)
         tmpl = templater.templater(mapfile, templater.common_filters,
                                    defaults={"header": header,
-                                             "footer": footer})
+                                             "footer": footer,
+                                             "url": url})
 
         def archivelist(ui, nodeid, url):
             allowed = ui.configlist("web", "allow_archive")
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -54,7 +54,7 @@ class localrepository(repo.repository):
         except IOError:
             pass
 
-        v = self.ui.revlogopts
+        v = self.ui.configrevlog()
         self.revlogversion = int(v.get('format', revlog.REVLOG_DEFAULT_FORMAT))
         self.revlogv1 = self.revlogversion != revlog.REVLOGV0
         fl = v.get('flags', None)
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -467,6 +467,7 @@ def diff(repo, node1=None, node2=None, f
         to = None
         tn = None
         dodiff = True
+        header = []
         if f in mmap:
             to = getfile(f).read(mmap[f])
         if f not in removed:
@@ -480,7 +481,6 @@ def diff(repo, node1=None, node2=None, f
                     header.append('new mode %s\n' % nmode)
 
             a, b = f, f
-            header = []
             if f in added:
                 if node2:
                     mode = gitmode(mmap2.execf(f))
@@ -510,11 +510,12 @@ def diff(repo, node1=None, node2=None, f
                     nmode = gitmode(util.is_exec(repo.wjoin(f), mmap.execf(f)))
                 addmodehdr(header, omode, nmode)
             r = None
-            if dodiff:
-                header.insert(0, 'diff --git a/%s b/%s\n' % (a, b))
+            header.insert(0, 'diff --git a/%s b/%s\n' % (a, b))
+        if dodiff:
+            text = mdiff.unidiff(to, date1, tn, date2(f), f, r, opts=opts)
+            if text or len(header) > 1:
                 fp.write(''.join(header))
-        if dodiff:
-            fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, opts=opts))
+            fp.write(text)
 
 def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
            opts=None):
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -973,7 +973,7 @@ class revlog(object):
             end = self.end(t)
             if not d:
                 prev = self.revision(self.tip())
-                d = self.diff(prev, str(text))
+                d = self.diff(prev, text)
             data = compress(d)
             l = len(data[1]) + len(data[0])
             dist = end - start + l
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -10,61 +10,75 @@ from demandload import *
 demandload(globals(), "errno getpass os re socket sys tempfile")
 demandload(globals(), "ConfigParser mdiff templater traceback util")
 
+def dupconfig(orig):
+    new = ConfigParser.SafeConfigParser(orig.defaults())
+    updateconfig(orig, new)
+    return new
+
+def updateconfig(source, dest):
+    for section in source.sections():
+        if not dest.has_section(section):
+            dest.add_section(section)
+        for name, value in source.items(section, raw=True):
+            dest.set(section, name, value)
+
 class ui(object):
     def __init__(self, verbose=False, debug=False, quiet=False,
                  interactive=True, traceback=False, parentui=None):
-        self.overlay = {}
+        self.overlay = None
+        self.header = []
+        self.prev_header = []
         if parentui is None:
             # this is the parent of all ui children
             self.parentui = None
             self.readhooks = []
+            self.quiet = quiet
+            self.verbose = verbose
+            self.debugflag = debug
+            self.interactive = interactive
+            self.traceback = traceback
             self.cdata = ConfigParser.SafeConfigParser()
             self.readconfig(util.rcpath())
-
-            self.quiet = self.configbool("ui", "quiet")
-            self.verbose = self.configbool("ui", "verbose")
-            self.debugflag = self.configbool("ui", "debug")
-            self.interactive = self.configbool("ui", "interactive", True)
-            self.traceback = traceback
-
             self.updateopts(verbose, debug, quiet, interactive)
-            self.diffcache = None
-            self.header = []
-            self.prev_header = []
-            self.revlogopts = self.configrevlog()
         else:
             # parentui may point to an ui object which is already a child
             self.parentui = parentui.parentui or parentui
-            self.readhooks = parentui.readhooks[:]
-            parent_cdata = self.parentui.cdata
-            self.cdata = ConfigParser.SafeConfigParser(parent_cdata.defaults())
-            # make interpolation work
-            for section in parent_cdata.sections():
-                self.cdata.add_section(section)
-                for name, value in parent_cdata.items(section, raw=True):
-                    self.cdata.set(section, name, value)
+            self.readhooks = self.parentui.readhooks[:]
+            self.cdata = dupconfig(self.parentui.cdata)
+            if self.parentui.overlay:
+                self.overlay = dupconfig(self.parentui.overlay)
 
     def __getattr__(self, key):
         return getattr(self.parentui, key)
 
     def updateopts(self, verbose=False, debug=False, quiet=False,
                    interactive=True, traceback=False, config=[]):
-        self.quiet = (self.quiet or quiet) and not verbose and not debug
-        self.verbose = ((self.verbose or verbose) or debug) and not self.quiet
-        self.debugflag = (self.debugflag or debug)
-        self.interactive = (self.interactive and interactive)
+        for section, name, value in config:
+            self.setconfig(section, name, value)
+
+        if quiet or verbose or debug:
+            self.setconfig('ui', 'quiet', str(bool(quiet)))
+            self.setconfig('ui', 'verbose', str(bool(verbose)))
+            self.setconfig('ui', 'debug', str(bool(debug)))
+
+        self.verbosity_constraints()
+
+        if not interactive:
+            self.setconfig('ui', 'interactive', 'False')
+            self.interactive = False
+
         self.traceback = self.traceback or traceback
-        for cfg in config:
-            try:
-                name, value = cfg.split('=', 1)
-                section, name = name.split('.', 1)
-                if not self.cdata.has_section(section):
-                    self.cdata.add_section(section)
-                if not section or not name:
-                    raise IndexError
-                self.cdata.set(section, name, value)
-            except (IndexError, ValueError):
-                raise util.Abort(_('malformed --config option: %s') % cfg)
+
+    def verbosity_constraints(self):
+        self.quiet = self.configbool('ui', 'quiet')
+        self.verbose = self.configbool('ui', 'verbose')
+        self.debugflag = self.configbool('ui', 'debug')
+
+        if self.debugflag:
+            self.verbose = True
+            self.quiet = False
+        elif self.verbose and self.quiet:
+            self.quiet = self.verbose = False
 
     def readconfig(self, fn, root=None):
         if isinstance(fn, basestring):
@@ -74,35 +88,67 @@ class ui(object):
                 self.cdata.read(f)
             except ConfigParser.ParsingError, inst:
                 raise util.Abort(_("Failed to parse %s\n%s") % (f, inst))
-        # translate paths relative to root (or home) into absolute paths
+        # override data from config files with data set with ui.setconfig
+        if self.overlay:
+            updateconfig(self.overlay, self.cdata)
         if root is None:
             root = os.path.expanduser('~')
-        for name, path in self.configitems("paths"):
-            if path and "://" not in path and not os.path.isabs(path):
-                self.cdata.set("paths", name, os.path.join(root, path))
+        self.fixconfig(root=root)
         for hook in self.readhooks:
             hook(self)
 
     def addreadhook(self, hook):
         self.readhooks.append(hook)
 
-    def setconfig(self, section, name, val):
-        self.overlay[(section, name)] = val
+    def fixconfig(self, section=None, name=None, value=None, root=None):
+        # translate paths relative to root (or home) into absolute paths
+        if section is None or section == 'paths':
+            if root is None:
+                root = os.getcwd()
+            items = section and [(name, value)] or []
+            for cdata in self.cdata, self.overlay:
+                if not cdata: continue
+                if not items and cdata.has_section('paths'):
+                    pathsitems = cdata.items('paths')
+                else:
+                    pathsitems = items
+                for n, path in pathsitems:
+                    if path and "://" not in path and not os.path.isabs(path):
+                        cdata.set("paths", n, os.path.join(root, path))
 
-    def config(self, section, name, default=None):
-        if self.overlay.has_key((section, name)):
-            return self.overlay[(section, name)]
+        # update quiet/verbose/debug and interactive status
+        if section is None or section == 'ui':
+            if name is None or name in ('quiet', 'verbose', 'debug'):
+                self.verbosity_constraints()
+
+            if name is None or name == 'interactive':
+                self.interactive = self.configbool("ui", "interactive", True)
+
+    def setconfig(self, section, name, value):
+        if not self.overlay:
+            self.overlay = ConfigParser.SafeConfigParser()
+        for cdata in (self.overlay, self.cdata):
+            if not cdata.has_section(section):
+                cdata.add_section(section)
+            cdata.set(section, name, value)
+        self.fixconfig(section, name, value)
+
+    def _config(self, section, name, default, funcname):
         if self.cdata.has_option(section, name):
             try:
-                return self.cdata.get(section, name)
+                func = getattr(self.cdata, funcname)
+                return func(section, name)
             except ConfigParser.InterpolationError, inst:
                 raise util.Abort(_("Error in configuration section [%s] "
                                    "parameter '%s':\n%s")
                                  % (section, name, inst))
-        if self.parentui is None:
-            return default
-        else:
-            return self.parentui.config(section, name, default)
+        return default
+
+    def config(self, section, name, default=None):
+        return self._config(section, name, default, 'get')
+
+    def configbool(self, section, name, default=False):
+        return self._config(section, name, default, 'getboolean')
 
     def configlist(self, section, name, default=None):
         """Return a list of comma/space separated strings"""
@@ -113,29 +159,12 @@ class ui(object):
             result = result.replace(",", " ").split()
         return result
 
-    def configbool(self, section, name, default=False):
-        if self.overlay.has_key((section, name)):
-            return self.overlay[(section, name)]
-        if self.cdata.has_option(section, name):
-            try:
-                return self.cdata.getboolean(section, name)
-            except ConfigParser.InterpolationError, inst:
-                raise util.Abort(_("Error in configuration section [%s] "
-                                   "parameter '%s':\n%s")
-                                 % (section, name, inst))
-        if self.parentui is None:
-            return default
-        else:
-            return self.parentui.configbool(section, name, default)
-
     def has_config(self, section):
         '''tell whether section exists in config.'''
         return self.cdata.has_section(section)
 
     def configitems(self, section):
         items = {}
-        if self.parentui is not None:
-            items = dict(self.parentui.configitems(section))
         if self.cdata.has_section(section):
             try:
                 items.update(dict(self.cdata.items(section)))
@@ -146,24 +175,12 @@ class ui(object):
         x.sort()
         return x
 
-    def walkconfig(self, seen=None):
-        if seen is None:
-            seen = {}
-        for (section, name), value in self.overlay.iteritems():
-            yield section, name, value
-            seen[section, name] = 1
-        for section in self.cdata.sections():
-            try:
-                for name, value in self.cdata.items(section):
-                    if (section, name) in seen: continue
-                    yield section, name, value.replace('\n', '\\n')
-                    seen[section, name] = 1
-            except ConfigParser.InterpolationError, inst:
-                raise util.Abort(_("Error in configuration section [%s]:\n%s")
-                                 % (section, inst))
-        if self.parentui is not None:
-            for parent in self.parentui.walkconfig(seen):
-                yield parent
+    def walkconfig(self):
+        sections = self.cdata.sections()
+        sections.sort()
+        for section in sections:
+            for name, value in self.configitems(section):
+                yield section, name, value.replace('\n', '\\n')
 
     def extensions(self):
         result = self.configitems("extensions")
--- a/tests/test-extdiff
+++ b/tests/test-extdiff
@@ -26,4 +26,13 @@ hg ci -d '0 0' -mtest1
 echo b >> a
 hg ci -d '1 0' -mtest2
 
-hg falabala -r 0:1 || echo "diff-like tools yield a non-zero exit code"
+hg falabala -r 0:1
+
+# test diff during merge
+hg update 0
+echo b >> b
+hg add b
+hg ci -m "new branch" -d '1 0'
+hg update -C 1
+hg merge tip
+hg falabala || echo "diff-like tools yield a non-zero exit code"
--- a/tests/test-extdiff.out
+++ b/tests/test-extdiff.out
@@ -29,4 +29,11 @@ options:
 making snapshot of 1 files from rev e27a2475d60a
 making snapshot of 1 files from rev 5e49ec8d3f05
 diffing a.e27a2475d60a a.5e49ec8d3f05
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+making snapshot of 1 files from rev 5e49ec8d3f05
+making snapshot of 1 files from working dir
+diffing a.5e49ec8d3f05 a
 diff-like tools yield a non-zero exit code
--- a/tests/test-globalopts.out
+++ b/tests/test-globalopts.out
@@ -105,6 +105,7 @@ a
 
 
 %% --traceback
+Traceback (most recent call last):
 %% --time
 Time: real x.x secs (user x.x+x.x sys x.x+x.x)
 %% --version
--- a/tests/test-merge1
+++ b/tests/test-merge1
@@ -23,6 +23,8 @@ hg commit -m "commit #2" -d "1000000 0"
 echo This is file b1 > b
 echo %% no merges expected
 env HGMERGE=../merge hg merge 1
+hg diff --nodates
+hg status
 cd ..; /bin/rm -rf t
 
 mkdir t
@@ -44,6 +46,8 @@ echo %% merge should fail
 env HGMERGE=../merge hg merge 1
 echo %% merge of b expected
 env HGMERGE=../merge hg merge -f 1
+hg diff --nodates
+hg status
 cd ..; /bin/rm -rf t
 echo %%
 
@@ -71,6 +75,8 @@ echo %% merge fails
 env HGMERGE=../merge hg merge 2
 echo %% merge expected!
 env HGMERGE=../merge hg merge -f 2
+hg diff --nodates
+hg status
 cd ..; /bin/rm -rf t
 
 mkdir t
@@ -93,4 +99,6 @@ echo %% merge of b should fail
 env HGMERGE=../merge hg merge 2
 echo %% merge of b expected
 env HGMERGE=../merge hg merge -f 2
+hg diff --nodates
+hg status
 cd ..; /bin/rm -rf t
--- a/tests/test-merge1.out
+++ b/tests/test-merge1.out
@@ -2,6 +2,12 @@ 0 files updated, 0 files merged, 1 files
 %% no merges expected
 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
+diff -r d9e5953b9dec b
+--- /dev/null
++++ b/b
+@@ -0,0 +1,1 @@
++This is file b1
+M b
 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
 %% merge should fail
 abort: 'b' already exists in the working dir and differs from remote
@@ -10,6 +16,12 @@ merging for b
 merging b
 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
+diff -r d9e5953b9dec b
+--- /dev/null
++++ b/b
+@@ -0,0 +1,1 @@
++This is file b2
+M b
 %%
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 Contents of b should be "this is file b1"
@@ -19,6 +31,13 @@ abort: outstanding uncommitted changes
 %% merge expected!
 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
+diff -r c1dd73cbf59f b
+--- a/b
++++ b/b
+@@ -1,1 +1,1 @@ This is file b1
+-This is file b1
++This is file b22
+M b
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 %% merge of b should fail
 abort: outstanding uncommitted changes
@@ -27,3 +46,10 @@ merging for b
 merging b
 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
+diff -r c1dd73cbf59f b
+--- a/b
++++ b/b
+@@ -1,1 +1,1 @@ This is file b1
+-This is file b1
++This is file b33
+M b
--- a/tests/test-mq
+++ b/tests/test-mq
@@ -160,6 +160,17 @@ sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/
     -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" ../.hg/patches/foo
 hg status
 
+echo % qpush failure
+cd ..
+hg qrefresh
+hg qnew -mbar bar
+echo foo > foo
+hg add foo
+hg qrefresh
+hg qpop -a
+echo bar > foo
+hg qpush -a
+
 cat >>$HGRCPATH <<EOF
 [diff]
 git = True
--- a/tests/test-mq.out
+++ b/tests/test-mq.out
@@ -164,6 +164,14 @@ diff -r cb9a9f314b8b b/f
 @@ -0,0 +1,1 @@
 +f
 M a
+% qpush failure
+Patch queue now empty
+applying foo
+applying bar
+1 out of 1 hunk ignored -- saving rejects to file foo.rej
+patch failed, unable to continue (try -v)
+patch failed, rejects left in working dir
+Errors during apply, please fix and refresh bar
 new file
 
 diff --git a/new b/new
--- a/tests/test-ui-config
+++ b/tests/test-ui-config
@@ -1,9 +1,9 @@
 #!/usr/bin/env python
 
-from mercurial import ui, util
+from mercurial import ui, util, commands
 
 testui = ui.ui()
-testui.updateopts(config=[
+parsed = commands.parseconfig([
     'values.string=string value',
     'values.bool1=true',
     'values.bool2=false',
@@ -17,6 +17,7 @@ testui.updateopts(config=[
     'interpolation.value4=%(bad)1',
     'interpolation.value5=%bad2',
 ])
+testui.updateopts(config=parsed)
 
 print repr(testui.configitems('values'))
 print repr(testui.configitems('lists'))
new file mode 100755
--- /dev/null
+++ b/tests/test-ui-verbosity
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+
+import os
+from mercurial import ui
+
+hgrc = os.environ['HGRCPATH']
+
+print '      hgrc settings    command line options      final result   '
+print '    quiet verbo debug   quiet verbo debug      quiet verbo debug'
+
+for i in xrange(64):
+    hgrc_quiet   = bool(i & 1<<0)
+    hgrc_verbose = bool(i & 1<<1)
+    hgrc_debug   = bool(i & 1<<2)
+    cmd_quiet    = bool(i & 1<<3)
+    cmd_verbose  = bool(i & 1<<4)
+    cmd_debug    = bool(i & 1<<5)
+
+    f = open(hgrc, 'w')
+    f.write('[ui]\n')
+    if hgrc_quiet:
+        f.write('quiet = True\n')
+    if hgrc_verbose:
+        f.write('verbose = True\n')
+    if hgrc_debug:
+        f.write('debug = True\n')
+    f.close()
+
+    u = ui.ui()
+    u.updateopts(quiet=cmd_quiet, verbose=cmd_verbose, debug=cmd_debug)
+
+    check = ''
+    if u.debugflag:
+        if not u.verbose or u.quiet:
+            check = ' *'
+    elif u.verbose and u.quiet:
+        check = ' +'
+
+    print ('%2d  %5s %5s %5s   %5s %5s %5s  ->  %5s %5s %5s%s'
+           % (i, hgrc_quiet, hgrc_verbose, hgrc_debug,
+              cmd_quiet, cmd_verbose, cmd_debug,
+              u.quiet, u.verbose, u.debugflag, check))
new file mode 100644
--- /dev/null
+++ b/tests/test-ui-verbosity.out
@@ -0,0 +1,66 @@
+      hgrc settings    command line options      final result   
+    quiet verbo debug   quiet verbo debug      quiet verbo debug
+ 0  False False False   False False False  ->  False False False
+ 1   True False False   False False False  ->   True False False
+ 2  False  True False   False False False  ->  False  True False
+ 3   True  True False   False False False  ->  False False False
+ 4  False False  True   False False False  ->  False  True  True
+ 5   True False  True   False False False  ->  False  True  True
+ 6  False  True  True   False False False  ->  False  True  True
+ 7   True  True  True   False False False  ->  False  True  True
+ 8  False False False    True False False  ->   True False False
+ 9   True False False    True False False  ->   True False False
+10  False  True False    True False False  ->   True False False
+11   True  True False    True False False  ->   True False False
+12  False False  True    True False False  ->   True False False
+13   True False  True    True False False  ->   True False False
+14  False  True  True    True False False  ->   True False False
+15   True  True  True    True False False  ->   True False False
+16  False False False   False  True False  ->  False  True False
+17   True False False   False  True False  ->  False  True False
+18  False  True False   False  True False  ->  False  True False
+19   True  True False   False  True False  ->  False  True False
+20  False False  True   False  True False  ->  False  True False
+21   True False  True   False  True False  ->  False  True False
+22  False  True  True   False  True False  ->  False  True False
+23   True  True  True   False  True False  ->  False  True False
+24  False False False    True  True False  ->  False False False
+25   True False False    True  True False  ->  False False False
+26  False  True False    True  True False  ->  False False False
+27   True  True False    True  True False  ->  False False False
+28  False False  True    True  True False  ->  False False False
+29   True False  True    True  True False  ->  False False False
+30  False  True  True    True  True False  ->  False False False
+31   True  True  True    True  True False  ->  False False False
+32  False False False   False False  True  ->  False  True  True
+33   True False False   False False  True  ->  False  True  True
+34  False  True False   False False  True  ->  False  True  True
+35   True  True False   False False  True  ->  False  True  True
+36  False False  True   False False  True  ->  False  True  True
+37   True False  True   False False  True  ->  False  True  True
+38  False  True  True   False False  True  ->  False  True  True
+39   True  True  True   False False  True  ->  False  True  True
+40  False False False    True False  True  ->  False  True  True
+41   True False False    True False  True  ->  False  True  True
+42  False  True False    True False  True  ->  False  True  True
+43   True  True False    True False  True  ->  False  True  True
+44  False False  True    True False  True  ->  False  True  True
+45   True False  True    True False  True  ->  False  True  True
+46  False  True  True    True False  True  ->  False  True  True
+47   True  True  True    True False  True  ->  False  True  True
+48  False False False   False  True  True  ->  False  True  True
+49   True False False   False  True  True  ->  False  True  True
+50  False  True False   False  True  True  ->  False  True  True
+51   True  True False   False  True  True  ->  False  True  True
+52  False False  True   False  True  True  ->  False  True  True
+53   True False  True   False  True  True  ->  False  True  True
+54  False  True  True   False  True  True  ->  False  True  True
+55   True  True  True   False  True  True  ->  False  True  True
+56  False False False    True  True  True  ->  False  True  True
+57   True False False    True  True  True  ->  False  True  True
+58  False  True False    True  True  True  ->  False  True  True
+59   True  True False    True  True  True  ->  False  True  True
+60  False False  True    True  True  True  ->  False  True  True
+61   True False  True    True  True  True  ->  False  True  True
+62  False  True  True    True  True  True  ->  False  True  True
+63   True  True  True    True  True  True  ->  False  True  True