diff --git a/mercurial/hgweb/protocol.py b/mercurial/hgweb/protocol.py --- a/mercurial/hgweb/protocol.py +++ b/mercurial/hgweb/protocol.py @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2, incorporated herein by reference. -import cStringIO, zlib, tempfile, errno, os, sys +import cStringIO, zlib, tempfile, errno, os, sys, urllib from mercurial import util, streamclone from mercurial.node import bin, hex from mercurial import changegroup as changegroupmod @@ -17,6 +17,7 @@ from common import ErrorResponse, HTTP_O __all__ = [ 'lookup', 'heads', 'branches', 'between', 'changegroup', 'changegroupsubset', 'capabilities', 'unbundle', 'stream_out', + 'branchmap', ] HGTYPE = 'application/mercurial-0.1' @@ -37,6 +38,17 @@ def heads(repo, req): req.respond(HTTP_OK, HGTYPE, length=len(resp)) yield resp +def branchmap(repo, req): + branches = repo.branchmap() + heads = [] + for branch, nodes in branches.iteritems(): + branchname = urllib.quote(branch) + branchnodes = [hex(node) for node in nodes] + heads.append('%s %s' % (branchname, ' '.join(branchnodes))) + resp = '\n'.join(heads) + req.respond(HTTP_OK, HGTYPE, length=len(resp)) + yield resp + def branches(repo, req): nodes = [] if 'nodes' in req.form: @@ -97,7 +109,7 @@ def changegroupsubset(repo, req): yield z.flush() def capabilities(repo, req): - caps = ['lookup', 'changegroupsubset'] + caps = ['lookup', 'changegroupsubset', 'branchmap'] if repo.ui.configbool('server', 'uncompressed', untrusted=True): caps.append('stream=%d' % repo.changelog.version) if changegroupmod.bundlepriority: diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -18,7 +18,7 @@ import weakref, stat, errno, os, time, i propertycache = util.propertycache class localrepository(repo.repository): - capabilities = set(('lookup', 'changegroupsubset')) + capabilities = set(('lookup', 'changegroupsubset', 'branchmap')) supported = set('revlogv1 store fncache'.split()) def __init__(self, baseui, path=None, create=0): @@ -360,7 +360,7 @@ class localrepository(repo.repository): return partial - def _branchheads(self): + def branchmap(self): tip = self.changelog.tip() if self.branchcache is not None and self._branchcachetip == tip: return self.branchcache @@ -392,7 +392,7 @@ class localrepository(repo.repository): '''return a dict where branch names map to the tipmost head of the branch, open heads come before closed''' bt = {} - for bn, heads in self._branchheads().iteritems(): + for bn, heads in self.branchmap().iteritems(): head = None for i in range(len(heads)-1, -1, -1): h = heads[i] @@ -1125,7 +1125,7 @@ class localrepository(repo.repository): def branchheads(self, branch=None, start=None, closed=True): if branch is None: branch = self[None].branch() - branches = self._branchheads() + branches = self.branchmap() if branch not in branches: return [] bheads = branches[branch] diff --git a/mercurial/sshserver.py b/mercurial/sshserver.py --- a/mercurial/sshserver.py +++ b/mercurial/sshserver.py @@ -9,7 +9,7 @@ from i18n import _ from node import bin, hex import streamclone, util, hook -import os, sys, tempfile +import os, sys, tempfile, urllib class sshserver(object): def __init__(self, ui, repo): @@ -64,6 +64,15 @@ class sshserver(object): success = 0 self.respond("%s %s\n" % (success, r)) + def do_branchmap(self): + branchmap = self.repo.branchmap() + heads = [] + for branch, nodes in branchmap.iteritems(): + branchname = urllib.quote(branch) + branchnodes = [hex(node) for node in nodes] + heads.append('%s %s' % (branchname, ' '.join(branchnodes))) + self.respond('\n'.join(heads)) + def do_heads(self): h = self.repo.heads() self.respond(" ".join(map(hex, h)) + "\n") @@ -77,7 +86,7 @@ class sshserver(object): capabilities: space separated list of tokens ''' - caps = ['unbundle', 'lookup', 'changegroupsubset'] + caps = ['unbundle', 'lookup', 'changegroupsubset', 'branchmap'] if self.ui.configbool('server', 'uncompressed'): caps.append('stream=%d' % self.repo.changelog.version) self.respond("capabilities: %s\n" % (' '.join(caps),)) diff --git a/tests/test-hgweb-commands.out b/tests/test-hgweb-commands.out --- a/tests/test-hgweb-commands.out +++ b/tests/test-hgweb-commands.out @@ -848,7 +848,7 @@ graph.render(data); % capabilities 200 Script output follows -lookup changegroupsubset unbundle=HG10GZ,HG10BZ,HG10UN% heads +lookup changegroupsubset branchmap unbundle=HG10GZ,HG10BZ,HG10UN% heads 200 Script output follows 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe