changeset 7135:06ca03380190

merge with crew
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Sat, 18 Oct 2008 20:39:08 +0200
parents cb6395fc16a9 (current diff) e9a2525d8834 (diff)
children d834ed27199f 0df098871e3d
files mercurial/parsers.c
diffstat 19 files changed, 245 insertions(+), 150 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/churn.py	Sat Oct 18 20:25:45 2008 +0200
+++ b/hgext/churn.py	Sat Oct 18 20:39:08 2008 +0200
@@ -5,7 +5,7 @@
 #
 # This software may be used and distributed according to the terms
 # of the GNU General Public License, incorporated herein by reference.
-'''allow graphing the number of lines (or count of revisions) grouped by template'''
+'''command to show certain statistics about revision history'''
 
 from mercurial.i18n import _
 from mercurial import patch, cmdutil, util, templater
@@ -180,5 +180,5 @@
           ('s', 'sort', False, _('sort by key (default: sort by count)')),
           ('', 'aliases', '', _('file with email aliases')),
           ('', 'progress', None, _('show progress'))],
-         _("hg stats [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]")),
+         _("hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]")),
 }
--- a/hgext/highlight/__init__.py	Sat Oct 18 20:25:45 2008 +0200
+++ b/hgext/highlight/__init__.py	Sat Oct 18 20:39:08 2008 +0200
@@ -1,4 +1,4 @@
-"""a mercurial extension for syntax highlighting in hgweb
+"""syntax highlighting in hgweb, based on Pygments
 
 It depends on the pygments syntax highlighting library:
 http://pygments.org/
--- a/hgext/notify.py	Sat Oct 18 20:25:45 2008 +0200
+++ b/hgext/notify.py	Sat Oct 18 20:39:08 2008 +0200
@@ -4,66 +4,65 @@
 #
 # This software may be used and distributed according to the terms
 # of the GNU General Public License, incorporated herein by reference.
-#
-# hook extension to email notifications to people when changesets are
-# committed to a repo they subscribe to.
-#
-# default mode is to print messages to stdout, for testing and
-# configuring.
-#
-# to use, configure notify extension and enable in hgrc like this:
-#
-#   [extensions]
-#   hgext.notify =
-#
-#   [hooks]
-#   # one email for each incoming changeset
-#   incoming.notify = python:hgext.notify.hook
-#   # batch emails when many changesets incoming at one time
-#   changegroup.notify = python:hgext.notify.hook
-#
-#   [notify]
-#   # config items go in here
-#
-# config items:
-#
-# REQUIRED:
-#   config = /path/to/file # file containing subscriptions
-#
-# OPTIONAL:
-#   test = True            # print messages to stdout for testing
-#   strip = 3              # number of slashes to strip for url paths
-#   domain = example.com   # domain to use if committer missing domain
-#   style = ...            # style file to use when formatting email
-#   template = ...         # template to use when formatting email
-#   incoming = ...         # template to use when run as incoming hook
-#   changegroup = ...      # template when run as changegroup hook
-#   maxdiff = 300          # max lines of diffs to include (0=none, -1=all)
-#   maxsubject = 67        # truncate subject line longer than this
-#   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)
-#   [email]
-#   from = user@host.com   # email address to send as if none given
-#   [web]
-#   baseurl = http://hgserver/... # root of hg web site for browsing commits
-#
-# notify config file has same format as regular hgrc. it has two
-# sections so you can express subscriptions in whatever way is handier
-# for you.
-#
-#   [usersubs]
-#   # key is subscriber email, value is ","-separated list of glob patterns
-#   user@host = pattern
-#
-#   [reposubs]
-#   # key is glob pattern, value is ","-separated list of subscriber emails
-#   pattern = user@host
-#
-# glob patterns are matched against path to repo root.
-#
-# if you like, you can put notify config file in repo that users can
-# push changes to, they can manage their own subscriptions.
+
+'''hook extension to email notifications on commits/pushes
+
+Subscriptions can be managed through hgrc. Default mode is to print
+messages to stdout, for testing and configuring.
+
+To use, configure notify extension and enable in hgrc like this:
+
+   [extensions]
+   hgext.notify =
+
+   [hooks]
+   # one email for each incoming changeset
+   incoming.notify = python:hgext.notify.hook
+   # batch emails when many changesets incoming at one time
+   changegroup.notify = python:hgext.notify.hook
+
+   [notify]
+   # config items go in here
+
+ config items:
+
+ REQUIRED:
+   config = /path/to/file # file containing subscriptions
+
+ OPTIONAL:
+   test = True            # print messages to stdout for testing
+   strip = 3              # number of slashes to strip for url paths
+   domain = example.com   # domain to use if committer missing domain
+   style = ...            # style file to use when formatting email
+   template = ...         # template to use when formatting email
+   incoming = ...         # template to use when run as incoming hook
+   changegroup = ...      # template when run as changegroup hook
+   maxdiff = 300          # max lines of diffs to include (0=none, -1=all)
+   maxsubject = 67        # truncate subject line longer than this
+   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)
+   [email]
+   from = user@host.com   # email address to send as if none given
+   [web]
+   baseurl = http://hgserver/... # root of hg web site for browsing commits
+
+ notify config file has same format as regular hgrc. it has two
+ sections so you can express subscriptions in whatever way is handier
+ for you.
+
+   [usersubs]
+   # key is subscriber email, value is ","-separated list of glob patterns
+   user@host = pattern
+
+   [reposubs]
+   # key is glob pattern, value is ","-separated list of subscriber emails
+   pattern = user@host
+
+ glob patterns are matched against path to repo root.
+
+ if you like, you can put notify config file in repo that users can
+ push changes to, they can manage their own subscriptions.'''
 
 from mercurial.i18n import _
 from mercurial.node import bin, short
--- a/hgext/rebase.py	Sat Oct 18 20:25:45 2008 +0200
+++ b/hgext/rebase.py	Sat Oct 18 20:39:08 2008 +0200
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms
 # of the GNU General Public License, incorporated herein by reference.
 
-''' Rebasing feature
+'''move sets of revisions to a different ancestor
 
 This extension lets you rebase changesets in an existing Mercurial repository.
 
@@ -105,6 +105,8 @@
 
         clearstatus(repo)
         ui.status(_("rebase completed\n"))
+        if os.path.exists(repo.sjoin('undo')):
+            util.unlink(repo.sjoin('undo'))
         if skipped:
             ui.note(_("%d revisions have been skipped\n") % len(skipped))
     finally:
--- a/mercurial/commands.py	Sat Oct 18 20:25:45 2008 +0200
+++ b/mercurial/commands.py	Sat Oct 18 20:39:08 2008 +0200
@@ -94,12 +94,12 @@
              ('follow', lambda x: x[0].path()),
             ]
 
-    if (not opts['user'] and not opts['changeset'] and not opts['date']
-        and not opts['follow']):
+    if (not opts.get('user') and not opts.get('changeset') and not opts.get('date')
+        and not opts.get('follow')):
         opts['number'] = 1
 
     linenumber = opts.get('line_number') is not None
-    if (linenumber and (not opts['changeset']) and (not opts['number'])):
+    if (linenumber and (not opts.get('changeset')) and (not opts.get('number'))):
         raise util.Abort(_('at least one of -n/-c is required for -l'))
 
     funcmap = [func for op, func in opmap if opts.get(op)]
@@ -107,12 +107,12 @@
         lastfunc = funcmap[-1]
         funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
 
-    ctx = repo[opts['rev']]
+    ctx = repo[opts.get('rev')]
 
     m = cmdutil.match(repo, pats, opts)
     for abs in ctx.walk(m):
         fctx = ctx[abs]
-        if not opts['text'] and util.binary(fctx.data()):
+        if not opts.get('text') and util.binary(fctx.data()):
             ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
             continue
 
@@ -154,7 +154,7 @@
     The default is the basename of the archive, with suffixes removed.
     '''
 
-    ctx = repo[opts['rev']]
+    ctx = repo[opts.get('rev')]
     if not ctx:
         raise util.Abort(_('repository has no revisions'))
     node = ctx.node()
@@ -163,14 +163,14 @@
         raise util.Abort(_('repository root cannot be destination'))
     matchfn = cmdutil.match(repo, [], opts)
     kind = opts.get('type') or 'files'
-    prefix = opts['prefix']
+    prefix = opts.get('prefix')
     if dest == '-':
         if kind == 'files':
             raise util.Abort(_('cannot archive plain files to stdout'))
         dest = sys.stdout
         if not prefix: prefix = os.path.basename(repo.root) + '-%h'
     prefix = cmdutil.make_filename(repo, prefix, node)
-    archival.archive(repo, dest, node, kind, not opts['no_decode'],
+    archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
                      matchfn, prefix)
 
 def backout(ui, repo, node=None, rev=None, **opts):
@@ -216,7 +216,7 @@
     if p1 == nullid:
         raise util.Abort(_('cannot back out a change with no parents'))
     if p2 != nullid:
-        if not opts['parent']:
+        if not opts.get('parent'):
             raise util.Abort(_('cannot back out a merge changeset without '
                                '--parent'))
         p = repo.lookup(opts['parent'])
@@ -225,7 +225,7 @@
                              (short(p), short(node)))
         parent = p
     else:
-        if opts['parent']:
+        if opts.get('parent'):
             raise util.Abort(_('cannot use --parent on non-merge changeset'))
         parent = p1
 
@@ -251,7 +251,7 @@
               (nice(repo.changelog.tip()), nice(node)))
     if op1 != node:
         hg.clean(repo, op1, show_stats=False)
-        if opts['merge']:
+        if opts.get('merge'):
             ui.status(_('merging with changeset %s\n') % nice(repo.changelog.tip()))
             hg.merge(repo, hex(repo.changelog.tip()))
         else:
@@ -478,7 +478,7 @@
         dest, revs, checkout = hg.parseurl(
             ui.expandpath(dest or 'default-push', dest or 'default'), revs)
         other = hg.repository(ui, dest)
-        o = repo.findoutgoing(other, force=opts['force'])
+        o = repo.findoutgoing(other, force=opts.get('force'))
 
     if revs:
         cg = repo.changegroupsubset(o, revs, 'bundle')
@@ -508,11 +508,11 @@
     %d   dirname of file being printed, or '.' if in repo root
     %p   root-relative path name of file being printed
     """
-    ctx = repo[opts['rev']]
+    ctx = repo[opts.get('rev')]
     err = 1
     m = cmdutil.match(repo, (file1,) + pats, opts)
     for abs in ctx.walk(m):
-        fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
+        fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
         data = ctx[abs].data()
         if opts.get('decode'):
             data = repo.wwritedata(abs, data)
@@ -566,10 +566,10 @@
     """
     cmdutil.setremoteconfig(ui, opts)
     hg.clone(ui, source, dest,
-             pull=opts['pull'],
-             stream=opts['uncompressed'],
-             rev=opts['rev'],
-             update=not opts['noupdate'])
+             pull=opts.get('pull'),
+             stream=opts.get('uncompressed'),
+             rev=opts.get('rev'),
+             update=not opts.get('noupdate'))
 
 def commit(ui, repo, *pats, **opts):
     """commit the specified files or all outstanding changes
@@ -588,7 +588,7 @@
     See 'hg help dates' for a list of formats valid for -d/--date.
     """
     def commitfunc(ui, repo, message, match, opts):
-        return repo.commit(match.files(), message, opts['user'], opts['date'],
+        return repo.commit(match.files(), message, opts.get('user'), opts.get('date'),
                            match, force_editor=opts.get('force_editor'))
 
     node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
@@ -651,7 +651,7 @@
 def debugcomplete(ui, cmd='', **opts):
     """returns the completion list associated with the given command"""
 
-    if opts['options']:
+    if opts.get('options'):
         options = []
         otables = [globalopts]
         if cmd:
@@ -981,7 +981,7 @@
     it detects as binary. With -a, diff will generate a diff anyway,
     probably with undesirable results.
     """
-    node1, node2 = cmdutil.revpair(repo, opts['rev'])
+    node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
 
     m = cmdutil.match(repo, pats, opts)
     patch.diff(repo, node1, node2, match=m, opts=patch.diffopts(ui, opts))
@@ -1023,8 +1023,8 @@
         ui.note(_('exporting patches:\n'))
     else:
         ui.note(_('exporting patch:\n'))
-    patch.export(repo, revs, template=opts['output'],
-                 switch_parent=opts['switch_parent'],
+    patch.export(repo, revs, template=opts.get('output'),
+                 switch_parent=opts.get('switch_parent'),
                  opts=patch.diffopts(ui, opts))
 
 def grep(ui, repo, pattern, *pats, **opts):
@@ -1044,7 +1044,7 @@
     use the --all flag.
     """
     reflags = 0
-    if opts['ignore_case']:
+    if opts.get('ignore_case'):
         reflags |= re.I
     try:
         regexp = re.compile(pattern, reflags)
@@ -1052,7 +1052,7 @@
         ui.warn(_("grep: invalid match pattern: %s\n") % inst)
         return None
     sep, eol = ':', '\n'
-    if opts['print0']:
+    if opts.get('print0'):
         sep = eol = '\0'
 
     fcache = {}
@@ -1118,21 +1118,21 @@
         found = False
         filerevmatches = {}
         r = prev.get(fn, -1)
-        if opts['all']:
+        if opts.get('all'):
             iter = difflinestates(states, prevstates)
         else:
             iter = [('', l) for l in prevstates]
         for change, l in iter:
             cols = [fn, str(r)]
-            if opts['line_number']:
+            if opts.get('line_number'):
                 cols.append(str(l.linenum))
-            if opts['all']:
+            if opts.get('all'):
                 cols.append(change)
-            if opts['user']:
+            if opts.get('user'):
                 cols.append(ui.shortuser(get(r)[1]))
             if opts.get('date'):
                 cols.append(datefunc(get(r)[2]))
-            if opts['files_with_matches']:
+            if opts.get('files_with_matches'):
                 c = (fn, r)
                 if c in filerevmatches:
                     continue
@@ -1177,7 +1177,7 @@
                 if fn in prev or fstate[fn]:
                     r = display(fn, rev, m, fstate[fn])
                     found = found or r
-                    if r and not opts['all']:
+                    if r and not opts.get('all'):
                         skip[fn] = True
                         if copy:
                             skip[copy] = True
@@ -1210,7 +1210,7 @@
     no child changesets with that tag. They are usually where
     development on the given branch takes place.
     """
-    if opts['rev']:
+    if opts.get('rev'):
         start = repo.lookup(opts['rev'])
     else:
         start = None
@@ -1230,10 +1230,10 @@
                 if branch != branchrev:
                     ui.warn(_("no changes on branch %s containing %s are "
                               "reachable from %s\n")
-                            % (branch, branchrev, opts['rev']))
+                            % (branch, branchrev, opts.get('rev')))
                 else:
                     ui.warn(_("no changes on branch %s are reachable from %s\n")
-                            % (branch, opts['rev']))
+                            % (branch, opts.get('rev')))
             heads.extend(bheads)
     if not heads:
         return 1
@@ -1310,6 +1310,8 @@
             f = c.split("|", 1)[0]
             if select and not select(f):
                 continue
+            if select is None and e[0].__module__ != __name__:
+                continue
             if name == "shortlist" and not f.startswith("^"):
                 continue
             f = f.lstrip("^")
@@ -1335,6 +1337,19 @@
             else:
                 ui.write(' %-*s   %s\n' % (m, f, h[f]))
 
+        exts = list(extensions.extensions())
+        if exts:
+            ui.write(_('\nenabled extensions:\n\n'))
+            maxlength = 0
+            exthelps = []
+            for ename, ext in exts:
+                doc = (ext.__doc__ or _('(no help text available)'))
+                ename = ename.split('.')[-1]
+                maxlength = max(len(ename), maxlength)
+                exthelps.append((ename, doc.splitlines(0)[0].strip()))
+            for ename, text in exthelps:
+                ui.write(_(' %s   %s\n') % (ename.ljust(maxlength), text))
+
         if not ui.quiet:
             addglobalopts(True)
 
@@ -1538,7 +1553,7 @@
     if date:
         opts['date'] = util.parsedate(date)
 
-    if opts.get('exact') or not opts['force']:
+    if opts.get('exact') or not opts.get('force'):
         cmdutil.bail_if_changed(repo)
 
     d = opts["base"]
@@ -1633,7 +1648,7 @@
     See pull for valid source format details.
     """
     limit = cmdutil.loglimit(opts)
-    source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
+    source, revs, checkout = hg.parseurl(ui.expandpath(source), opts.get('rev'))
     cmdutil.setremoteconfig(ui, opts)
 
     other = hg.repository(ui, source)
@@ -1668,7 +1683,7 @@
                 other = bundlerepo.bundlerepository(ui, repo.root, fname)
 
         o = other.changelog.nodesbetween(incoming, revs)[0]
-        if opts['newest_first']:
+        if opts.get('newest_first'):
             o.reverse()
         displayer = cmdutil.show_changeset(ui, other, opts)
         count = 0
@@ -1676,7 +1691,7 @@
             if count >= limit:
                 break
             parents = [p for p in other.changelog.parents(n) if p != nullid]
-            if opts['no_merges'] and len(parents) == 2:
+            if opts.get('no_merges') and len(parents) == 2:
                 continue
             count += 1
             displayer.show(changenode=n)
@@ -1719,7 +1734,7 @@
     This will avoid the problem of "xargs" treating single filenames
     that contain white space as multiple filenames.
     """
-    end = opts['print0'] and '\0' or '\n'
+    end = opts.get('print0') and '\0' or '\n'
     rev = opts.get('rev') or None
 
     ret = 1
@@ -1728,7 +1743,7 @@
     for abs in repo[rev].walk(m):
         if not rev and abs not in repo.dirstate:
             continue
-        if opts['fullpath']:
+        if opts.get('fullpath'):
             ui.write(os.path.join(repo.root, abs), end)
         else:
             ui.write(((pats and m.rel(abs)) or abs), end)
@@ -1772,8 +1787,8 @@
     limit = cmdutil.loglimit(opts)
     count = 0
 
-    if opts['copies'] and opts['rev']:
-        endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
+    if opts.get('copies') and opts.get('rev'):
+        endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
     else:
         endrev = len(repo)
     rcache = {}
@@ -1812,7 +1827,7 @@
     if opts["date"]:
         df = util.matchdate(opts["date"])
 
-    only_branches = opts['only_branch']
+    only_branches = opts.get('only_branch')
 
     displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
     for st, rev, fns in changeiter:
@@ -1820,9 +1835,9 @@
             changenode = repo.changelog.node(rev)
             parents = [p for p in repo.changelog.parentrevs(rev)
                        if p != nullrev]
-            if opts['no_merges'] and len(parents) == 2:
+            if opts.get('no_merges') and len(parents) == 2:
                 continue
-            if opts['only_merges'] and len(parents) != 2:
+            if opts.get('only_merges') and len(parents) != 2:
                 continue
 
             if only_branches:
@@ -1835,7 +1850,7 @@
                 if not df(changes[2][0]):
                     continue
 
-            if opts['keyword']:
+            if opts.get('keyword'):
                 changes = get(rev)
                 miss = 0
                 for k in [kw.lower() for kw in opts['keyword']]:
@@ -1943,19 +1958,19 @@
     """
     limit = cmdutil.loglimit(opts)
     dest, revs, checkout = hg.parseurl(
-        ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
+        ui.expandpath(dest or 'default-push', dest or 'default'), opts.get('rev'))
     cmdutil.setremoteconfig(ui, opts)
     if revs:
         revs = [repo.lookup(rev) for rev in revs]
 
     other = hg.repository(ui, dest)
     ui.status(_('comparing with %s\n') % util.hidepassword(dest))
-    o = repo.findoutgoing(other, force=opts['force'])
+    o = repo.findoutgoing(other, force=opts.get('force'))
     if not o:
         ui.status(_("no changes found\n"))
         return 1
     o = repo.changelog.nodesbetween(o, revs)[0]
-    if opts['newest_first']:
+    if opts.get('newest_first'):
         o.reverse()
     displayer = cmdutil.show_changeset(ui, repo, opts)
     count = 0
@@ -1963,7 +1978,7 @@
         if count >= limit:
             break
         parents = [p for p in repo.changelog.parents(n) if p != nullid]
-        if opts['no_merges'] and len(parents) == 2:
+        if opts.get('no_merges') and len(parents) == 2:
             continue
         count += 1
         displayer.show(changenode=n)
@@ -2082,7 +2097,7 @@
       Alternatively specify "ssh -C" as your ssh command in your hgrc or
       with the --ssh command line option.
     """
-    source, revs, checkout = hg.parseurl(ui.expandpath(source), opts['rev'])
+    source, revs, checkout = hg.parseurl(ui.expandpath(source), opts.get('rev'))
     cmdutil.setremoteconfig(ui, opts)
 
     other = hg.repository(ui, source)
@@ -2095,8 +2110,8 @@
                       "so a rev cannot be specified.")
             raise util.Abort(error)
 
-    modheads = repo.pull(other, heads=revs, force=opts['force'])
-    return postincoming(ui, repo, modheads, opts['update'], checkout)
+    modheads = repo.pull(other, heads=revs, force=opts.get('force'))
+    return postincoming(ui, repo, modheads, opts.get('update'), checkout)
 
 def push(ui, repo, dest=None, **opts):
     """push changes to the specified destination
@@ -2130,14 +2145,14 @@
     feature is explicitly enabled on the remote Mercurial server.
     """
     dest, revs, checkout = hg.parseurl(
-        ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
+        ui.expandpath(dest or 'default-push', dest or 'default'), opts.get('rev'))
     cmdutil.setremoteconfig(ui, opts)
 
     other = hg.repository(ui, dest)
     ui.status(_('pushing to %s\n') % util.hidepassword(dest))
     if revs:
         revs = [repo.lookup(rev) for rev in revs]
-    r = repo.push(other, opts['force'], revs=revs)
+    r = repo.push(other, opts.get('force'), revs=revs)
     return r == 0
 
 def rawcommit(ui, repo, *pats, **opts):
@@ -2158,7 +2173,7 @@
     message = cmdutil.logmessage(opts)
 
     files = cmdutil.match(repo, pats, opts).files()
-    if opts['files']:
+    if opts.get('files'):
         files += open(opts['files']).read().splitlines()
 
     parents = [repo.lookup(p) for p in opts['parent']]
@@ -2327,15 +2342,15 @@
             raise util.Abort(_("you can't specify a revision and a date"))
         opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
 
-    if not pats and not opts['all']:
+    if not pats and not opts.get('all'):
         raise util.Abort(_('no files or directories specified; '
                            'use --all to revert the whole repo'))
 
     parent, p2 = repo.dirstate.parents()
-    if not opts['rev'] and p2 != nullid:
+    if not opts.get('rev') and p2 != nullid:
         raise util.Abort(_('uncommitted merge - please provide a '
                            'specific revision'))
-    ctx = repo[opts['rev']]
+    ctx = repo[opts.get('rev')]
     node = ctx.node()
     mf = ctx.manifest()
     if node == parent:
@@ -2417,7 +2432,7 @@
             target = repo.wjoin(abs)
             def handle(xlist, dobackup):
                 xlist[0].append(abs)
-                if dobackup and not opts['no_backup'] and util.lexists(target):
+                if dobackup and not opts.get('no_backup') and util.lexists(target):
                     bakname = "%s.orig" % rel
                     ui.note(_('saving current version of %s as %s\n') %
                             (rel, bakname))
@@ -2638,11 +2653,11 @@
 
     node1, node2 = cmdutil.revpair(repo, opts.get('rev'))
     cwd = (pats and repo.getcwd()) or ''
-    end = opts['print0'] and '\0' or '\n'
+    end = opts.get('print0') and '\0' or '\n'
     copy = {}
     states = 'modified added removed deleted unknown ignored clean'.split()
     show = [k for k in states if opts[k]]
-    if opts['all']:
+    if opts.get('all'):
         show += ui.quiet and (states[:4] + ['clean']) or states
     if not show:
         show = ui.quiet and states[:4] or states[:5]
@@ -2651,7 +2666,7 @@
                        'ignored' in show, 'clean' in show, 'unknown' in show)
     changestates = zip(states, 'MAR!?IC', stat)
 
-    if (opts['all'] or opts['copies']) and not opts['no_status']:
+    if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
         ctxn = repo[nullid]
         ctx1 = repo[node1]
         ctx2 = repo[node2]
@@ -2668,7 +2683,7 @@
     for state, char, files in changestates:
         if state in show:
             format = "%s %%s%s" % (char, end)
-            if opts['no_status']:
+            if opts.get('no_status'):
                 format = "%%s%s" % end
 
             for f in files:
@@ -2704,13 +2719,13 @@
     for n in names:
         if n in ['tip', '.', 'null']:
             raise util.Abort(_('the name \'%s\' is reserved') % n)
-    if opts['rev'] and opts['remove']:
+    if opts.get('rev') and opts.get('remove'):
         raise util.Abort(_("--rev and --remove are incompatible"))
-    if opts['rev']:
+    if opts.get('rev'):
         rev_ = opts['rev']
-    message = opts['message']
-    if opts['remove']:
-        expectedtype = opts['local'] and 'local' or 'global'
+    message = opts.get('message')
+    if opts.get('remove'):
+        expectedtype = opts.get('local') and 'local' or 'global'
         for n in names:
             if not repo.tagtype(n):
                 raise util.Abort(_('tag \'%s\' does not exist') % n)
@@ -2720,7 +2735,7 @@
         rev_ = nullid
         if not message:
             message = _('Removed tag %s') % ', '.join(names)
-    elif not opts['force']:
+    elif not opts.get('force'):
         for n in names:
             if n in repo.tags():
                 raise util.Abort(_('tag \'%s\' already exists '
@@ -2738,7 +2753,7 @@
     if date:
         date = util.parsedate(date)
 
-    repo.tag(names, r, message, opts['local'], opts['user'], date)
+    repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
 
 def tags(ui, repo):
     """list repository tags
@@ -2808,7 +2823,7 @@
     finally:
         del lock
 
-    return postincoming(ui, repo, modheads, opts['update'], None)
+    return postincoming(ui, repo, modheads, opts.get('update'), None)
 
 def update(ui, repo, node=None, rev=None, clean=False, date=None):
     """update working directory
--- a/mercurial/dirstate.py	Sat Oct 18 20:25:45 2008 +0200
+++ b/mercurial/dirstate.py	Sat Oct 18 20:39:08 2008 +0200
@@ -205,7 +205,7 @@
         if not st:
             return
 
-        p = parsers.parse_dirstate(self._map, self._copymap, st);
+        p = parsers.parse_dirstate(self._map, self._copymap, st)
         if not self._dirtypl:
             self._pl = p
 
--- a/mercurial/parsers.c	Sat Oct 18 20:25:45 2008 +0200
+++ b/mercurial/parsers.c	Sat Oct 18 20:39:08 2008 +0200
@@ -137,6 +137,7 @@
 /* msvc 6.0 has problems */
 #  define inline __inline
 typedef unsigned long uint32_t;
+typedef unsigned __int64 uint64_t;
 # else
 #  include <stdint.h>
 # endif
--- a/mercurial/util.py	Sat Oct 18 20:25:45 2008 +0200
+++ b/mercurial/util.py	Sat Oct 18 20:39:08 2008 +0200
@@ -51,18 +51,22 @@
 
 try:
     import subprocess
+    closefds = os.name == 'posix'
     def popen2(cmd, mode='t', bufsize=-1):
-        p = subprocess.Popen(cmd, shell=True, bufsize=bufsize, close_fds=True,
+        p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
+                             close_fds=closefds,
                              stdin=subprocess.PIPE, stdout=subprocess.PIPE)
         return p.stdin, p.stdout
     def popen3(cmd, mode='t', bufsize=-1):
-        p = subprocess.Popen(cmd, shell=True, bufsize=bufsize, close_fds=True,
+        p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
+                             close_fds=closefds,
                              stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE)
         return p.stdin, p.stdout, p.stderr
     def Popen3(cmd, capturestderr=False, bufsize=-1):
         stderr = capturestderr and subprocess.PIPE or None
-        p = subprocess.Popen(cmd, shell=True, bufsize=bufsize, close_fds=True,
+        p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
+                             close_fds=closefds,
                              stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                              stderr=stderr)
         p.fromchild = p.stdout
--- a/templates/coal/graph.tmpl	Sat Oct 18 20:25:45 2008 +0200
+++ b/templates/coal/graph.tmpl	Sat Oct 18 20:39:08 2008 +0200
@@ -40,7 +40,7 @@
 | {changenav%navgraphentry}
 </div>
 
-<div id="noscript">The revision graph only works with JavaScript-enabled browsers.</div>
+<noscript>The revision graph only works with JavaScript-enabled browsers.</noscript>
 
 <div id="wrapper">
 <ul id="nodebgs"></ul>
@@ -52,8 +52,6 @@
 <script type="text/javascript">
 <!-- hide script content
 
-document.getElementById('noscript').style.display = 'none';
-
 var data = {jsdata|json};
 var graph = new Graph();
 graph.scale({bg_height});
--- a/templates/gitweb/graph.tmpl	Sat Oct 18 20:25:45 2008 +0200
+++ b/templates/gitweb/graph.tmpl	Sat Oct 18 20:39:08 2008 +0200
@@ -32,7 +32,7 @@
 
 <div class="title">&nbsp;</div>
 
-<div id="noscript">The revision graph only works with JavaScript-enabled browsers.</div>
+<noscript>The revision graph only works with JavaScript-enabled browsers.</noscript>
 
 <div id="wrapper">
 <ul id="nodebgs"></ul>
@@ -44,8 +44,6 @@
 <script>
 <!-- hide script content
 
-document.getElementById('noscript').style.display = 'none';
-
 var data = {jsdata|json};
 var graph = new Graph();
 graph.scale({bg_height});
--- a/templates/graph.tmpl	Sat Oct 18 20:25:45 2008 +0200
+++ b/templates/graph.tmpl	Sat Oct 18 20:39:08 2008 +0200
@@ -26,7 +26,7 @@
 </p>
 </form>
 
-<div id="noscript">The revision graph only works with JavaScript-enabled browsers.</div>
+<noscript>The revision graph only works with JavaScript-enabled browsers.</noscript>
 
 <div id="wrapper">
 <ul id="nodebgs"></ul>
@@ -38,8 +38,6 @@
 <script type="text/javascript">
 <!-- hide script content
 
-document.getElementById('noscript').style.display = 'none';
-
 var data = {jsdata|json};
 var graph = new Graph();
 graph.scale({bg_height});
--- a/tests/test-extension.out	Sat Oct 18 20:25:45 2008 +0200
+++ b/tests/test-extension.out	Sat Oct 18 20:39:08 2008 +0200
@@ -33,6 +33,10 @@
  debugfoobar:
       yet another debug command
 
+enabled extensions:
+
+ debugextension   only debugcommands
+
 special help topics:
  dates             Date Formats
  patterns          File Name Patterns
Binary file tests/test-hgweb-commands.out has changed
--- a/tests/test-keyword.out	Sat Oct 18 20:25:45 2008 +0200
+++ b/tests/test-keyword.out	Sat Oct 18 20:39:08 2008 +0200
@@ -51,6 +51,12 @@
  kwfiles    print files currently configured for keyword expansion
  kwshrink   revert expanded keywords in working directory
 
+enabled extensions:
+
+ keyword   keyword expansion in local repositories
+ mq        patch management and development
+ notify    hook extension to email notifications on commits/pushes
+
 use "hg -v help keyword" to show aliases and global options
 % hg kwdemo
 [extensions]
--- a/tests/test-mq.out	Sat Oct 18 20:25:45 2008 +0200
+++ b/tests/test-mq.out	Sat Oct 18 20:39:08 2008 +0200
@@ -51,6 +51,10 @@
  qunapplied   print the patches not yet applied
  strip        strip a revision and all its descendants from the repository
 
+enabled extensions:
+
+ mq   patch management and development
+
 use "hg -v help mq" to show aliases and global options
 adding a
 updating working directory
--- a/tests/test-notify.out	Sat Oct 18 20:25:45 2008 +0200
+++ b/tests/test-notify.out	Sat Oct 18 20:39:08 2008 +0200
@@ -1,4 +1,61 @@
-notify extension - No help text available
+notify extension - hook extension to email notifications on commits/pushes
+
+Subscriptions can be managed through hgrc. Default mode is to print
+messages to stdout, for testing and configuring.
+
+To use, configure notify extension and enable in hgrc like this:
+
+   [extensions]
+   hgext.notify =
+
+   [hooks]
+   # one email for each incoming changeset
+   incoming.notify = python:hgext.notify.hook
+   # batch emails when many changesets incoming at one time
+   changegroup.notify = python:hgext.notify.hook
+
+   [notify]
+   # config items go in here
+
+ config items:
+
+ REQUIRED:
+   config = /path/to/file # file containing subscriptions
+
+ OPTIONAL:
+   test = True            # print messages to stdout for testing
+   strip = 3              # number of slashes to strip for url paths
+   domain = example.com   # domain to use if committer missing domain
+   style = ...            # style file to use when formatting email
+   template = ...         # template to use when formatting email
+   incoming = ...         # template to use when run as incoming hook
+   changegroup = ...      # template when run as changegroup hook
+   maxdiff = 300          # max lines of diffs to include (0=none, -1=all)
+   maxsubject = 67        # truncate subject line longer than this
+   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)
+   [email]
+   from = user@host.com   # email address to send as if none given
+   [web]
+   baseurl = http://hgserver/... # root of hg web site for browsing commits
+
+ notify config file has same format as regular hgrc. it has two
+ sections so you can express subscriptions in whatever way is handier
+ for you.
+
+   [usersubs]
+   # key is subscriber email, value is ","-separated list of glob patterns
+   user@host = pattern
+
+   [reposubs]
+   # key is glob pattern, value is ","-separated list of subscriber emails
+   pattern = user@host
+
+ glob patterns are matched against path to repo root.
+
+ if you like, you can put notify config file in repo that users can
+ push changes to, they can manage their own subscriptions.
 
 no commands defined
 % commit
--- a/tests/test-qrecord.out	Sat Oct 18 20:25:45 2008 +0200
+++ b/tests/test-qrecord.out	Sat Oct 18 20:39:08 2008 +0200
@@ -21,6 +21,10 @@
  status     show changed files in the working directory
  update     update working directory
 
+enabled extensions:
+
+ record   interactive change selection during commit or qrefresh
+
 use "hg help" for the full list of commands or "hg -v" for details
 % help (mq present)
 hg qrecord [OPTION]... PATCH [FILE]...
--- a/tests/test-rebase-parameters	Sat Oct 18 20:25:45 2008 +0200
+++ b/tests/test-rebase-parameters	Sat Oct 18 20:39:08 2008 +0200
@@ -64,6 +64,9 @@
 hg update -C 5
 hg rebase 2>&1 | sed 's/\(saving bundle to \).*/\1/'
 
+echo "% Try to rollback after a rebase (fail)"
+hg rollback
+
 createrepo > /dev/null 2>&1
 echo
 echo "% Rebase with base == '.' => same as no arguments (from 3 onto 7)"
--- a/tests/test-rebase-parameters.out	Sat Oct 18 20:25:45 2008 +0200
+++ b/tests/test-rebase-parameters.out	Sat Oct 18 20:39:08 2008 +0200
@@ -126,6 +126,8 @@
 adding file changes
 added 5 changesets with 5 changes to 5 files
 rebase completed
+% Try to rollback after a rebase (fail)
+no rollback information available
 
 % Rebase with base == '.' => same as no arguments (from 3 onto 7)
 3 files updated, 0 files merged, 3 files removed, 0 files unresolved