comparison mercurial/hg.py @ 192:5d8553352d2e

Changes to network protocol -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Changes to network protocol Stream changes at the delta level rather than at whole delta groups this breaks the protocol - we now send a zero byte delta to indicate the end of a group rather than sending the entire group length up front Fix filename length asymmetry while we're breaking things Fix hidden O(n^2) bug in calculating changegroup list.append(e) is O(n), list + [element] is not Decompress chunks on read in revlog.group() Improve status messages report bytes transferred report nothing to do Deal with /dev/null path brokenness Remove untriggered patch assertion manifest hash: 3eedcfe878561f9eb4adedb04f6be618fb8ae8d8 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCmzlqywK+sNU5EO8RAn0KAJ4z4toWSSGjLoZO6FKWLx/3QbZufACglQgd S48bumc++DnuY1iPSNWKGAI= =lCjx -----END PGP SIGNATURE-----
author mpm@selenic.com
date Mon, 30 May 2005 08:03:54 -0800
parents d7e859cf2f1b
children 2424676edd8c
comparison
equal deleted inserted replaced
191:d7e859cf2f1b 192:5d8553352d2e
289 289
290 def join(self, f): 290 def join(self, f):
291 return os.path.join(self.path, f) 291 return os.path.join(self.path, f)
292 292
293 def file(self, f): 293 def file(self, f):
294 if f[0] == '/': f = f[1:]
294 return filelog(self.opener, f) 295 return filelog(self.opener, f)
295 296
296 def transaction(self): 297 def transaction(self):
297 return transaction(self.opener, self.join("journal"), 298 return transaction(self.opener, self.join("journal"),
298 self.join("undo")) 299 self.join("undo"))
528 m = self.changelog.nodemap 529 m = self.changelog.nodemap
529 search = [] 530 search = []
530 fetch = [] 531 fetch = []
531 seen = {} 532 seen = {}
532 seenbranch = {} 533 seenbranch = {}
534
535 self.ui.status("searching for changes\n")
533 tip = remote.branches([])[0] 536 tip = remote.branches([])[0]
534 self.ui.debug("remote tip branch is %s:%s\n" % 537 self.ui.debug("remote tip branch is %s:%s\n" %
535 (short(tip[0]), short(tip[1]))) 538 (short(tip[0]), short(tip[1])))
536 539
537 # if we have an empty repo, fetch everything 540 # if we have an empty repo, fetch everything
540 543
541 # otherwise, assume we're closer to the tip than the root 544 # otherwise, assume we're closer to the tip than the root
542 unknown = [tip] 545 unknown = [tip]
543 546
544 if tip[0] in m: 547 if tip[0] in m:
545 self.ui.note("nothing to do!\n") 548 self.ui.status("nothing to do!\n")
546 return None 549 return None
547 550
548 while unknown: 551 while unknown:
549 n = unknown.pop(0) 552 n = unknown.pop(0)
550 seen[n[0]] = 1 553 seen[n[0]] = 1
625 changed.sort() 628 changed.sort()
626 629
627 # the changegroup is changesets + manifests + all file revs 630 # the changegroup is changesets + manifests + all file revs
628 revs = [ self.changelog.rev(n) for n in nodes ] 631 revs = [ self.changelog.rev(n) for n in nodes ]
629 632
630 yield self.changelog.group(linkmap) 633 for y in self.changelog.group(linkmap): yield y
631 yield self.manifest.group(linkmap) 634 for y in self.manifest.group(linkmap): yield y
632
633 for f in changed: 635 for f in changed:
636 yield struct.pack(">l", len(f) + 4) + f
634 g = self.file(f).group(linkmap) 637 g = self.file(f).group(linkmap)
635 if not g: raise "couldn't find change to %s" % f 638 for y in g:
636 l = struct.pack(">l", len(f)) 639 yield y
637 yield "".join([l, f, g])
638 640
639 def addchangegroup(self, generator): 641 def addchangegroup(self, generator):
640 changesets = files = revisions = 0 642 changesets = files = revisions = 0
641 643
642 self.lock() 644 self.lock()
654 return d 656 return d
655 657
656 if not generator: return 658 if not generator: return
657 source = genread(generator) 659 source = genread(generator)
658 660
659 def getchunk(add = 0): 661 def getchunk():
660 d = source.read(4) 662 d = source.read(4)
661 if not d: return "" 663 if not d: return ""
662 l = struct.unpack(">l", d)[0] 664 l = struct.unpack(">l", d)[0]
663 return source.read(l - 4 + add) 665 if l <= 4: return ""
666 return source.read(l - 4)
667
668 def getgroup():
669 while 1:
670 c = getchunk()
671 if not c: break
672 yield c
664 673
665 tr = self.transaction() 674 tr = self.transaction()
666 simple = True 675 simple = True
667 need = {} 676 need = {}
668 677
669 self.ui.status("adding changesets\n") 678 self.ui.status("adding changesets\n")
670 # pull off the changeset group 679 # pull off the changeset group
671 def report(x): 680 def report(x):
672 self.ui.debug("add changeset %s\n" % short(x)) 681 self.ui.debug("add changeset %s\n" % short(x))
673 return self.changelog.count() 682 return self.changelog.count()
674 683
675 csg = getchunk()
676 co = self.changelog.tip() 684 co = self.changelog.tip()
677 cn = self.changelog.addgroup(csg, report, tr) 685 cn = self.changelog.addgroup(getgroup(), report, tr)
678 686
679 revisions = self.changelog.rev(cn) - self.changelog.rev(co) 687 changesets = self.changelog.rev(cn) - self.changelog.rev(co)
680 changesets = revisions
681 688
682 self.ui.status("adding manifests\n") 689 self.ui.status("adding manifests\n")
683 # pull off the manifest group 690 # pull off the manifest group
684 mfg = getchunk()
685 mm = self.manifest.tip() 691 mm = self.manifest.tip()
686 mo = self.manifest.addgroup(mfg, lambda x: self.changelog.rev(x), tr) 692 mo = self.manifest.addgroup(getgroup(),
687 693 lambda x: self.changelog.rev(x), tr)
688 revisions += self.manifest.rev(mo) - self.manifest.rev(mm)
689 694
690 # do we need a resolve? 695 # do we need a resolve?
691 if self.changelog.ancestor(co, cn) != co: 696 if self.changelog.ancestor(co, cn) != co:
692 simple = False 697 simple = False
693 resolverev = self.changelog.count() 698 resolverev = self.changelog.count()
747 new.sort() 752 new.sort()
748 753
749 # process the files 754 # process the files
750 self.ui.status("adding files\n") 755 self.ui.status("adding files\n")
751 while 1: 756 while 1:
752 f = getchunk(4) 757 f = getchunk()
753 if not f: break 758 if not f: break
754 fg = getchunk()
755 self.ui.debug("adding %s revisions\n" % f) 759 self.ui.debug("adding %s revisions\n" % f)
756 fl = self.file(f) 760 fl = self.file(f)
757 o = fl.tip() 761 o = fl.tip()
758 n = fl.addgroup(fg, lambda x: self.changelog.rev(x), tr) 762 n = fl.addgroup(getgroup(), lambda x: self.changelog.rev(x), tr)
759 revisions += fl.rev(n) - fl.rev(o) 763 revisions += fl.rev(n) - fl.rev(o)
760 files += 1 764 files += 1
761 if f in need: 765 if f in need:
762 del need[f] 766 del need[f]
763 # manifest resolve determined we need to merge the tips 767 # manifest resolve determined we need to merge the tips
772 revisions += 1 776 revisions += 1
773 777
774 # For simple merges, we don't need to resolve manifests or changesets 778 # For simple merges, we don't need to resolve manifests or changesets
775 if simple: 779 if simple:
776 self.ui.debug("simple merge, skipping resolve\n") 780 self.ui.debug("simple merge, skipping resolve\n")
777 self.ui.status(("added %d changesets, %d files," + 781 self.ui.status(("modified %d files, added %d changesets" +
778 " and %d new revisions\n") 782 " and %d new revisions\n")
779 % (changesets, files, revisions)) 783 % (files, changesets, revisions))
780 tr.close() 784 tr.close()
781 return 785 return
782 786
783 node = self.manifest.add(nmap, tr, resolverev, mm, mo) 787 node = self.manifest.add(nmap, tr, resolverev, mm, mo)
784 revisions += 1 788 revisions += 1
863 867
864 def changegroup(self, nodes): 868 def changegroup(self, nodes):
865 n = " ".join(map(hex, nodes)) 869 n = " ".join(map(hex, nodes))
866 zd = zlib.decompressobj() 870 zd = zlib.decompressobj()
867 f = self.do_cmd("changegroup", roots=n) 871 f = self.do_cmd("changegroup", roots=n)
872 bytes = 0
868 while 1: 873 while 1:
869 d = f.read(4096) 874 d = f.read(4096)
875 bytes += len(d)
870 if not d: 876 if not d:
871 yield zd.flush() 877 yield zd.flush()
872 break 878 break
873 yield zd.decompress(d) 879 yield zd.decompress(d)
880 self.ui.note("%d bytes of data transfered\n" % bytes)
874 881
875 def repository(ui, path=None, create=0): 882 def repository(ui, path=None, create=0):
876 if path and path[:7] == "http://": 883 if path and path[:7] == "http://":
877 return remoterepository(ui, path) 884 return remoterepository(ui, path)
878 if path and path[:5] == "hg://": 885 if path and path[:5] == "hg://":