changeset 3241:a184cd0c2db9

Merge with upstream
author Brendan Cully <brendan@kublai.com>
date Tue, 03 Oct 2006 12:14:33 -0700
parents e0069e7fe419 (diff) 8d4855fd9d7b (current diff)
children 1539f788e913
files mercurial/context.py mercurial/localrepo.py
diffstat 53 files changed, 288 insertions(+), 266 deletions(-) [+]
line wrap: on
line diff
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -5,10 +5,8 @@ include hgeditor rewrite-log
 include tests/README tests/*.py tests/test-*[a-z0-9] tests/*.out
 prune tests/*.err
 include *.txt
-include templates/map templates/map-*[a-z0-9]
-include templates/*.tmpl
-include templates/static/*
 include doc/README doc/Makefile doc/gendoc.py doc/*.txt doc/*.html doc/*.[0-9]
+recursive-include templates *
 recursive-include contrib *
 recursive-include hgext *
 include README
--- a/contrib/churn.py
+++ b/contrib/churn.py
@@ -58,7 +58,7 @@ def __gather(ui, repo, node1, node2):
 
     for f in added:
         lines += dirtywork(f, None, mmap2)
-        
+
     for f in removed:
         lines += dirtywork(f, mmap1, None)
 
@@ -72,7 +72,7 @@ def __gather(ui, repo, node1, node2):
 
 def gather_stats(ui, repo, amap, revs=None, progress=False):
     stats = {}
-    
+
     cl    = repo.changelog
 
     if not revs:
@@ -117,7 +117,7 @@ def gather_stats(ui, repo, amap, revs=No
 
 def churn(ui, repo, **opts):
     "Graphs the number of lines changed"
-    
+
     def pad(s, l):
         if len(s) < l:
             return s + " " * (l-len(s))
@@ -125,7 +125,7 @@ def churn(ui, repo, **opts):
 
     def graph(n, maximum, width, char):
         n = int(n * width / float(maximum))
-        
+
         return char * (n)
 
     def get_aliases(f):
@@ -137,7 +137,7 @@ def churn(ui, repo, **opts):
             aliases[alias] = actual
 
         return aliases
-    
+
     amap = {}
     aliases = opts.get('aliases')
     if aliases:
--- a/hgext/fetch.py
+++ b/hgext/fetch.py
@@ -63,7 +63,7 @@ def fetch(ui, repo, source='default', **
             revs = [other.lookup(rev) for rev in opts['rev']]
         modheads = repo.pull(other, heads=revs, lock=lock)
         return postincoming(other, modheads)
-        
+
     parent, p2 = repo.dirstate.parents()
     if parent != repo.changelog.tip():
         raise util.Abort(_('working dir not at tip '
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -130,7 +130,7 @@ class queue:
         for c in bad_chars:
             if c in guard:
                 return _('invalid character in guard %r: %r') % (guard, c)
-        
+
     def set_active(self, guards):
         for guard in guards:
             bad = self.check_guard(guard)
@@ -172,7 +172,7 @@ class queue:
         self.full_series[idx] = drop + ''.join([' #' + g for g in guards])
         self.parse_series()
         self.series_dirty = True
-        
+
     def pushable(self, idx):
         if isinstance(idx, str):
             idx = self.series.index(idx)
@@ -724,7 +724,7 @@ class queue:
                 return (i, a.rev, a.name)
         return None
 
-    # if the exact patch name does not exist, we try a few 
+    # if the exact patch name does not exist, we try a few
     # variations.  If strict is passed, we try only #1
     #
     # 1) a number to indicate an offset in the series file
@@ -1638,7 +1638,7 @@ def guard(ui, repo, *args, **opts):
       hg qguard -- -foo
 
     To set guards on another patch:
-      hg qguard other.patch +2.6.17 -stable    
+      hg qguard other.patch +2.6.17 -stable
     '''
     def status(idx):
         guards = q.series_guards[idx] or ['unguarded']
@@ -1765,7 +1765,7 @@ def rename(ui, repo, patch, name=None, *
         absdest = q.join(name)
     if os.path.exists(absdest):
         raise util.Abort(_('%s already exists') % absdest)
-    
+
     if name in q.series:
         raise util.Abort(_('A patch named %s already exists in the series file') % name)
 
@@ -1862,7 +1862,7 @@ def select(ui, repo, *args, **opts):
 
     With no arguments, prints the currently active guards.
     With one argument, sets the active guard.
-    
+
     Use -n/--none to deactivate guards (no other arguments needed).
     When no guards are active, patches with positive guards are skipped
     and patches with negative guards are pushed.
@@ -1952,7 +1952,7 @@ def reposetup(ui, repo):
                 parent = revlog.hex(self.dirstate.parents()[0])
                 if parent in [s.rev for s in self.mq.applied]:
                     raise util.Abort(errmsg)
-            
+
         def commit(self, *args, **opts):
             if len(args) >= 6:
                 force = args[5]
@@ -1968,7 +1968,7 @@ def reposetup(ui, repo):
             if self.mq.applied and not force:
                 raise util.Abort(_('source has mq patches applied'))
             return super(mqrepo, self).push(remote, force, revs)
-            
+
         def tags(self):
             if self.tagscache:
                 return self.tagscache
--- a/mercurial/changelog.py
+++ b/mercurial/changelog.py
@@ -10,46 +10,91 @@ from i18n import gettext as _
 from demandload import demandload
 demandload(globals(), "os time util")
 
+def _string_escape(text):
+    """
+    >>> d = {'nl': chr(10), 'bs': chr(92), 'cr': chr(13), 'nul': chr(0)}
+    >>> s = "ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d
+    >>> s
+    'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n'
+    >>> res = _string_escape(s)
+    >>> s == _string_unescape(res)
+    True
+    """
+    # subset of the string_escape codec
+    text = text.replace('\\', '\\\\').replace('\n', '\\n').replace('\r', '\\r')
+    return text.replace('\0', '\\0')
+
+def _string_unescape(text):
+    return text.decode('string_escape')
+
 class changelog(revlog):
     def __init__(self, opener, defversion=REVLOGV0):
         revlog.__init__(self, opener, "00changelog.i", "00changelog.d",
                         defversion)
 
+    def decode_extra(self, text):
+        extra = {}
+        for l in text.split('\0'):
+            if not l:
+                continue
+            k, v = _string_unescape(l).split(':', 1)
+            extra[k] = v
+        return extra
+
+    def encode_extra(self, d):
+        items = [_string_escape(":".join(t)) for t in d.iteritems()]
+        return "\0".join(items)
+
     def extract(self, text):
         """
         format used:
-        nodeid\n  : manifest node in ascii
-        user\n    : user, no \n or \r allowed
-        time tz\n : date (time is int or float, timezone is int)
-        files\n\n : files modified by the cset, no \n or \r allowed
-        (.*)      : comment (free text, ideally utf-8)
+        nodeid\n        : manifest node in ascii
+        user\n          : user, no \n or \r allowed
+        time tz extra\n : date (time is int or float, timezone is int)
+                        : extra is metadatas, encoded and separated by '\0'
+                        : older versions ignore it
+        files\n\n       : files modified by the cset, no \n or \r allowed
+        (.*)            : comment (free text, ideally utf-8)
+
+        changelog v0 doesn't use extra
         """
         if not text:
             return (nullid, "", (0, 0), [], "")
         last = text.index("\n\n")
         desc = text[last + 2:]
-        l = text[:last].splitlines()
+        l = text[:last].split('\n')
         manifest = bin(l[0])
         user = l[1]
-        date = l[2].split(' ')
-        time = float(date.pop(0))
-        try:
-            # various tools did silly things with the time zone field.
-            timezone = int(date[0])
-        except:
-            timezone = 0
+
+        extra_data = l[2].split(' ', 2)
+        if len(extra_data) != 3:
+            time = float(extra_data.pop(0))
+            try:
+                # various tools did silly things with the time zone field.
+                timezone = int(extra_data[0])
+            except:
+                timezone = 0
+            extra = {}
+        else:
+            time, timezone, extra = extra_data
+            time, timezone = float(time), int(timezone)
+            extra = self.decode_extra(extra)
         files = l[3:]
-        return (manifest, user, (time, timezone), files, desc)
+        return (manifest, user, (time, timezone), files, desc, extra)
 
     def read(self, node):
         return self.extract(self.revision(node))
 
     def add(self, manifest, list, desc, transaction, p1=None, p2=None,
-                  user=None, date=None):
+                  user=None, date=None, extra={}):
+
         if date:
             parseddate = "%d %d" % util.parsedate(date)
         else:
             parseddate = "%d %d" % util.makedate()
+        if extra:
+            extra = self.encode_extra(extra)
+            parseddate = "%s %s" % (parseddate, extra)
         list.sort()
         l = [hex(manifest), user, parseddate] + list + ["", desc]
         text = "\n".join(l)
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2502,7 +2502,7 @@ def status(ui, repo, *pats, **opts):
     """
 
     all = opts['all']
-    
+
     files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
     cwd = (pats and repo.getcwd()) or ''
     modified, added, removed, deleted, unknown, ignored, clean = [
@@ -3236,7 +3236,7 @@ def load_extensions(ui):
             if t in table:
                 ui.warn(_("module %s overrides %s\n") % (name, t))
         table.update(cmdtable)
-    
+
 def dispatch(args):
     for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
         num = getattr(signal, name, None)
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -5,13 +5,10 @@
 # This software may be used and distributed according to the terms
 # of the GNU General Public License, incorporated herein by reference.
 
-from demandload import *
 from node import *
-demandload(globals(), 'bdiff')
-
-from node import *
+from i18n import gettext as _
 from demandload import demandload
-demandload(globals(), "ancestor util")
+demandload(globals(), "ancestor bdiff repo revlog util")
 
 class changectx(object):
     """A changecontext object makes access to data related to a particular
@@ -136,10 +133,13 @@ class filectx(object):
             self._changeid = self._filelog.linkrev(self._filenode)
             return self._changeid
         elif name == '_filenode':
-            if hasattr(self, "_fileid"):
-                self._filenode = self._filelog.lookup(self._fileid)
-            else:
-                self._filenode = self._changectx.filenode(self._path)
+            try:
+                if hasattr(self, "_fileid"):
+                    self._filenode = self._filelog.lookup(self._fileid)
+                else:
+                    self._filenode = self._changectx.filenode(self._path)
+            except revlog.RevlogError, inst:
+                raise repo.LookupError(str(inst))
             return self._filenode
         elif name == '_filerev':
             self._filerev = self._filelog.rev(self._filenode)
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -206,7 +206,7 @@ class dirstate(object):
             self.dirs = {}
             for f in self.map:
                 self.updatedirs(f, 1)
-        
+
     def updatedirs(self, path, delta):
         if self.dirs is not None:
             for c in strutil.findall(path, '/'):
--- a/mercurial/filelog.py
+++ b/mercurial/filelog.py
@@ -7,7 +7,7 @@
 
 from revlog import *
 from demandload import *
-demandload(globals(), "bdiff os")
+demandload(globals(), "os")
 
 class filelog(revlog):
     def __init__(self, opener, path, defversion=REVLOG_DEFAULT_VERSION):
@@ -84,72 +84,3 @@ class filelog(revlog):
             return t2 != text
 
         return revlog.cmp(self, node, text)
-
-    def annotate(self, node):
-
-        def decorate(text, rev):
-            return ([rev] * len(text.splitlines()), text)
-
-        def pair(parent, child):
-            for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]):
-                child[0][b1:b2] = parent[0][a1:a2]
-            return child
-
-        # find all ancestors
-        needed = {(self, node):1}
-        files = [self]
-        visit = [(self, node)]
-        while visit:
-            f, n = visit.pop(0)
-            rn = f.renamed(n)
-            if rn:
-                f, n = rn
-                f = filelog(self.opener, f, self.defversion)
-                files.insert(0, f)
-                if (f, n) not in needed:
-                    needed[(f, n)] = 1
-                else:
-                    needed[(f, n)] += 1
-            for p in f.parents(n):
-                if p == nullid:
-                    continue
-                if (f, p) not in needed:
-                    needed[(f, p)] = 1
-                    visit.append((f, p))
-                else:
-                    # count how many times we'll use this
-                    needed[(f, p)] += 1
-
-        # sort by revision (per file) which is a topological order
-        visit = []
-        for f in files:
-            fn = [(f.rev(n[1]), f, n[1]) for n in needed.keys() if n[0] == f]
-            fn.sort()
-            visit.extend(fn)
-        hist = {}
-
-        for i in range(len(visit)):
-            r, f, n = visit[i]
-            curr = decorate(f.read(n), f.linkrev(n))
-            if r == -1:
-                continue
-            parents = f.parents(n)
-            # follow parents across renames
-            if r < 1 and i > 0:
-                j = i
-                while j > 0 and visit[j][1] == f:
-                    j -= 1
-                parents = (visit[j][2],)
-                f = visit[j][1]
-            else:
-                parents = f.parents(n)
-            for p in parents:
-                if p != nullid:
-                    curr = pair(hist[p], curr)
-                    # trim the history of unneeded revs
-                    needed[(f, p)] -= 1
-                    if not needed[(f, p)]:
-                        del hist[p]
-            hist[n] = curr
-
-        return zip(hist[n][0], hist[n][1].splitlines(1))
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -149,7 +149,8 @@ class hgweb(object):
             yield diffblock(mdiff.unidiff(to, date1, tn, date2, f,
                                           opts=diffopts), f, tn)
 
-    def changelog(self, pos, shortlog=False):
+    def changelog(self, ctx, shortlog=False):
+        pos = ctx.rev()
         def changenav(**map):
             def seq(factor, maxchanges=None):
                 if maxchanges:
@@ -209,7 +210,6 @@ class hgweb(object):
 
         maxchanges = shortlog and self.maxshortchanges or self.maxchanges
         cl = self.repo.changelog
-        mf = cl.read(cl.tip())[0]
         count = cl.count()
         start = max(0, pos - maxchanges + 1)
         end = min(count, start + maxchanges)
@@ -274,8 +274,7 @@ class hgweb(object):
                      node=hex(cl.tip()),
                      entries=changelist)
 
-    def changeset(self, nodeid):
-        ctx = self.repo.changectx(nodeid)
+    def changeset(self, ctx):
         n = ctx.node()
         parents = ctx.parents()
         p1 = parents[0].node()
@@ -302,11 +301,10 @@ class hgweb(object):
                      desc=ctx.description(),
                      date=ctx.date(),
                      files=files,
-                     archives=self.archivelist(nodeid))
+                     archives=self.archivelist(hex(n)))
 
     def filelog(self, fctx):
         f = fctx.path()
-        cl = self.repo.changelog
         fl = fctx.filelog()
         count = fl.count()
 
@@ -505,7 +503,6 @@ class hgweb(object):
                     break;
 
                 c = cl.read(n)
-                m = c[0]
                 t = c[2]
 
                 yield self.t("tagentry",
@@ -552,21 +549,21 @@ class hgweb(object):
                  node = hex(self.repo.changelog.tip()),
                  archives=self.archivelist("tip"))
 
-    def filediff(self, file, changeset):
-        ctx = self.repo.changectx(changeset)
-        n = ctx.node()
-        parents = ctx.parents()
+    def filediff(self, fctx):
+        n = fctx.node()
+        path = fctx.path()
+        parents = fctx.changectx().parents()
         p1 = parents[0].node()
 
         def diff(**map):
-            yield self.diff(p1, n, [file])
+            yield self.diff(p1, n, [path])
 
         yield self.t("filediff",
-                     file=file,
+                     file=path,
                      node=hex(n),
-                     rev=ctx.rev(),
+                     rev=fctx.rev(),
                      parent=self.siblings(parents),
-                     child=self.siblings(ctx.children()),
+                     child=self.siblings(fctx.children()),
                      diff=diff)
 
     archive_specs = {
@@ -648,25 +645,6 @@ class hgweb(object):
                         form[name] = value
                     del form[k]
 
-            if form.has_key('manifest'):
-                changeid = req.form['manifest'][0]
-                try:
-                    req.changectx = self.repo.changectx(changeid)
-                except hg.RepoError:
-                    man = self.repo.manifest
-                    mn = man.lookup(changeid)
-                    req.changectx = self.repo.changectx(man.linkrev(mn))
-
-            if form.has_key('filenode'):
-                changeid = req.form['filenode'][0]
-                path = self.cleanpath(req.form['file'][0])
-                try:
-                    req.changectx = self.repo.changectx(changeid)
-                    req.filectx = req.changectx.filectx(path)
-                except hg.RepoError:
-                    req.filectx = self.repo.filectx(path, fileid=changeid)
-                    req.changectx = req.filectx.changectx()
-
         self.refresh()
 
         expand_form(req.form)
@@ -710,6 +688,34 @@ class hgweb(object):
         else:
             req.write(self.t("error"))
 
+    def changectx(self, req):
+        if req.form.has_key('node'):
+            changeid = req.form['node'][0]
+        else:
+            changeid = req.form['manifest'][0]
+        try:
+            ctx = self.repo.changectx(changeid)
+        except hg.RepoError:
+            man = self.repo.manifest
+            mn = man.lookup(changeid)
+            ctx = self.repo.changectx(man.linkrev(mn))
+
+        return ctx
+
+    def filectx(self, req):
+        path = self.cleanpath(req.form['file'][0])
+        if req.form.has_key('node'):
+            changeid = req.form['node'][0]
+        else:
+            changeid = req.form['filenode'][0]
+        try:
+            ctx = self.repo.changectx(changeid)
+            fctx = ctx.filectx(path)
+        except hg.RepoError:
+            fctx = self.repo.filectx(path, fileid=changeid)
+
+        return fctx
+
     def stripes(self, parity):
         "make horizontal stripes for easier reading"
         if self.stripecount:
@@ -717,35 +723,31 @@ class hgweb(object):
         else:
             return 0
 
-    def do_changelog(self, req):
-        hi = self.repo.changelog.count() - 1
-        if req.form.has_key('rev'):
-            hi = req.form['rev'][0]
+    def do_changelog(self, req, shortlog = False):
+        if req.form.has_key('node'):
+            ctx = self.changectx(req)
+        else:
+            if req.form.has_key('rev'):
+                hi = req.form['rev'][0]
+            else:
+                hi = self.repo.changelog.count() - 1
             try:
-                hi = self.repo.changelog.rev(self.repo.lookup(hi))
+                ctx = self.repo.changectx(hi)
             except hg.RepoError:
                 req.write(self.search(hi)) # XXX redirect to 404 page?
                 return
 
-        req.write(self.changelog(hi))
+        req.write(self.changelog(ctx, shortlog = shortlog))
 
     def do_shortlog(self, req):
-        hi = self.repo.changelog.count() - 1
-        if req.form.has_key('rev'):
-            hi = req.form['rev'][0]
-            try:
-                hi = self.repo.changelog.rev(self.repo.lookup(hi))
-            except hg.RepoError:
-                req.write(self.search(hi)) # XXX redirect to 404 page?
-                return
-
-        req.write(self.changelog(hi, shortlog = True))
+        self.do_changelog(req, shortlog = True)
 
     def do_changeset(self, req):
-        req.write(self.changeset(req.form['node'][0]))
+        ctx = self.repo.changectx(req.form['node'][0])
+        req.write(self.changeset(ctx))
 
     def do_manifest(self, req):
-        req.write(self.manifest(req.changectx,
+        req.write(self.manifest(self.changectx(req),
                                 self.cleanpath(req.form['path'][0])))
 
     def do_tags(self, req):
@@ -755,17 +757,16 @@ class hgweb(object):
         req.write(self.summary())
 
     def do_filediff(self, req):
-        req.write(self.filediff(self.cleanpath(req.form['file'][0]),
-                                req.form['node'][0]))
+        req.write(self.filediff(self.filectx(req)))
 
     def do_file(self, req):
-        req.write(self.filerevision(req.filectx))
+        req.write(self.filerevision(self.filectx(req)))
 
     def do_annotate(self, req):
-        req.write(self.fileannotate(req.filectx))
+        req.write(self.fileannotate(self.filectx(req)))
 
     def do_filelog(self, req):
-        req.write(self.filelog(req.filectx))
+        req.write(self.filelog(self.filectx(req)))
 
     def do_heads(self, req):
         resp = " ".join(map(hex, self.repo.heads())) + "\n"
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -21,6 +21,7 @@ class hgwebdir(object):
             return [(name.strip(os.sep), path) for name, path in items]
 
         self.motd = ""
+        self.style = ""
         self.repos_sorted = ('name', False)
         if isinstance(config, (list, tuple)):
             self.repos = cleannames(config)
@@ -32,8 +33,11 @@ class hgwebdir(object):
             cp = ConfigParser.SafeConfigParser()
             cp.read(config)
             self.repos = []
-            if cp.has_section('web') and cp.has_option('web', 'motd'):
-                self.motd = cp.get('web', 'motd')
+            if cp.has_section('web'):
+                if cp.has_option('web', 'motd'):
+                    self.motd = cp.get('web', 'motd')
+                if cp.has_option('web', 'style'):
+                    self.style = cp.get('web', 'style')
             if cp.has_section('paths'):
                 self.repos.extend(cleannames(cp.items('paths')))
             if cp.has_section('collections'):
@@ -66,6 +70,15 @@ class hgwebdir(object):
             yield tmpl("footer", motd=self.motd, **map)
 
         m = os.path.join(templater.templatepath(), "map")
+        style = self.style
+        if req.form.has_key('style'):
+            style = req.form['style'][0]
+        if style != "":
+            b = os.path.basename("map-" + style)
+            p = os.path.join(templater.templatepath(), b)
+            if os.path.isfile(p):
+                m = p
+
         tmpl = templater.templater(m, templater.common_filters,
                                    defaults={"header": header,
                                              "footer": footer})
--- a/mercurial/httprepo.py
+++ b/mercurial/httprepo.py
@@ -165,7 +165,7 @@ class httprepository(remoterepository):
                                                proxyuser, proxypasswd or ''),
                     proxypath, proxyquery, proxyfrag))
                 handler = urllib2.ProxyHandler({scheme: proxyurl})
-                ui.debug(_('proxying through http://%s:%s\n') % 
+                ui.debug(_('proxying through http://%s:%s\n') %
                           (proxyhost, proxyport))
 
         # urllib2 takes proxy values from the environment and those
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1763,6 +1763,6 @@ def aftertrans(base):
 
 def instance(ui, path, create):
     return localrepository(ui, util.drop_scheme('file', path), create)
-    
+
 def islocal(path):
     return True
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -53,7 +53,7 @@ class manifest(revlog):
         for f, n in self.parselines(delta):
             deltamap.rawset(f, n)
         return deltamap
-            
+
     def read(self, node):
         if node == nullid: return manifestdict() # don't upset local cache
         if self.mapcache and self.mapcache[0] == node:
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -128,7 +128,7 @@ def readgitpatch(patchname):
             self.op = 'MODIFY'
             self.copymod = False
             self.lineno = 0
-    
+
     # Filter patch for git information
     gitre = re.compile('diff --git a/(.*) b/(.*)')
     pf = file(patchname)
@@ -309,7 +309,6 @@ def updatedir(ui, repo, patches, wlock=N
     copies = []
     removes = []
     cfiles = patches.keys()
-    copts = {'after': False, 'force': False}
     cwd = repo.getcwd()
     if cwd:
         cfiles = [util.pathto(cwd, f) for f in patches.keys()]
--- a/mercurial/repo.py
+++ b/mercurial/repo.py
@@ -9,6 +9,9 @@
 class RepoError(Exception):
     pass
 
+class LookupError(RepoError):
+    pass
+
 class repository(object):
     def capable(self, name):
         '''tell whether repo supports named capability.
--- a/mercurial/sshserver.py
+++ b/mercurial/sshserver.py
@@ -124,7 +124,7 @@ class sshserver(object):
     def client_url(self):
         client = os.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
         return 'remote:ssh:' + client
-        
+
     def do_unbundle(self):
         their_heads = self.getarg()[1].split()
 
--- a/setup.py
+++ b/setup.py
@@ -9,7 +9,7 @@ import sys
 if not hasattr(sys, 'version_info') or sys.version_info < (2, 3):
     raise SystemExit, "Mercurial requires python 2.3 or later."
 
-import glob
+import os
 from distutils.core import setup, Extension
 from distutils.command.install_data import install_data
 
@@ -55,9 +55,9 @@ try:
                 self.includes = []
             else:
                 self.includes = self.includes.split(',')
-            mercurial.packagescan.scan(self.build_lib,'mercurial')
-            mercurial.packagescan.scan(self.build_lib,'mercurial.hgweb')
-            mercurial.packagescan.scan(self.build_lib,'hgext')
+            mercurial.packagescan.scan(self.build_lib, 'mercurial')
+            mercurial.packagescan.scan(self.build_lib, 'mercurial.hgweb')
+            mercurial.packagescan.scan(self.build_lib, 'hgext')
             self.includes += mercurial.packagescan.getmodules()
             build_exe.finalize_options(self)
 except ImportError:
@@ -79,26 +79,24 @@ py2exe_opts = {}
 if py2exe_for_demandload is not None:
     cmdclass['py2exe'] = py2exe_for_demandload
     py2exe_opts['console'] = ['hg']
+
 setup(name='mercurial',
-        version=mercurial.version.get_version(),
-        author='Matt Mackall',
-        author_email='mpm@selenic.com',
-        url='http://selenic.com/mercurial',
-        description='Scalable distributed SCM',
-        license='GNU GPL',
-        packages=['mercurial', 'mercurial.hgweb', 'hgext'],
-        ext_modules=[Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
-                    Extension('mercurial.bdiff', ['mercurial/bdiff.c'])],
-        data_files=[('mercurial/templates',
-                    ['templates/map'] +
-                    glob.glob('templates/map-*') +
-                    glob.glob('templates/*.tmpl')),
-                    ('mercurial/templates/static',
-                    glob.glob('templates/static/*'))],
-        cmdclass=cmdclass,
-        scripts=['hg', 'hgmerge'],
-        options=dict(bdist_mpkg=dict(zipdist=True,
-                                    license='COPYING',
-                                    readme='contrib/macosx/Readme.html',
-                                    welcome='contrib/macosx/Welcome.html')),
-        **py2exe_opts)
+      version=mercurial.version.get_version(),
+      author='Matt Mackall',
+      author_email='mpm@selenic.com',
+      url='http://selenic.com/mercurial',
+      description='Scalable distributed SCM',
+      license='GNU GPL',
+      packages=['mercurial', 'mercurial.hgweb', 'hgext'],
+      ext_modules=[Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
+                   Extension('mercurial.bdiff', ['mercurial/bdiff.c'])],
+      data_files=[(os.path.join('mercurial', root),
+                   [os.path.join(root, file_) for file_ in files])
+                  for root, dirs, files in os.walk('templates')],
+      cmdclass=cmdclass,
+      scripts=['hg', 'hgmerge'],
+      options=dict(bdist_mpkg=dict(zipdist=True,
+                                   license='COPYING',
+                                   readme='contrib/macosx/Readme.html',
+                                   welcome='contrib/macosx/Welcome.html')),
+      **py2exe_opts)
rename from templates/changelog-gitweb.tmpl
rename to templates/gitweb/changelog.tmpl
rename from templates/changelogentry-gitweb.tmpl
rename to templates/gitweb/changelogentry.tmpl
rename from templates/changeset-gitweb.tmpl
rename to templates/gitweb/changeset.tmpl
rename from templates/error-gitweb.tmpl
rename to templates/gitweb/error.tmpl
rename from templates/fileannotate-gitweb.tmpl
rename to templates/gitweb/fileannotate.tmpl
rename from templates/filelog-gitweb.tmpl
rename to templates/gitweb/filelog.tmpl
rename from templates/filerevision-gitweb.tmpl
rename to templates/gitweb/filerevision.tmpl
rename from templates/footer-gitweb.tmpl
rename to templates/gitweb/footer.tmpl
rename from templates/header-gitweb.tmpl
rename to templates/gitweb/header.tmpl
new file mode 100644
--- /dev/null
+++ b/templates/gitweb/index.tmpl
@@ -0,0 +1,23 @@
+#header#
+<title>Mercurial repositories index</title>
+</head>
+<body>
+
+<div class="page_header">
+<a href="http://www.selenic.com/mercurial/" title="Mercurial"><div style="float:right;">Mercurial</div></a>Repositories list
+</div>
+
+<table cellspacing="0">
+    <tr>
+        <td><a href="?sort=#sort_name#">Name</a></td>
+        <td><a href="?sort=#sort_description#">Description</a></td>
+        <td><a href="?sort=#sort_contact#">Contact</a></td>
+        <td><a href="?sort=#sort_lastchange#">Last change</a></td>
+        <td>&nbsp;</td>
+    <tr>
+    #entries%indexentry#
+</table>
+<div class="page_footer">
+</div>
+</body>
+</html>
rename from templates/manifest-gitweb.tmpl
rename to templates/gitweb/manifest.tmpl
rename from templates/search-gitweb.tmpl
rename to templates/gitweb/search.tmpl
rename from templates/shortlog-gitweb.tmpl
rename to templates/gitweb/shortlog.tmpl
rename from templates/summary-gitweb.tmpl
rename to templates/gitweb/summary.tmpl
rename from templates/tags-gitweb.tmpl
rename to templates/gitweb/tags.tmpl
--- a/templates/map-gitweb
+++ b/templates/map-gitweb
@@ -1,24 +1,24 @@
 default = 'summary'
-header = header-gitweb.tmpl
-footer = footer-gitweb.tmpl
-search = search-gitweb.tmpl
-changelog = changelog-gitweb.tmpl
-summary = summary-gitweb.tmpl
-error = error-gitweb.tmpl
+header = gitweb/header.tmpl
+footer = gitweb/footer.tmpl
+search = gitweb/search.tmpl
+changelog = gitweb/changelog.tmpl
+summary = gitweb/summary.tmpl
+error = gitweb/error.tmpl
 naventry = '<a href="?cmd=changelog;rev=#rev#;style=gitweb">#label|escape#</a> '
 navshortentry = '<a href="?cmd=shortlog;rev=#rev#;style=gitweb">#label|escape#</a> '
 filedifflink = '<a href="?cmd=filediff;node=#node#;file=#file|urlescape#;style=gitweb">#file|escape#</a> '
 filenodelink = '<tr class="parity#parity#"><td><a class="list" href="">#file|escape#</a></td><td></td><td class="link"><a href="?f=#node|short#;file=#file|urlescape#;style=gitweb">file</a> | <a href="?fa=#node|short#;file=#file|urlescape#;style=gitweb">annotate</a> | <!-- FIXME: <a href="?fd=#node|short#;file=#file|urlescape#;style=gitweb">diff</a> | --> <a href="?cmd=filelog;filenode=#node|short#;file=#file|urlescape#;style=gitweb">revisions</a></td></tr>'
 fileellipses = '...'
-changelogentry = changelogentry-gitweb.tmpl
-searchentry = changelogentry-gitweb.tmpl
-changeset = changeset-gitweb.tmpl
-manifest = manifest-gitweb.tmpl
+changelogentry = gitweb/changelogentry.tmpl
+searchentry = gitweb/changelogentry.tmpl
+changeset = gitweb/changeset.tmpl
+manifest = gitweb/manifest.tmpl
 manifestdirentry = '<tr class="parity#parity#"><td style="font-family:monospace">drwxr-xr-x</td><td><a href="?mf=#node|short#;path=#path|urlescape#;style=gitweb">#basename|escape#/</a></td><td class="link"><a href="?mf=#node|short#;path=#path|urlescape#;style=gitweb">manifest</a></td></tr>'
 manifestfileentry = '<tr class="parity#parity#"><td style="font-family:monospace">#permissions|permissions#</td><td class="list"><a class="list" href="?f=#node|short#;file=#file|urlescape#;style=gitweb">#basename|escape#</a></td><td class="link"><a href="?f=#node|short#;file=#file|urlescape#;style=gitweb">file</a> | <a href="?fl=#node|short#;file=#file|urlescape#;style=gitweb">revisions</a> | <a href="?fa=#node|short#;file=#file|urlescape#;style=gitweb">annotate</a></td></tr>'
-filerevision = filerevision-gitweb.tmpl
-fileannotate = fileannotate-gitweb.tmpl
-filelog = filelog-gitweb.tmpl
+filerevision = gitweb/filerevision.tmpl
+fileannotate = gitweb/fileannotate.tmpl
+filelog = gitweb/filelog.tmpl
 fileline = '<div style="font-family:monospace" class="parity#parity#"><pre><span class="linenr">   #linenumber#</span> #line|escape#</pre></div>'
 annotateline = '<tr style="font-family:monospace" class="parity#parity#"><td class="linenr" style="text-align: right;"><a href="?fa=#node|short#;file=#file|urlescape#;style=gitweb">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>'
 difflineplus = '<div style="color:#008800;">#line|escape#</div>'
@@ -35,7 +35,7 @@ changelogchild = '<tr><th class="child">
 changesetchild = '<tr><td>child</td><td style="font-family:monospace"><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb">#node|short#</a></td></tr>'
 filerevchild = '<tr><td class="metatag">child:</td><td><a href="?cmd=file;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>'
 fileannotatechild = '<tr><td class="metatag">child:</td><td><a href="?cmd=annotate;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>'
-tags = tags-gitweb.tmpl
+tags = gitweb/tags.tmpl
 tagentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#tag|escape#</b></a></td><td class="link"><a href="?cmd=changeset;node=#node|short#;style=gitweb">changeset</a> | <a href="?cmd=changelog;rev=#node|short#;style=gitweb">changelog</a> |  <a href="?mf=#node|short#;path=/;style=gitweb">manifest</a></td></tr>'
 diffblock = '<pre>#lines#</pre>'
 changelogtag = '<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>'
@@ -44,7 +44,9 @@ filediffparent = '<tr><th class="parent"
 filelogparent = '<tr><td align="right">parent #rev#:&nbsp;</td><td><a href="?cmd=file;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>'
 filediffchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="?cmd=changeset;node=#node#;style=gitweb">#node|short#</a></td></tr>'
 filelogchild = '<tr><td align="right">child #rev#:&nbsp;</td><td><a href="?cmd=file;file=#file|urlescape#;filenode=#node#;style=gitweb">#node|short#</a></td></tr>'
-shortlog = shortlog-gitweb.tmpl
+shortlog = gitweb/shortlog.tmpl
 shortlogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><i>#author#</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><a href="?cmd=changeset;node=#node|short#;style=gitweb">changeset</a> |  <a href="?cmd=manifest;manifest=#node|short#;path=/;style=gitweb">manifest</a></td></tr>'
 filelogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="?cmd=changeset;node=#node|short#;style=gitweb"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><a href="?f=#node|short#;file=#file|urlescape#;style=gitweb">file</a> | <!-- FIXME: <a href="?fd=#node|short#;file=#file|urlescape#;style=gitweb">diff</a> | --> <a href="?fa=#node|short#;file=#file|urlescape#;style=gitweb">annotate</a> #rename%filelogrename#</td></tr>'
-archiveentry = ' | <a href="?ca=#node|short#;type=#type|urlescape#">#type|escape#</a> '
+archiveentry = ' | <a href="#url#?ca=#node|short#;type=#type|urlescape#">#type|escape#</a> '
+indexentry = '<tr class="parity#parity#"><td><a class="list" href="#url#"><b>#name|escape#</b></a></td><td>#description#</td><td>#contact|obfuscate#</td><td class="age">#lastchange|age# ago</td><td class="indexlinks"><a class="rss_logo" href="#url#?cl=tip;style=rss">RSS</a> #archives%archiveentry#</td></tr>' 
+index = gitweb/index.tmpl
--- a/templates/map-raw
+++ b/templates/map-raw
@@ -1,6 +1,6 @@
-header = header-raw.tmpl
+header = raw/header.tmpl
 footer = ''
-changeset = changeset-raw.tmpl
+changeset = raw/changeset.tmpl
 difflineplus = '#line#'
 difflineminus = '#line#'
 difflineat = '#line#'
@@ -11,6 +11,6 @@ filenodelink = ''
 filerevision = '#rawfileheader##raw#'
 fileline = '#line#'
 diffblock = '#lines#'
-filediff = filediff-raw.tmpl
-fileannotate = fileannotate-raw.tmpl
+filediff = raw/filediff.tmpl
+fileannotate = raw/fileannotate.tmpl
 annotateline = '#author#@#rev#: #line#'
--- a/templates/map-rss
+++ b/templates/map-rss
@@ -1,8 +1,8 @@
 default = 'changelog'
-header = header-rss.tmpl
-changelog = changelog-rss.tmpl
-changelogentry = changelogentry-rss.tmpl
-filelog = filelog-rss.tmpl
-filelogentry = filelogentry-rss.tmpl
-tags = tags-rss.tmpl
-tagentry = tagentry-rss.tmpl
+header = rss/header.tmpl
+changelog = rss/changelog.tmpl
+changelogentry = rss/changelogentry.tmpl
+filelog = rss/filelog.tmpl
+filelogentry = rss/filelogentry.tmpl
+tags = rss/tags.tmpl
+tagentry = rss/tagentry.tmpl
rename from templates/changeset-raw.tmpl
rename to templates/raw/changeset.tmpl
rename from templates/fileannotate-raw.tmpl
rename to templates/raw/fileannotate.tmpl
rename from templates/filediff-raw.tmpl
rename to templates/raw/filediff.tmpl
rename from templates/header-raw.tmpl
rename to templates/raw/header.tmpl
rename from templates/changelog-rss.tmpl
rename to templates/rss/changelog.tmpl
rename from templates/changelogentry-rss.tmpl
rename to templates/rss/changelogentry.tmpl
rename from templates/filelog-rss.tmpl
rename to templates/rss/filelog.tmpl
rename from templates/filelogentry-rss.tmpl
rename to templates/rss/filelogentry.tmpl
rename from templates/header-rss.tmpl
rename to templates/rss/header.tmpl
rename from templates/tagentry-rss.tmpl
rename to templates/rss/tagentry.tmpl
rename from templates/tags-rss.tmpl
rename to templates/rss/tags.tmpl
--- a/templates/template-vars.txt
+++ b/templates/template-vars.txt
@@ -12,7 +12,7 @@ date          a date string
 age           age in hours, days, etc
 line          a line of text (escaped)
 desc          a description (escaped, with breaks)
-shortdesc         a short description (escaped)
+shortdesc     a short description (escaped)
 author        a name or email addressv(obfuscated)
 parent        a list of the parent
 child         a list of the children
--- a/tests/coverage.py
+++ b/tests/coverage.py
@@ -87,19 +87,19 @@ class StatementFindingAstVisitor(compile
         self.excluded = excluded
         self.suite_spots = suite_spots
         self.excluding_suite = 0
-        
+
     def doRecursive(self, node):
         self.recordNodeLine(node)
         for n in node.getChildNodes():
             self.dispatch(n)
 
     visitStmt = visitModule = doRecursive
-    
+
     def doCode(self, node):
         if hasattr(node, 'decorators') and node.decorators:
             self.dispatch(node.decorators)
         self.doSuite(node, node.code)
-    
+
     visitFunction = visitClass = doCode
 
     def getFirstLine(self, node):
@@ -119,17 +119,17 @@ class StatementFindingAstVisitor(compile
         for n in node.getChildNodes():
             lineno = max(lineno, self.getLastLine(n))
         return lineno
-    
+
     def doStatement(self, node):
         self.recordLine(self.getFirstLine(node))
 
     visitAssert = visitAssign = visitAssTuple = visitDiscard = visitPrint = \
         visitPrintnl = visitRaise = visitSubscript = visitDecorators = \
         doStatement
-    
+
     def recordNodeLine(self, node):
         return self.recordLine(node.lineno)
-    
+
     def recordLine(self, lineno):
         # Returns a bool, whether the line is included or excluded.
         if lineno:
@@ -153,9 +153,9 @@ class StatementFindingAstVisitor(compile
                 self.statements[lineno] = 1
                 return 1
         return 0
-    
+
     default = recordNodeLine
-    
+
     def recordAndDispatch(self, node):
         self.recordNodeLine(node)
         self.dispatch(node)
@@ -166,7 +166,7 @@ class StatementFindingAstVisitor(compile
             self.excluding_suite = 1
         self.recordAndDispatch(body)
         self.excluding_suite = exsuite
-        
+
     def doPlainWordSuite(self, prevsuite, suite):
         # Finding the exclude lines for else's is tricky, because they aren't
         # present in the compiler parse tree.  Look at the previous suite,
@@ -180,11 +180,11 @@ class StatementFindingAstVisitor(compile
                 break
         else:
             self.doSuite(None, suite)
-        
+
     def doElse(self, prevsuite, node):
         if node.else_:
             self.doPlainWordSuite(prevsuite, node.else_)
-    
+
     def visitFor(self, node):
         self.doSuite(node, node.body)
         self.doElse(node.body, node)
@@ -216,11 +216,11 @@ class StatementFindingAstVisitor(compile
             else:
                 self.doSuite(a, h)
         self.doElse(node.handlers[-1][2], node)
-    
+
     def visitTryFinally(self, node):
         self.doSuite(node, node.body)
         self.doPlainWordSuite(node.body, node.final)
-        
+
     def visitGlobal(self, node):
         # "global" statements don't execute like others (they don't call the
         # trace function), so don't record their line numbers.
@@ -240,7 +240,7 @@ class coverage:
     # A dictionary with an entry for (Python source file name, line number
     # in that file) if that line has been executed.
     c = {}
-    
+
     # A map from canonical Python source file name to a dictionary in
     # which there's an entry for each line number that has been
     # executed.
@@ -266,12 +266,12 @@ class coverage:
         self.xstack = []
         self.relative_dir = os.path.normcase(os.path.abspath(os.curdir)+os.path.sep)
 
-    # t(f, x, y).  This method is passed to sys.settrace as a trace function.  
-    # See [van Rossum 2001-07-20b, 9.2] for an explanation of sys.settrace and 
+    # t(f, x, y).  This method is passed to sys.settrace as a trace function.
+    # See [van Rossum 2001-07-20b, 9.2] for an explanation of sys.settrace and
     # the arguments and return value of the trace function.
     # See [van Rossum 2001-07-20a, 3.2] for a description of frame and code
     # objects.
-    
+
     def t(self, f, w, a):                                   #pragma: no cover
         #print w, f.f_code.co_filename, f.f_lineno
         if w == 'line':
@@ -279,7 +279,7 @@ class coverage:
             for c in self.cstack:
                 c[(f.f_code.co_filename, f.f_lineno)] = 1
         return self.t
-    
+
     def help(self, error=None):
         if error:
             print error
@@ -330,7 +330,7 @@ class coverage:
             self.help("You must specify at least one of -e, -x, -r, or -a.")
         if not args_needed and args:
             self.help("Unexpected arguments %s." % args)
-        
+
         self.get_ready()
         self.exclude('#pragma[: ]+[nN][oO] [cC][oO][vV][eE][rR]')
 
@@ -359,14 +359,14 @@ class coverage:
 
     def use_cache(self, usecache):
         self.usecache = usecache
-        
+
     def get_ready(self):
         if self.usecache and not self.cache:
             self.cache = os.path.abspath(os.environ.get(self.cache_env,
                                                         self.cache_default))
             self.restore()
         self.analysis_cache = {}
-        
+
     def start(self):
         self.get_ready()
         if self.nesting == 0:                               #pragma: no cover
@@ -374,7 +374,7 @@ class coverage:
             if hasattr(threading, 'settrace'):
                 threading.settrace(self.t)
         self.nesting += 1
-        
+
     def stop(self):
         self.nesting -= 1
         if self.nesting == 0:                               #pragma: no cover
@@ -398,7 +398,7 @@ class coverage:
     def begin_recursive(self):
         self.cstack.append(self.c)
         self.xstack.append(self.exclude_re)
-        
+
     def end_recursive(self):
         self.c = self.cstack.pop()
         self.exclude_re = self.xstack.pop()
@@ -452,7 +452,7 @@ class coverage:
             self.canonical_filename_cache[filename] = cf
         return self.canonical_filename_cache[filename]
 
-    # canonicalize_filenames().  Copy results from "c" to "cexecuted", 
+    # canonicalize_filenames().  Copy results from "c" to "cexecuted",
     # canonicalizing filenames on the way.  Clear the "c" map.
 
     def canonicalize_filenames(self):
@@ -550,7 +550,7 @@ class coverage:
         import parser
         tree = parser.suite(text+'\n\n').totuple(1)
         self.get_suite_spots(tree, suite_spots)
-            
+
         # Use the compiler module to parse the text and find the executable
         # statements.  We add newlines to be impervious to final partial lines.
         statements = {}
@@ -713,7 +713,7 @@ class coverage:
             except:
                 if not ignore_errors:
                     raise
-                
+
     def annotate_file(self, filename, statements, excluded, missing, directory=None):
         source = open(filename, 'r')
         if directory:
@@ -741,7 +741,7 @@ class coverage:
             if self.blank_re.match(line):
                 dest.write('  ')
             elif self.else_re.match(line):
-                # Special logic for lines containing only 'else:'.  
+                # Special logic for lines containing only 'else:'.
                 # See [GDR 2001-12-04b, 3.2].
                 if i >= len(statements) and j >= len(missing):
                     dest.write('! ')
@@ -850,7 +850,7 @@ if __name__ == '__main__':
 # Thanks, Allen.
 #
 # 2005-12-02 NMB Call threading.settrace so that all threads are measured.
-# Thanks Martin Fuzzey. Add a file argument to report so that reports can be 
+# Thanks Martin Fuzzey. Add a file argument to report so that reports can be
 # captured to a different destination.
 #
 # 2005-12-03 NMB coverage.py can now measure itself.
--- a/tests/md5sum.py
+++ b/tests/md5sum.py
@@ -16,7 +16,7 @@ for filename in sys.argv[1:]:
     except IOError, msg:
         sys.stderr.write('%s: Can\'t open: %s\n' % (filename, msg))
         sys.exit(1)
-    
+
     m = md5.new()
     try:
         while 1:
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -104,7 +104,7 @@ def use_correct_python():
         # windows fallback
         shutil.copyfile(sys.executable, my_python)
         shutil.copymode(sys.executable, my_python)
-            
+
 def install_hg():
     vlog("# Performing temporary installation of HG")
     installerrs = os.path.join("tests", "install.err")
@@ -358,7 +358,7 @@ try:
             args = os.listdir(".")
         for test in args:
             if (test.startswith("test-") and '~' not in test and
-                ('.' not in test or test.endswith('.py') or 
+                ('.' not in test or test.endswith('.py') or
                  test.endswith('.bat'))):
                 ret = run_one(test)
                 if ret is None:
new file mode 100644
--- /dev/null
+++ b/tests/test-doctest.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+#
+
+import doctest
+
+import mercurial.changelog
+# test doctest from changelog
+
+doctest.testmod(mercurial.changelog)
+
--- a/tests/test-merge-revert2
+++ b/tests/test-merge-revert2
@@ -27,8 +27,7 @@ hg id
 hg update -C 0
 echo "changed file1 different" >> file1
 HGMERGE=merge hg update
-#hg diff --nodates | sed -e "s/\(<<<<<<<\) .*/\1/" -e "s/\(>>>>>>>\) .*/\1/"
-hg diff --nodates | sed -e "s/\(<<<<<<<\|>>>>>>>\) .*/\1/"
+hg diff --nodates | sed -e "s/\(<<<<<<<\) .*/\1/" -e "s/\(>>>>>>>\) .*/\1/"
 hg status
 hg id
 hg revert --no-backup --all