comparison mercurial/localrepo.py @ 7803:6d99ff7b79b5

Merge with stable
author Matt Mackall <mpm@selenic.com>
date Fri, 27 Feb 2009 08:13:42 -0600
parents dd970a311ea8 b8d750daadde
children 4421abf8c85d
comparison
equal deleted inserted replaced
7802:dd970a311ea8 7803:6d99ff7b79b5
8 from node import bin, hex, nullid, nullrev, short 8 from node import bin, hex, nullid, nullrev, short
9 from i18n import _ 9 from i18n import _
10 import repo, changegroup 10 import repo, changegroup
11 import changelog, dirstate, filelog, manifest, context, weakref 11 import changelog, dirstate, filelog, manifest, context, weakref
12 import lock, transaction, stat, errno, ui, store 12 import lock, transaction, stat, errno, ui, store
13 import os, revlog, time, util, extensions, hook, inspect 13 import os, time, util, extensions, hook, inspect, error
14 import match as match_ 14 import match as match_
15 import merge as merge_ 15 import merge as merge_
16 16
17 class localrepository(repo.repository): 17 class localrepository(repo.repository):
18 capabilities = util.set(('lookup', 'changegroupsubset')) 18 capabilities = util.set(('lookup', 'changegroupsubset'))
45 reqfile = self.opener("requires", "w") 45 reqfile = self.opener("requires", "w")
46 for r in requirements: 46 for r in requirements:
47 reqfile.write("%s\n" % r) 47 reqfile.write("%s\n" % r)
48 reqfile.close() 48 reqfile.close()
49 else: 49 else:
50 raise repo.RepoError(_("repository %s not found") % path) 50 raise error.RepoError(_("repository %s not found") % path)
51 elif create: 51 elif create:
52 raise repo.RepoError(_("repository %s already exists") % path) 52 raise error.RepoError(_("repository %s already exists") % path)
53 else: 53 else:
54 # find requirements 54 # find requirements
55 requirements = [] 55 requirements = []
56 try: 56 try:
57 requirements = self.opener("requires").read().splitlines() 57 requirements = self.opener("requires").read().splitlines()
58 for r in requirements: 58 for r in requirements:
59 if r not in self.supported: 59 if r not in self.supported:
60 raise repo.RepoError(_("requirement '%s' not supported") % r) 60 raise error.RepoError(_("requirement '%s' not supported") % r)
61 except IOError, inst: 61 except IOError, inst:
62 if inst.errno != errno.ENOENT: 62 if inst.errno != errno.ENOENT:
63 raise 63 raise
64 64
65 self.store = store.store(requirements, self.path, util.opener) 65 self.store = store.store(requirements, self.path, util.opener)
86 self._transref = self._lockref = self._wlockref = None 86 self._transref = self._lockref = self._wlockref = None
87 87
88 def __getattr__(self, name): 88 def __getattr__(self, name):
89 if name == 'changelog': 89 if name == 'changelog':
90 self.changelog = changelog.changelog(self.sopener) 90 self.changelog = changelog.changelog(self.sopener)
91 if 'HG_PENDING' in os.environ:
92 p = os.environ['HG_PENDING']
93 if p.startswith(self.root):
94 self.changelog.readpending('00changelog.i.a')
91 self.sopener.defversion = self.changelog.version 95 self.sopener.defversion = self.changelog.version
92 return self.changelog 96 return self.changelog
93 if name == 'manifest': 97 if name == 'manifest':
94 self.changelog 98 self.changelog
95 self.manifest = manifest.manifest(self.sopener) 99 self.manifest = manifest.manifest(self.sopener)
175 else: 179 else:
176 prevtags = fp.read() 180 prevtags = fp.read()
177 else: 181 else:
178 try: 182 try:
179 prevtags = self.filectx('.hgtags', parent).data() 183 prevtags = self.filectx('.hgtags', parent).data()
180 except revlog.LookupError: 184 except error.LookupError:
181 pass 185 pass
182 fp = self.wfile('.hgtags', 'wb') 186 fp = self.wfile('.hgtags', 'wb')
183 if prevtags: 187 if prevtags:
184 fp.write(prevtags) 188 fp.write(prevtags)
185 189
263 if key in filetags: 267 if key in filetags:
264 n, h = filetags[key] 268 n, h = filetags[key]
265 h.append(n) 269 h.append(n)
266 filetags[key] = (bin_n, h) 270 filetags[key] = (bin_n, h)
267 271
268 for k, nh in filetags.items(): 272 for k, nh in filetags.iteritems():
269 if k not in globaltags: 273 if k not in globaltags:
270 globaltags[k] = nh 274 globaltags[k] = nh
271 tagtypes[k] = tagtype 275 tagtypes[k] = tagtype
272 continue 276 continue
273 277
299 except IOError: 303 except IOError:
300 pass 304 pass
301 305
302 self.tagscache = {} 306 self.tagscache = {}
303 self._tagstypecache = {} 307 self._tagstypecache = {}
304 for k,nh in globaltags.items(): 308 for k, nh in globaltags.iteritems():
305 n = nh[0] 309 n = nh[0]
306 if n != nullid: 310 if n != nullid:
307 self.tagscache[k] = n 311 self.tagscache[k] = n
308 self._tagstypecache[k] = tagtypes[k] 312 self._tagstypecache[k] = tagtypes[k]
309 self.tagscache['tip'] = self.changelog.tip() 313 self.tagscache['tip'] = self.changelog.tip()
330 for node in heads: 334 for node in heads:
331 c = self[node] 335 c = self[node]
332 rev = c.rev() 336 rev = c.rev()
333 try: 337 try:
334 fnode = c.filenode('.hgtags') 338 fnode = c.filenode('.hgtags')
335 except revlog.LookupError: 339 except error.LookupError:
336 continue 340 continue
337 ret.append((rev, node, fnode)) 341 ret.append((rev, node, fnode))
338 if fnode in last: 342 if fnode in last:
339 ret[last[fnode]] = None 343 ret[last[fnode]] = None
340 last[fnode] = len(ret) - 1 344 last[fnode] = len(ret) - 1
341 return [item for item in ret if item] 345 return [item for item in ret if item]
342 346
343 def tagslist(self): 347 def tagslist(self):
344 '''return a list of tags ordered by revision''' 348 '''return a list of tags ordered by revision'''
345 l = [] 349 l = []
346 for t, n in self.tags().items(): 350 for t, n in self.tags().iteritems():
347 try: 351 try:
348 r = self.changelog.rev(n) 352 r = self.changelog.rev(n)
349 except: 353 except:
350 r = -2 # sort to the beginning of the list if unknown 354 r = -2 # sort to the beginning of the list if unknown
351 l.append((r, t, n)) 355 l.append((r, t, n))
353 357
354 def nodetags(self, node): 358 def nodetags(self, node):
355 '''return the tags associated with a node''' 359 '''return the tags associated with a node'''
356 if not self.nodetagscache: 360 if not self.nodetagscache:
357 self.nodetagscache = {} 361 self.nodetagscache = {}
358 for t, n in self.tags().items(): 362 for t, n in self.tags().iteritems():
359 self.nodetagscache.setdefault(n, []).append(t) 363 self.nodetagscache.setdefault(n, []).append(t)
360 return self.nodetagscache.get(node, []) 364 return self.nodetagscache.get(node, [])
361 365
362 def _branchtags(self, partial, lrev): 366 def _branchtags(self, partial, lrev):
367 # TODO: rename this function?
363 tiprev = len(self) - 1 368 tiprev = len(self) - 1
364 if lrev != tiprev: 369 if lrev != tiprev:
365 self._updatebranchcache(partial, lrev+1, tiprev+1) 370 self._updatebranchcache(partial, lrev+1, tiprev+1)
366 self._writebranchcache(partial, self.changelog.tip(), tiprev) 371 self._writebranchcache(partial, self.changelog.tip(), tiprev)
367 372
368 return partial 373 return partial
369 374
370 def branchtags(self): 375 def _branchheads(self):
371 tip = self.changelog.tip() 376 tip = self.changelog.tip()
372 if self.branchcache is not None and self._branchcachetip == tip: 377 if self.branchcache is not None and self._branchcachetip == tip:
373 return self.branchcache 378 return self.branchcache
374 379
375 oldtip = self._branchcachetip 380 oldtip = self._branchcachetip
383 else: 388 else:
384 lrev = self.changelog.rev(oldtip) 389 lrev = self.changelog.rev(oldtip)
385 partial = self._ubranchcache 390 partial = self._ubranchcache
386 391
387 self._branchtags(partial, lrev) 392 self._branchtags(partial, lrev)
393 # this private cache holds all heads (not just tips)
394 self._ubranchcache = partial
388 395
389 # the branch cache is stored on disk as UTF-8, but in the local 396 # the branch cache is stored on disk as UTF-8, but in the local
390 # charset internally 397 # charset internally
391 for k, v in partial.items(): 398 for k, v in partial.iteritems():
392 self.branchcache[util.tolocal(k)] = v 399 self.branchcache[util.tolocal(k)] = v
393 self._ubranchcache = partial
394 return self.branchcache 400 return self.branchcache
401
402
403 def branchtags(self):
404 '''return a dict where branch names map to the tipmost head of
405 the branch, open heads come before closed'''
406 bt = {}
407 for bn, heads in self._branchheads().iteritems():
408 head = None
409 for i in range(len(heads)-1, -1, -1):
410 h = heads[i]
411 if 'close' not in self.changelog.read(h)[5]:
412 head = h
413 break
414 # no open heads were found
415 if head is None:
416 head = heads[-1]
417 bt[bn] = head
418 return bt
419
395 420
396 def _readbranchcache(self): 421 def _readbranchcache(self):
397 partial = {} 422 partial = {}
398 try: 423 try:
399 f = self.opener("branch.cache") 424 f = self.opener("branchheads.cache")
400 lines = f.read().split('\n') 425 lines = f.read().split('\n')
401 f.close() 426 f.close()
402 except (IOError, OSError): 427 except (IOError, OSError):
403 return {}, nullid, nullrev 428 return {}, nullid, nullrev
404 429
409 # invalidate the cache 434 # invalidate the cache
410 raise ValueError('invalidating branch cache (tip differs)') 435 raise ValueError('invalidating branch cache (tip differs)')
411 for l in lines: 436 for l in lines:
412 if not l: continue 437 if not l: continue
413 node, label = l.split(" ", 1) 438 node, label = l.split(" ", 1)
414 partial[label.strip()] = bin(node) 439 partial.setdefault(label.strip(), []).append(bin(node))
415 except (KeyboardInterrupt, util.SignalInterrupt): 440 except KeyboardInterrupt:
416 raise 441 raise
417 except Exception, inst: 442 except Exception, inst:
418 if self.ui.debugflag: 443 if self.ui.debugflag:
419 self.ui.warn(str(inst), '\n') 444 self.ui.warn(str(inst), '\n')
420 partial, last, lrev = {}, nullid, nullrev 445 partial, last, lrev = {}, nullid, nullrev
421 return partial, last, lrev 446 return partial, last, lrev
422 447
423 def _writebranchcache(self, branches, tip, tiprev): 448 def _writebranchcache(self, branches, tip, tiprev):
424 try: 449 try:
425 f = self.opener("branch.cache", "w", atomictemp=True) 450 f = self.opener("branchheads.cache", "w", atomictemp=True)
426 f.write("%s %s\n" % (hex(tip), tiprev)) 451 f.write("%s %s\n" % (hex(tip), tiprev))
427 for label, node in branches.iteritems(): 452 for label, nodes in branches.iteritems():
428 f.write("%s %s\n" % (hex(node), label)) 453 for node in nodes:
454 f.write("%s %s\n" % (hex(node), label))
429 f.rename() 455 f.rename()
430 except (IOError, OSError): 456 except (IOError, OSError):
431 pass 457 pass
432 458
433 def _updatebranchcache(self, partial, start, end): 459 def _updatebranchcache(self, partial, start, end):
434 for r in xrange(start, end): 460 for r in xrange(start, end):
435 c = self[r] 461 c = self[r]
436 b = c.branch() 462 b = c.branch()
437 partial[b] = c.node() 463 bheads = partial.setdefault(b, [])
464 bheads.append(c.node())
465 for p in c.parents():
466 pn = p.node()
467 if pn in bheads:
468 bheads.remove(pn)
438 469
439 def lookup(self, key): 470 def lookup(self, key):
440 if isinstance(key, int): 471 if isinstance(key, int):
441 return self.changelog.node(key) 472 return self.changelog.node(key)
442 elif key == '.': 473 elif key == '.':
458 try: 489 try:
459 if len(key) == 20: 490 if len(key) == 20:
460 key = hex(key) 491 key = hex(key)
461 except: 492 except:
462 pass 493 pass
463 raise repo.RepoError(_("unknown revision '%s'") % key) 494 raise error.RepoError(_("unknown revision '%s'") % key)
464 495
465 def local(self): 496 def local(self):
466 return True 497 return True
467 498
468 def join(self, f): 499 def join(self, f):
564 if self._transref and self._transref(): 595 if self._transref and self._transref():
565 return self._transref().nest() 596 return self._transref().nest()
566 597
567 # abort here if the journal already exists 598 # abort here if the journal already exists
568 if os.path.exists(self.sjoin("journal")): 599 if os.path.exists(self.sjoin("journal")):
569 raise repo.RepoError(_("journal already exists - run hg recover")) 600 raise error.RepoError(_("journal already exists - run hg recover"))
570 601
571 # save dirstate for rollback 602 # save dirstate for rollback
572 try: 603 try:
573 ds = self.opener("dirstate").read() 604 ds = self.opener("dirstate").read()
574 except IOError: 605 except IOError:
635 self._branchcachetip = None 666 self._branchcachetip = None
636 667
637 def _lock(self, lockname, wait, releasefn, acquirefn, desc): 668 def _lock(self, lockname, wait, releasefn, acquirefn, desc):
638 try: 669 try:
639 l = lock.lock(lockname, 0, releasefn, desc=desc) 670 l = lock.lock(lockname, 0, releasefn, desc=desc)
640 except lock.LockHeld, inst: 671 except error.LockHeld, inst:
641 if not wait: 672 if not wait:
642 raise 673 raise
643 self.ui.warn(_("waiting for lock on %s held by %r\n") % 674 self.ui.warn(_("waiting for lock on %s held by %r\n") %
644 (desc, inst.locker)) 675 (desc, inst.locker))
645 # default to 600 seconds timeout 676 # default to 600 seconds timeout
747 778
748 def commit(self, files=None, text="", user=None, date=None, 779 def commit(self, files=None, text="", user=None, date=None,
749 match=None, force=False, force_editor=False, 780 match=None, force=False, force_editor=False,
750 p1=None, p2=None, extra={}, empty_ok=False): 781 p1=None, p2=None, extra={}, empty_ok=False):
751 wlock = lock = None 782 wlock = lock = None
783 if extra.get("close"):
784 force = True
752 if files: 785 if files:
753 files = util.unique(files) 786 files = util.unique(files)
754 try: 787 try:
755 wlock = self.wlock() 788 wlock = self.wlock()
756 lock = self.lock() 789 lock = self.lock()
924 del lines[0] 957 del lines[0]
925 if not lines and use_dirstate: 958 if not lines and use_dirstate:
926 raise util.Abort(_("empty commit message")) 959 raise util.Abort(_("empty commit message"))
927 text = '\n'.join(lines) 960 text = '\n'.join(lines)
928 961
962 self.changelog.delayupdate()
929 n = self.changelog.add(mn, changed + removed, text, trp, p1, p2, 963 n = self.changelog.add(mn, changed + removed, text, trp, p1, p2,
930 user, wctx.date(), extra) 964 user, wctx.date(), extra)
965 p = lambda: self.changelog.writepending() and self.root or ""
931 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1, 966 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
932 parent2=xp2) 967 parent2=xp2, pending=p)
968 self.changelog.finalize(trp)
933 tr.close() 969 tr.close()
934 970
935 if self.branchcache: 971 if self.branchcache:
936 self.branchtags() 972 self.branchtags()
937 973
1021 try: 1057 try:
1022 try: 1058 try:
1023 wlock = self.wlock(False) 1059 wlock = self.wlock(False)
1024 for f in fixup: 1060 for f in fixup:
1025 self.dirstate.normal(f) 1061 self.dirstate.normal(f)
1026 except lock.LockException: 1062 except lock.LockError:
1027 pass 1063 pass
1028 finally: 1064 finally:
1029 del wlock 1065 del wlock
1030 1066
1031 if not parentworking: 1067 if not parentworking:
1160 self.dirstate.add(dest) 1196 self.dirstate.add(dest)
1161 self.dirstate.copy(source, dest) 1197 self.dirstate.copy(source, dest)
1162 finally: 1198 finally:
1163 del wlock 1199 del wlock
1164 1200
1165 def heads(self, start=None): 1201 def heads(self, start=None, closed=True):
1166 heads = self.changelog.heads(start) 1202 heads = self.changelog.heads(start)
1203 def display(head):
1204 if closed:
1205 return True
1206 extras = self.changelog.read(head)[5]
1207 return ('close' not in extras)
1167 # sort the output in rev descending order 1208 # sort the output in rev descending order
1168 heads = [(-self.changelog.rev(h), h) for h in heads] 1209 heads = [(-self.changelog.rev(h), h) for h in heads if display(h)]
1169 return [n for (r, n) in util.sort(heads)] 1210 return [n for (r, n) in util.sort(heads)]
1170 1211
1171 def branchheads(self, branch=None, start=None): 1212 def branchheads(self, branch=None, start=None, closed=True):
1172 if branch is None: 1213 if branch is None:
1173 branch = self[None].branch() 1214 branch = self[None].branch()
1174 branches = self.branchtags() 1215 branches = self._branchheads()
1175 if branch not in branches: 1216 if branch not in branches:
1176 return [] 1217 return []
1177 # The basic algorithm is this: 1218 bheads = branches[branch]
1178 # 1219 # the cache returns heads ordered lowest to highest
1179 # Start from the branch tip since there are no later revisions that can 1220 bheads.reverse()
1180 # possibly be in this branch, and the tip is a guaranteed head.
1181 #
1182 # Remember the tip's parents as the first ancestors, since these by
1183 # definition are not heads.
1184 #
1185 # Step backwards from the brach tip through all the revisions. We are
1186 # guaranteed by the rules of Mercurial that we will now be visiting the
1187 # nodes in reverse topological order (children before parents).
1188 #
1189 # If a revision is one of the ancestors of a head then we can toss it
1190 # out of the ancestors set (we've already found it and won't be
1191 # visiting it again) and put its parents in the ancestors set.
1192 #
1193 # Otherwise, if a revision is in the branch it's another head, since it
1194 # wasn't in the ancestor list of an existing head. So add it to the
1195 # head list, and add its parents to the ancestor list.
1196 #
1197 # If it is not in the branch ignore it.
1198 #
1199 # Once we have a list of heads, use nodesbetween to filter out all the
1200 # heads that cannot be reached from startrev. There may be a more
1201 # efficient way to do this as part of the previous algorithm.
1202
1203 set = util.set
1204 heads = [self.changelog.rev(branches[branch])]
1205 # Don't care if ancestors contains nullrev or not.
1206 ancestors = set(self.changelog.parentrevs(heads[0]))
1207 for rev in xrange(heads[0] - 1, nullrev, -1):
1208 if rev in ancestors:
1209 ancestors.update(self.changelog.parentrevs(rev))
1210 ancestors.remove(rev)
1211 elif self[rev].branch() == branch:
1212 heads.append(rev)
1213 ancestors.update(self.changelog.parentrevs(rev))
1214 heads = [self.changelog.node(rev) for rev in heads]
1215 if start is not None: 1221 if start is not None:
1216 heads = self.changelog.nodesbetween([start], heads)[2] 1222 # filter out the heads that cannot be reached from startrev
1217 return heads 1223 bheads = self.changelog.nodesbetween([start], bheads)[2]
1224 if not closed:
1225 bheads = [h for h in bheads if
1226 ('close' not in self.changelog.read(h)[5])]
1227 return bheads
1218 1228
1219 def branches(self, nodes): 1229 def branches(self, nodes):
1220 if not nodes: 1230 if not nodes:
1221 nodes = [self.changelog.tip()] 1231 nodes = [self.changelog.tip()]
1222 b = [] 1232 b = []
1391 search = newsearch 1401 search = newsearch
1392 1402
1393 # sanity check our fetch list 1403 # sanity check our fetch list
1394 for f in fetch.keys(): 1404 for f in fetch.keys():
1395 if f in m: 1405 if f in m:
1396 raise repo.RepoError(_("already have changeset ") + short(f[:4])) 1406 raise error.RepoError(_("already have changeset ")
1407 + short(f[:4]))
1397 1408
1398 if base.keys() == [nullid]: 1409 if base.keys() == [nullid]:
1399 if force: 1410 if force:
1400 self.ui.warn(_("warning: repository is unrelated\n")) 1411 self.ui.warn(_("warning: repository is unrelated\n"))
1401 else: 1412 else:
1577 1588
1578 def changegroupinfo(self, nodes, source): 1589 def changegroupinfo(self, nodes, source):
1579 if self.ui.verbose or source == 'bundle': 1590 if self.ui.verbose or source == 'bundle':
1580 self.ui.status(_("%d changesets found\n") % len(nodes)) 1591 self.ui.status(_("%d changesets found\n") % len(nodes))
1581 if self.ui.debugflag: 1592 if self.ui.debugflag:
1582 self.ui.debug(_("List of changesets:\n")) 1593 self.ui.debug(_("list of changesets:\n"))
1583 for node in nodes: 1594 for node in nodes:
1584 self.ui.debug("%s\n" % hex(node)) 1595 self.ui.debug("%s\n" % hex(node))
1585 1596
1586 def changegroupsubset(self, bases, heads, source, extranodes=None): 1597 def changegroupsubset(self, bases, heads, source, extranodes=None):
1587 """This function generates a changegroup consisting of all the nodes 1598 """This function generates a changegroup consisting of all the nodes
1754 if r == next_rev[0]: 1765 if r == next_rev[0]:
1755 # If the last rev we looked at was the one just previous, 1766 # If the last rev we looked at was the one just previous,
1756 # we only need to see a diff. 1767 # we only need to see a diff.
1757 deltamf = mnfst.readdelta(mnfstnode) 1768 deltamf = mnfst.readdelta(mnfstnode)
1758 # For each line in the delta 1769 # For each line in the delta
1759 for f, fnode in deltamf.items(): 1770 for f, fnode in deltamf.iteritems():
1760 f = changedfiles.get(f, None) 1771 f = changedfiles.get(f, None)
1761 # And if the file is in the list of files we care 1772 # And if the file is in the list of files we care
1762 # about. 1773 # about.
1763 if f is not None: 1774 if f is not None:
1764 # Get the changenode this manifest belongs to 1775 # Get the changenode this manifest belongs to
2028 if fl.addgroup(chunkiter, revmap, trp) is None: 2039 if fl.addgroup(chunkiter, revmap, trp) is None:
2029 raise util.Abort(_("received file revlog group is empty")) 2040 raise util.Abort(_("received file revlog group is empty"))
2030 revisions += len(fl) - o 2041 revisions += len(fl) - o
2031 files += 1 2042 files += 1
2032 2043
2033 # make changelog see real files again
2034 cl.finalize(trp)
2035
2036 newheads = len(self.changelog.heads()) 2044 newheads = len(self.changelog.heads())
2037 heads = "" 2045 heads = ""
2038 if oldheads and newheads != oldheads: 2046 if oldheads and newheads != oldheads:
2039 heads = _(" (%+d heads)") % (newheads - oldheads) 2047 heads = _(" (%+d heads)") % (newheads - oldheads)
2040 2048
2041 self.ui.status(_("added %d changesets" 2049 self.ui.status(_("added %d changesets"
2042 " with %d changes to %d files%s\n") 2050 " with %d changes to %d files%s\n")
2043 % (changesets, revisions, files, heads)) 2051 % (changesets, revisions, files, heads))
2044 2052
2045 if changesets > 0: 2053 if changesets > 0:
2054 p = lambda: self.changelog.writepending() and self.root or ""
2046 self.hook('pretxnchangegroup', throw=True, 2055 self.hook('pretxnchangegroup', throw=True,
2047 node=hex(self.changelog.node(cor+1)), source=srctype, 2056 node=hex(self.changelog.node(cor+1)), source=srctype,
2048 url=url) 2057 url=url, pending=p)
2058
2059 # make changelog see real files again
2060 cl.finalize(trp)
2049 2061
2050 tr.close() 2062 tr.close()
2051 finally: 2063 finally:
2052 del tr 2064 del tr
2053 2065
2073 fp = remote.stream_out() 2085 fp = remote.stream_out()
2074 l = fp.readline() 2086 l = fp.readline()
2075 try: 2087 try:
2076 resp = int(l) 2088 resp = int(l)
2077 except ValueError: 2089 except ValueError:
2078 raise util.UnexpectedOutput( 2090 raise error.ResponseError(
2079 _('Unexpected response from remote server:'), l) 2091 _('Unexpected response from remote server:'), l)
2080 if resp == 1: 2092 if resp == 1:
2081 raise util.Abort(_('operation forbidden by server')) 2093 raise util.Abort(_('operation forbidden by server'))
2082 elif resp == 2: 2094 elif resp == 2:
2083 raise util.Abort(_('locking the remote repository failed')) 2095 raise util.Abort(_('locking the remote repository failed'))
2086 self.ui.status(_('streaming all changes\n')) 2098 self.ui.status(_('streaming all changes\n'))
2087 l = fp.readline() 2099 l = fp.readline()
2088 try: 2100 try:
2089 total_files, total_bytes = map(int, l.split(' ', 1)) 2101 total_files, total_bytes = map(int, l.split(' ', 1))
2090 except (ValueError, TypeError): 2102 except (ValueError, TypeError):
2091 raise util.UnexpectedOutput( 2103 raise error.ResponseError(
2092 _('Unexpected response from remote server:'), l) 2104 _('Unexpected response from remote server:'), l)
2093 self.ui.status(_('%d files to transfer, %s of data\n') % 2105 self.ui.status(_('%d files to transfer, %s of data\n') %
2094 (total_files, util.bytecount(total_bytes))) 2106 (total_files, util.bytecount(total_bytes)))
2095 start = time.time() 2107 start = time.time()
2096 for i in xrange(total_files): 2108 for i in xrange(total_files):
2098 l = fp.readline() 2110 l = fp.readline()
2099 try: 2111 try:
2100 name, size = l.split('\0', 1) 2112 name, size = l.split('\0', 1)
2101 size = int(size) 2113 size = int(size)
2102 except (ValueError, TypeError): 2114 except (ValueError, TypeError):
2103 raise util.UnexpectedOutput( 2115 raise error.ResponseError(
2104 _('Unexpected response from remote server:'), l) 2116 _('Unexpected response from remote server:'), l)
2105 self.ui.debug(_('adding %s (%s)\n') % (name, util.bytecount(size))) 2117 self.ui.debug(_('adding %s (%s)\n') % (name, util.bytecount(size)))
2106 ofp = self.sopener(name, 'w') 2118 ofp = self.sopener(name, 'w')
2107 for chunk in util.filechunkiter(fp, limit=size): 2119 for chunk in util.filechunkiter(fp, limit=size):
2108 ofp.write(chunk) 2120 ofp.write(chunk)