# HG changeset patch # User Eric Hopper # Date 1157851506 25200 # Node ID 3505fcd5a231d0022b85fc7d1e9fe27d67e41574 # Parent e6045fc3cd50c15e4013f7bc353d3e5f60d6cfb6 Adding changegroupsubset and lookup to web protocol so pull -r and clone -r can be supported. diff -r e6045fc3cd50 -r 3505fcd5a231 mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py Wed Oct 18 02:08:33 2006 -0500 +++ b/mercurial/hgweb/hgweb_mod.py Sat Sep 09 18:25:06 2006 -0700 @@ -883,6 +883,11 @@ def do_filelog(self, req): req.write(self.filelog(self.filectx(req))) + def do_lookup(self, req): + resp = hex(self.repo.lookup(req.form['key'][0])) + "\n" + req.httphdr("application/mercurial-0.1", length=len(resp)) + req.write(resp) + def do_heads(self, req): resp = " ".join(map(hex, self.repo.heads())) + "\n" req.httphdr("application/mercurial-0.1", length=len(resp)) @@ -929,6 +934,28 @@ req.write(z.flush()) + def do_changegroupsubset(self, req): + req.httphdr("application/mercurial-0.1") + bases = [] + heads = [] + if not self.allowpull: + return + + if req.form.has_key('bases'): + bases = [bin(x) for x in req.form['bases'][0].split(' ')] + if req.form.has_key('heads'): + heads = [bin(x) for x in req.form['heads'][0].split(' ')] + + z = zlib.compressobj() + f = self.repo.changegroupsubset(bases, heads, 'serve') + while 1: + chunk = f.read(4096) + if not chunk: + break + req.write(z.compress(chunk)) + + req.write(z.flush()) + def do_archive(self, req): changeset = self.repo.lookup(req.form['node'][0]) type_ = req.form['type'][0] @@ -949,7 +976,7 @@ or self.t("error", error="%r not found" % fname)) def do_capabilities(self, req): - caps = ['unbundle'] + caps = ['unbundle', 'lookup', 'changegroupsubset'] if self.repo.ui.configbool('server', 'uncompressed'): caps.append('stream=%d' % self.repo.revlogversion) resp = ' '.join(caps) diff -r e6045fc3cd50 -r 3505fcd5a231 mercurial/httprepo.py --- a/mercurial/httprepo.py Wed Oct 18 02:08:33 2006 -0500 +++ b/mercurial/httprepo.py Sat Sep 09 18:25:06 2006 -0700 @@ -261,6 +261,14 @@ # if using keepalive, allow connection to be reused fp.close() + def lookup(self, key): + try: + d = self.do_cmd("lookup", key = key).read() + return bin(d[:-1]) + except: + self.ui.warn('Not able to look up revision named "%s"\n' % (key,)) + raise + def heads(self): d = self.do_read("heads") try: @@ -298,6 +306,22 @@ try: for chnk in f: yield zd.decompress(chnk) + except httplib.HTTPException, inst: + raise IOError(None, _('connection ended unexpectedly')) + yield zd.flush() + + return util.chunkbuffer(zgenerator(util.filechunkiter(f))) + + def changegroupsubset(self, bases, heads, source): + baselst = " ".join([hex(n) for n in bases]) + headlst = " ".join([hex(n) for n in heads]) + f = self.do_cmd("changegroupsubset", bases=baselst, heads=headlst) + + def zgenerator(f): + zd = zlib.decompressobj() + try: + for chnk in f: + yield zd.decompress(chnk) except httplib.HTTPException: raise IOError(None, _('connection ended unexpectedly')) yield zd.flush()