diff --git a/hgext/convert/common.py b/hgext/convert/common.py --- a/hgext/convert/common.py +++ b/hgext/convert/common.py @@ -30,8 +30,8 @@ SKIPREV = 'SKIP' class commit(object): def __init__(self, author, date, desc, parents, branch=None, rev=None, extra={}): - self.author = author - self.date = date + self.author = author or 'unknown' + self.date = date or '0 0' self.desc = desc self.parents = parents self.branch = branch diff --git a/hgext/convert/git.py b/hgext/convert/git.py --- a/hgext/convert/git.py +++ b/hgext/convert/git.py @@ -102,7 +102,6 @@ class convert_git(converter_source): tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:] tz = -int(tzs) * (int(tzh) * 3600 + int(tzm)) date = tm + " " + str(tz) - author = author or "unknown" c = commit(parents=parents, date=date, author=author, desc=message, rev=version) diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -600,11 +600,19 @@ class queue: raise util.Abort(_("local changes found")) return m, a, r, d + _reserved = ('series', 'status', 'guards') + def check_reserved_name(self, name): + if (name in self._reserved or name.startswith('.hg') + or name.startswith('.mq')): + raise util.Abort(_('"%s" cannot be used as the name of a patch') + % name) + def new(self, repo, patch, *pats, **opts): msg = opts.get('msg') force = opts.get('force') user = opts.get('user') date = opts.get('date') + self.check_reserved_name(patch) if os.path.exists(self.join(patch)): raise util.Abort(_('patch "%s" already exists') % patch) if opts.get('include') or opts.get('exclude') or pats: @@ -872,10 +880,16 @@ class queue: start = info[0] rev = revlog.bin(info[1]) + if update: + top = self.check_toppatch(repo) + + if repo.changelog.heads(rev) != [revlog.bin(self.applied[-1].rev)]: + raise util.Abort("popping would remove a revision not " + "managed by this patch queue") + # we know there are no local changes, so we can make a simplified # form of hg.update. if update: - top = self.check_toppatch(repo) qp = self.qparents(repo, rev) changes = repo.changelog.read(qp) mmap = repo.manifest.read(changes[0]) @@ -898,8 +912,8 @@ class queue: except: pass repo.dirstate.forget(f) repo.dirstate.setparents(qp, revlog.nullid) + del self.applied[start:end] self.strip(repo, rev, update=False, backup='strip') - del self.applied[start:end] if len(self.applied): self.ui.write("Now at: %s\n" % self.applied[-1].name) else: @@ -926,6 +940,8 @@ class queue: self.check_toppatch(repo) (top, patchfn) = (self.applied[-1].rev, self.applied[-1].name) top = revlog.bin(top) + if repo.changelog.heads(top) != [top]: + raise util.Abort("cannot refresh a revision with children") cparents = repo.changelog.parents(top) patchparent = self.qparents(repo, top) message, comments, user, date, patchfound = self.readheaders(patchfn) @@ -1112,12 +1128,13 @@ class queue: if not user: user = changes[1] + self.applied.pop() + self.applied_dirty = 1 self.strip(repo, top, update=False, backup='strip') n = repo.commit(filelist, message, user, date, match=matchfn, force=1) - self.applied[-1] = statusentry(revlog.hex(n), patchfn) - self.applied_dirty = 1 + self.applied.append(statusentry(revlog.hex(n), patchfn)) self.removeundo(repo) else: self.printdiff(repo, patchparent, fp=patchf) @@ -1406,6 +1423,7 @@ class queue: if not patchname: patchname = normname('%d.diff' % r) + self.check_reserved_name(patchname) checkseries(patchname) checkfile(patchname) self.full_series.insert(0, patchname) @@ -1428,6 +1446,7 @@ class queue: raise util.Abort(_('-e is incompatible with import from -')) if not patchname: patchname = normname(filename) + self.check_reserved_name(patchname) if not os.path.isfile(self.join(patchname)): raise util.Abort(_("patch %s does not exist") % patchname) else: @@ -1442,6 +1461,7 @@ class queue: raise util.Abort(_("unable to read %s") % patchname) if not patchname: patchname = normname(os.path.basename(filename)) + self.check_reserved_name(patchname) checkfile(patchname) patchf = self.opener(patchname, "w") patchf.write(text) @@ -2147,6 +2167,12 @@ def reposetup(ui, repo): return tagscache mqtags = [(revlog.bin(patch.rev), patch.name) for patch in q.applied] + + if mqtags[-1][0] not in self.changelog.nodemap: + self.ui.warn('mq status file refers to unknown node %s\n' + % revlog.short(mqtags[-1][0])) + return tagscache + mqtags.append((mqtags[-1][0], 'qtip')) mqtags.append((mqtags[0][0], 'qbase')) mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent')) @@ -2163,11 +2189,17 @@ def reposetup(ui, repo): if not q.applied: return super(mqrepo, self)._branchtags() + cl = self.changelog + qbasenode = revlog.bin(q.applied[0].rev) + if qbasenode not in cl.nodemap: + self.ui.warn('mq status file refers to unknown node %s\n' + % revlog.short(qbasenode)) + return super(mqrepo, self)._branchtags() + self.branchcache = {} # avoid recursion in changectx - cl = self.changelog partial, last, lrev = self._readbranchcache() - qbase = cl.rev(revlog.bin(q.applied[0].rev)) + qbase = cl.rev(qbasenode) start = lrev + 1 if start < qbase: # update the cache (excluding the patches) and save it diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1540,6 +1540,9 @@ def import_(ui, repo, patch1, *patches, repo.rollback() raise util.Abort(_('patch is damaged' ' or loses information')) + # Force a dirstate write so that the next transaction + # backups an up-do-date file. + repo.dirstate.write() finally: os.unlink(tmpname) finally: diff --git a/mercurial/httprepo.py b/mercurial/httprepo.py --- a/mercurial/httprepo.py +++ b/mercurial/httprepo.py @@ -103,10 +103,13 @@ class httpconnection(keepalive.HTTPConne # must be able to send big bundle as stream. send = _gen_sendfile(keepalive.HTTPConnection) -class basehttphandler(keepalive.HTTPHandler): +class httphandler(keepalive.HTTPHandler): def http_open(self, req): return self.do_open(httpconnection, req) + def __del__(self): + self.close_all() + has_https = hasattr(urllib2, 'HTTPSHandler') if has_https: class httpsconnection(httplib.HTTPSConnection): @@ -114,12 +117,9 @@ if has_https: # must be able to send big bundle as stream. send = _gen_sendfile(httplib.HTTPSConnection) - class httphandler(basehttphandler, urllib2.HTTPSHandler): + class httpshandler(keepalive.KeepAliveHandler, urllib2.HTTPSHandler): def https_open(self, req): return self.do_open(httpsconnection, req) -else: - class httphandler(basehttphandler): - pass # In python < 2.5 AbstractDigestAuthHandler raises a ValueError if # it doesn't know about the auth type requested. This can happen if @@ -203,8 +203,9 @@ class httprepository(remoterepository): proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy') # XXX proxyauthinfo = None - self.handler = httphandler() - handlers = [self.handler] + handlers = [httphandler()] + if has_https: + handlers.append(httpshandler()) if proxyurl: # proxy can be proper url or host[:port] @@ -270,11 +271,6 @@ class httprepository(remoterepository): opener.addheaders = [('User-agent', 'mercurial/proto-1.0')] urllib2.install_opener(opener) - def __del__(self): - if self.handler: - self.handler.close_all() - self.handler = None - def url(self): return self.path diff --git a/mercurial/keepalive.py b/mercurial/keepalive.py --- a/mercurial/keepalive.py +++ b/mercurial/keepalive.py @@ -175,7 +175,7 @@ class ConnectionManager: else: return dict(self._hostmap) -class HTTPHandler(urllib2.HTTPHandler): +class KeepAliveHandler: def __init__(self): self._cm = ConnectionManager() @@ -314,6 +314,9 @@ class HTTPHandler(urllib2.HTTPHandler): except socket.error, err: # XXX what error? raise urllib2.URLError(err) +class HTTPHandler(KeepAliveHandler, urllib2.HTTPHandler): + pass + class HTTPResponse(httplib.HTTPResponse): # we need to subclass HTTPResponse in order to # 1) add readline() and readlines() methods diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -120,6 +120,7 @@ class localrepository(repo.repository): self.hook('pretag', throw=True, node=hex(node), tag=name, local=local) def writetag(fp, name, munge, prevtags): + fp.seek(0, 2) if prevtags and prevtags[-1] != '\n': fp.write('\n') fp.write('%s %s\n' % (hex(node), munge and munge(name) or name)) @@ -1981,6 +1982,10 @@ class localrepository(repo.repository): del tr if changesets > 0: + # forcefully update the on-disk branch cache + self.ui.debug(_("updating the branch cache\n")) + self.branchcache = None + self.branchtags() self.hook("changegroup", node=hex(self.changelog.node(cor+1)), source=srctype, url=url) diff --git a/mercurial/sshrepo.py b/mercurial/sshrepo.py --- a/mercurial/sshrepo.py +++ b/mercurial/sshrepo.py @@ -114,14 +114,25 @@ class sshrepository(remoterepository): return self.pipei def call(self, cmd, **args): - r = self.do_cmd(cmd, **args) - l = r.readline() + self.do_cmd(cmd, **args) + return self._recv() + + def _recv(self): + l = self.pipei.readline() self.readerr() try: l = int(l) except: self.raise_(util.UnexpectedOutput(_("unexpected response:"), l)) - return r.read(l) + return self.pipei.read(l) + + def _send(self, data, flush=False): + self.pipeo.write("%d\n" % len(data)) + if data: + self.pipeo.write(data) + if flush: + self.pipeo.flush() + self.readerr() def lock(self): self.call("lock") @@ -182,25 +193,22 @@ class sshrepository(remoterepository): while 1: d = cg.read(4096) - if not d: break - self.pipeo.write(str(len(d)) + '\n') - self.pipeo.write(d) - self.readerr() + if not d: + break + self._send(d) - self.pipeo.write('0\n') - self.pipeo.flush() + self._send("", flush=True) - self.readerr() - l = int(self.pipei.readline()) - r = self.pipei.read(l) + r = self._recv() if r: # remote may send "unsynced changes" self.raise_(repo.RepoError(_("push failed: %s") % r)) - self.readerr() - l = int(self.pipei.readline()) - r = self.pipei.read(l) - return int(r) + r = self._recv() + try: + return int(r) + except: + self.raise_(util.UnexpectedOutput(_("unexpected response:"), r)) def addchangegroup(self, cg, source, url): d = self.call("addchangegroup") @@ -208,18 +216,21 @@ class sshrepository(remoterepository): self.raise_(repo.RepoError(_("push refused: %s") % d)) while 1: d = cg.read(4096) - if not d: break + if not d: + break self.pipeo.write(d) self.readerr() self.pipeo.flush() self.readerr() - l = int(self.pipei.readline()) - r = self.pipei.read(l) + r = self._recv() if not r: return 1 - return int(r) + try: + return int(r) + except: + self.raise_(util.UnexpectedOutput(_("unexpected response:"), r)) def stream_out(self): return self.do_cmd('stream_out') diff --git a/templates/header.tmpl b/templates/header.tmpl --- a/templates/header.tmpl +++ b/templates/header.tmpl @@ -1,6 +1,6 @@
- + diff --git a/templates/old/header.tmpl b/templates/old/header.tmpl --- a/templates/old/header.tmpl +++ b/templates/old/header.tmpl @@ -1,6 +1,6 @@ - + diff --git a/tests/test-acl.out b/tests/test-acl.out --- a/tests/test-acl.out +++ b/tests/test-acl.out @@ -28,6 +28,7 @@ adding foo/Bar/file.txt revisions adding foo/file.txt revisions adding quux/file.py revisions added 3 changesets with 3 changes to 3 files +updating the branch cache rolling back last transaction 0:6675d58eff77 @@ -59,6 +60,7 @@ calling hook pretxnchangegroup.acl: hgex acl: acl.allow not enabled acl: acl.deny not enabled acl: changes have source "push" - skipping +updating the branch cache rolling back last transaction 0:6675d58eff77 @@ -94,6 +96,7 @@ acl: acl.deny not enabled acl: allowing changeset ef1ea85a6374 acl: allowing changeset f9cafe1212c8 acl: allowing changeset 911600dab2ae +updating the branch cache rolling back last transaction 0:6675d58eff77 @@ -383,6 +386,7 @@ acl: acl.deny enabled, 0 entries for use acl: allowing changeset ef1ea85a6374 acl: allowing changeset f9cafe1212c8 acl: allowing changeset 911600dab2ae +updating the branch cache rolling back last transaction 0:6675d58eff77 @@ -578,6 +582,7 @@ acl: acl.deny enabled, 0 entries for use acl: allowing changeset ef1ea85a6374 acl: allowing changeset f9cafe1212c8 acl: allowing changeset 911600dab2ae +updating the branch cache rolling back last transaction 0:6675d58eff77 diff --git a/tests/test-hgweb-commands.out b/tests/test-hgweb-commands.out index 326d8df07cad7af2196b263febeb5b826bf1fdc8..684b3e91d0dd961c12354408a2906d90d327a5b0 GIT binary patch literal 15009 zc%1E9>2ljR63+fy)jkA