comparison mercurial/hg.py @ 222:87484f627422

make pull work for multiple heads -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 make pull work for multiple heads add repository.heads() teach remoterepository and hgweb about heads command teach getchangegroup about multiple heads break apart addchangegroup and merge (cleaning up merge saved for later) after this change, it is now possible to pull and get multiple heads, but not possible to merge the heads manifest hash: 86fe3ede296254698fdd4c97df02944993ef2cbb -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCn8SZywK+sNU5EO8RAkSvAJ9NOA4UZ3cFyyzymlYBZnV+PpGRcACeLL+R PFaSgJHGKvxsXpvPYiZA0O0= =L2Xr -----END PGP SIGNATURE-----
author mpm@selenic.com
date Thu, 02 Jun 2005 18:46:49 -0800
parents 3113a94c1bff
children 1aaa49039a6b
comparison
equal deleted inserted replaced
221:2bfe525ef6ca 222:87484f627422
592 elif f not in self.dirstate: 592 elif f not in self.dirstate:
593 self.ui.warn("%s not tracked!\n" % f) 593 self.ui.warn("%s not tracked!\n" % f)
594 else: 594 else:
595 self.dirstate.update([f], "r") 595 self.dirstate.update([f], "r")
596 596
597 def heads(self):
598 return self.changelog.heads()
599
597 def branches(self, nodes): 600 def branches(self, nodes):
598 if not nodes: nodes = [self.changelog.tip()] 601 if not nodes: nodes = [self.changelog.tip()]
599 b = [] 602 b = []
600 for n in nodes: 603 for n in nodes:
601 t = n 604 t = n
657 search = [] 660 search = []
658 fetch = [] 661 fetch = []
659 seen = {} 662 seen = {}
660 seenbranch = {} 663 seenbranch = {}
661 664
662 self.ui.status("searching for changes\n")
663 tip = remote.branches([])[0]
664 self.ui.debug("remote tip branch is %s:%s\n" %
665 (short(tip[0]), short(tip[1])))
666
667 # if we have an empty repo, fetch everything 665 # if we have an empty repo, fetch everything
668 if self.changelog.tip() == nullid: 666 if self.changelog.tip() == nullid:
667 self.ui.status("requesting all changes\n")
669 return remote.changegroup([nullid]) 668 return remote.changegroup([nullid])
670 669
671 # otherwise, assume we're closer to the tip than the root 670 # otherwise, assume we're closer to the tip than the root
672 unknown = [tip] 671 self.ui.status("searching for changes\n")
673 672 heads = remote.heads()
674 if tip[0] in m: 673 unknown = []
674 for h in heads:
675 if h not in m:
676 unknown.append(h)
677
678 if not unknown:
675 self.ui.status("nothing to do!\n") 679 self.ui.status("nothing to do!\n")
676 return None 680 return None
677 681
682 unknown = remote.branches(unknown)
678 while unknown: 683 while unknown:
679 n = unknown.pop(0) 684 n = unknown.pop(0)
680 seen[n[0]] = 1 685 seen[n[0]] = 1
681 686
682 self.ui.debug("examining %s:%s\n" % (short(n[0]), short(n[1]))) 687 self.ui.debug("examining %s:%s\n" % (short(n[0]), short(n[1])))
764 g = self.file(f).group(linkmap) 769 g = self.file(f).group(linkmap)
765 for y in g: 770 for y in g:
766 yield y 771 yield y
767 772
768 def addchangegroup(self, generator): 773 def addchangegroup(self, generator):
774
775 class genread:
776 def __init__(self, generator):
777 self.g = generator
778 self.buf = ""
779 def read(self, l):
780 while l > len(self.buf):
781 try:
782 self.buf += self.g.next()
783 except StopIteration:
784 break
785 d, self.buf = self.buf[:l], self.buf[l:]
786 return d
787
788 def getchunk():
789 d = source.read(4)
790 if not d: return ""
791 l = struct.unpack(">l", d)[0]
792 if l <= 4: return ""
793 return source.read(l - 4)
794
795 def getgroup():
796 while 1:
797 c = getchunk()
798 if not c: break
799 yield c
800
801 def csmap(x):
802 self.ui.debug("add changeset %s\n" % short(x))
803 return self.changelog.count()
804
805 def revmap(x):
806 return self.changelog.rev(x)
807
808 if not generator: return
809 changesets = files = revisions = 0
810 self.lock()
811 source = genread(generator)
812 tr = self.transaction()
813
814 # pull off the changeset group
815 self.ui.status("adding changesets\n")
816 co = self.changelog.tip()
817 cn = self.changelog.addgroup(getgroup(), csmap, tr)
818 changesets = self.changelog.rev(cn) - self.changelog.rev(co)
819
820 # pull off the manifest group
821 self.ui.status("adding manifests\n")
822 mm = self.manifest.tip()
823 mo = self.manifest.addgroup(getgroup(), revmap, tr)
824
825 # process the files
826 self.ui.status("adding file revisions\n")
827 while 1:
828 f = getchunk()
829 if not f: break
830 self.ui.debug("adding %s revisions\n" % f)
831 fl = self.file(f)
832 o = fl.tip()
833 n = fl.addgroup(getgroup(), revmap, tr)
834 revisions += fl.rev(n) - fl.rev(o)
835 files += 1
836
837 self.ui.status(("modified %d files, added %d changesets" +
838 " and %d new revisions\n")
839 % (files, changesets, revisions))
840
841 tr.close()
842 return
843
844 def merge(self, generator):
769 changesets = files = revisions = 0 845 changesets = files = revisions = 0
770 846
771 self.lock() 847 self.lock()
772 class genread: 848 class genread:
773 def __init__(self, generator): 849 def __init__(self, generator):
978 q.update(args) 1054 q.update(args)
979 qs = urllib.urlencode(q) 1055 qs = urllib.urlencode(q)
980 cu = "%s?%s" % (self.url, qs) 1056 cu = "%s?%s" % (self.url, qs)
981 return urllib.urlopen(cu) 1057 return urllib.urlopen(cu)
982 1058
1059 def heads(self):
1060 d = self.do_cmd("heads").read()
1061 try:
1062 return map(bin, d[:-1].split(" "))
1063 except:
1064 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n")
1065 raise
1066
983 def branches(self, nodes): 1067 def branches(self, nodes):
984 n = " ".join(map(hex, nodes)) 1068 n = " ".join(map(hex, nodes))
985 d = self.do_cmd("branches", nodes=n).read() 1069 d = self.do_cmd("branches", nodes=n).read()
986 try: 1070 try:
987 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ] 1071 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]