22
22
At the moment remote branches are only for HTTP and only for read
28
30
from cStringIO import StringIO
31
32
from errors import BzrError, BzrCheckError
32
from branch import Branch, BZR_BRANCH_FORMAT
33
from trace import mutter
33
from branch import Branch
35
35
# velocitynet.com.au transparently proxies connections and thereby
36
36
# breaks keep-alive -- sucks!
39
ENABLE_URLGRABBER = True
41
from bzrlib.errors import BzrError
43
class GetFailed(BzrError):
44
def __init__(self, url, status):
45
BzrError.__init__(self, "Get %s failed with status %s" % (url, status))
40
ENABLE_URLGRABBER = False
42
def get_url(url, compressed=False):
46
url_f = urllib2.urlopen(url)
48
return gzip.GzipFile(fileobj=StringIO(url_f.read()))
49
52
if ENABLE_URLGRABBER:
58
mutter("grab url %s" % url)
59
61
url_f = urlgrabber.urlopen(url, keepalive=1, close_connection=0)
60
if url_f.status != 200:
61
raise GetFailed(url, url_f.status)
65
65
return gzip.GzipFile(fileobj=StringIO(url_f.read()))
66
66
except urllib2.URLError, e:
67
67
raise BzrError("remote fetch failed: %r: %s" % (url, e))
69
def get_url(url, compressed=False):
73
mutter("get_url %s" % url)
74
url_f = urllib2.urlopen(url)
76
return gzip.GzipFile(fileobj=StringIO(url_f.read()))
110
91
class RemoteBranch(Branch):
111
def __init__(self, baseurl, find_root=True):
92
def __init__(self, baseurl, find_root=False, lock_mode='r'):
112
93
"""Create new proxy for a remote branch."""
114
self.baseurl = _find_remote_root(baseurl)
116
self.baseurl = baseurl
119
self.inventory_store = RemoteStore(baseurl + '/.bzr/inventory-store/')
120
self.text_store = RemoteStore(baseurl + '/.bzr/text-store/')
121
self.revision_store = RemoteStore(baseurl + '/.bzr/revision-store/')
124
b = getattr(self, 'baseurl', 'undefined')
125
return '%s(%r)' % (self.__class__.__name__, b)
94
if lock_mode not in ('', 'r'):
95
raise BzrError('lock mode %r is not supported for remote branches'
98
self.baseurl = baseurl
129
101
def controlfile(self, filename, mode):
130
102
if mode not in ('rb', 'rt', 'r'):
131
103
raise BzrError("file mode %r not supported for remote branches" % mode)
132
104
return get_url(self.baseurl + '/.bzr/' + filename, False)
136
# no locking for remote branches yet
139
def lock_write(self):
140
from errors import LockError
141
raise LockError("write lock not supported for remote branch %s"
106
def _need_readlock(self):
107
# remote branch always safe for read
110
def _need_writelock(self):
111
raise BzrError("cannot get write lock on HTTP remote branch")
148
113
def relpath(self, path):
149
114
if not path.startswith(self.baseurl):
152
117
pl = len(self.baseurl)
153
118
return path[pl:].lstrip('/')
156
120
def get_revision(self, revision_id):
157
from bzrlib.revision import Revision
158
from bzrlib.xml import unpack_xml
159
revf = self.revision_store[revision_id]
160
r = unpack_xml(Revision, revf)
121
from revision import Revision
122
revf = get_url(self.baseurl + '/.bzr/revision-store/' + revision_id,
124
r = Revision.read_xml(revf)
161
125
if r.revision_id != revision_id:
162
126
raise BzrCheckError('revision stored as {%s} actually contains {%s}'
163
127
% (revision_id, r.revision_id))
167
class RemoteStore(object):
168
def __init__(self, baseurl):
169
self._baseurl = baseurl
172
def _path(self, name):
174
raise ValueError('invalid store id', name)
175
return self._baseurl + '/' + name
177
def __getitem__(self, fileid):
178
p = self._path(fileid)
180
return get_url(p, compressed=True)
182
raise KeyError(fileid)
132
from revision import Revision
133
from branch import Branch
134
from inventory import Inventory
140
history = get_url('/.bzr/revision-history').readlines()
141
num_revs = len(history)
142
for i, rev_id in enumerate(history):
143
rev_id = rev_id.rstrip()
144
print 'read revision %d/%d' % (i, num_revs)
146
# python gzip needs a seekable file (!!) but the HTTP response
147
# isn't, so we need to buffer it
149
rev_f = get_url('/.bzr/revision-store/%s' % rev_id,
152
rev = Revision.read_xml(rev_f)
154
inv_id = rev.inventory_id
155
if inv_id not in got_invs:
156
print 'get inventory %s' % inv_id
157
inv_f = get_url('/.bzr/inventory-store/%s' % inv_id,
159
inv = Inventory.read_xml(inv_f)
160
print '%4d inventory entries' % len(inv)
162
for path, ie in inv.iter_entries():
166
if text_id in got_texts:
168
print ' fetch %s text {%s}' % (path, text_id)
169
text_f = get_url('/.bzr/text-store/%s' % text_id,
171
got_texts.add(text_id)
179
BASE_URL = 'http://bazaar-ng.org/bzr/bzr.dev/'
180
b = RemoteBranch(BASE_URL)
181
## print '\n'.join(b.revision_history())
182
from log import show_log
186
if __name__ == '__main__':