# HG changeset patch # User Alexis S. L. Carvalho # Date 1186372810 10800 # Node ID 79373ec3f27d719afaec3a69d38aedc4a5a9e610 # Parent 487659a90497a21e1ff4c3a360f20e8f539862b6# Parent 167c422c745fee634cce9ec2b937559c0ba684ee merge with crew-stable diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -250,8 +250,14 @@ class dirstate(object): except KeyError: self._ui.warn(_("not in dirstate: %s!\n") % f) + def clear(self): + self._map = {} + self._copymap = {} + self._pl = [nullid, nullid] + self._dirty = True + def rebuild(self, parent, files): - self.invalidate() + self.clear() for f in files: if files.execf(f): self._map[f] = ('n', 0777, -1, 0) diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -488,7 +488,7 @@ class hgweb(object): continue yield {"parity": parity.next(), - "path": os.path.join(abspath, f), + "path": "%s%s" % (abspath, f), "basename": f[:-1]} yield self.t("manifest", diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py --- a/mercurial/hgweb/hgwebdir_mod.py +++ b/mercurial/hgweb/hgwebdir_mod.py @@ -17,7 +17,8 @@ from hgweb_mod import hgweb class hgwebdir(object): def __init__(self, config, parentui=None): def cleannames(items): - return [(name.strip(os.sep), path) for name, path in items] + return [(util.pconvert(name.strip(os.sep)), path) + for name, path in items] self.parentui = parentui self.motd = None diff --git a/mercurial/httprepo.py b/mercurial/httprepo.py --- a/mercurial/httprepo.py +++ b/mercurial/httprepo.py @@ -144,6 +144,43 @@ def zgenerator(f): raise IOError(None, _('connection ended unexpectedly')) yield zd.flush() +_safe = ('abcdefghijklmnopqrstuvwxyz' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + '0123456789' '_.-/') +_safeset = None +_hex = None +def quotepath(path): + '''quote the path part of a URL + + This is similar to urllib.quote, but it also tries to avoid + quoting things twice (inspired by wget): + + >>> quotepath('abc def') + 'abc%20def' + >>> quotepath('abc%20def') + 'abc%20def' + >>> quotepath('abc%20 def') + 'abc%20%20def' + >>> quotepath('abc def%20') + 'abc%20def%20' + >>> quotepath('abc def%2') + 'abc%20def%252' + >>> quotepath('abc def%') + 'abc%20def%25' + ''' + global _safeset, _hex + if _safeset is None: + _safeset = util.set(_safe) + _hex = util.set('abcdefABCDEF0123456789') + l = list(path) + for i in xrange(len(l)): + c = l[i] + if c == '%' and i + 2 < len(l) and (l[i+1] in _hex and l[i+2] in _hex): + pass + elif c not in _safeset: + l[i] = '%%%02X' % ord(c) + return ''.join(l) + class httprepository(remoterepository): def __init__(self, ui, path): self.path = path @@ -153,13 +190,16 @@ class httprepository(remoterepository): if query or frag: raise util.Abort(_('unsupported URL component: "%s"') % (query or frag)) - if not urlpath: urlpath = '/' + if not urlpath: + urlpath = '/' + urlpath = quotepath(urlpath) host, port, user, passwd = netlocsplit(netloc) # urllib cannot handle URLs with embedded user or passwd self._url = urlparse.urlunsplit((scheme, netlocunsplit(host, port), urlpath, '', '')) self.ui = ui + self.ui.debug(_('using %s\n') % self._url) proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy') # XXX proxyauthinfo = None diff --git a/tests/test-doctest.py b/tests/test-doctest.py --- a/tests/test-doctest.py +++ b/tests/test-doctest.py @@ -5,3 +5,5 @@ import mercurial.changelog doctest.testmod(mercurial.changelog) +import mercurial.httprepo +doctest.testmod(mercurial.httprepo) diff --git a/tests/test-rebuildstate b/tests/test-rebuildstate new file mode 100755 --- /dev/null +++ b/tests/test-rebuildstate @@ -0,0 +1,24 @@ +#!/bin/sh +# basic test for hg debugrebuildstate + +hg init repo +cd repo + +touch foo bar +hg ci -Am 'add foo bar' + +touch baz +hg add baz +hg rm bar + +echo '% state dump' +hg debugstate | cut -b 1-16,35- | sort +echo '% status' +hg st -A + +hg debugrebuildstate +echo '% state dump' +hg debugstate | cut -b 1-16,35- | sort +echo '% status' +hg st -A + diff --git a/tests/test-rebuildstate.out b/tests/test-rebuildstate.out new file mode 100644 --- /dev/null +++ b/tests/test-rebuildstate.out @@ -0,0 +1,17 @@ +adding bar +adding foo +% state dump +a 0 -1 baz +n 644 0 foo +r 0 0 bar +% status +A baz +R bar +C foo +% state dump +n 666 -1 bar +n 666 -1 foo +% status +! bar +? baz +C foo