comparison mercurial/hg.py @ 46:93e868fa0db8

Add changegroup support
author mpm@selenic.com
date Tue, 10 May 2005 00:40:49 -0800
parents e825a68d7227
children 9f64181ff9a9
comparison
equal deleted inserted replaced
45:f2b2d5daec30 46:93e868fa0db8
556 556
557 def remove(self, list): 557 def remove(self, list):
558 dl = self.opener("to-remove", "a") 558 dl = self.opener("to-remove", "a")
559 for f in list: 559 for f in list:
560 dl.write(f + "\n") 560 dl.write(f + "\n")
561
562 def newer(self, node):
563 nodes = []
564 for i in xrange(self.changelog.rev(node) + 1, self.changelog.count()):
565 nodes.append(self.changelog.node(i))
566
567 return nodes
568
569 def changegroup(self, nodes):
570 # construct the link map
571 linkmap = {}
572 for n in nodes:
573 linkmap[self.changelog.rev(n)] = n
574
575 # construct a list of all changed files
576 changed = {}
577 for n in nodes:
578 c = self.changelog.read(n)
579 for f in c[3]:
580 changed[f] = 1
581 changed = changed.keys()
582 changed.sort()
583
584 # the changegroup is changesets + manifests + all file revs
585 cg = []
586 revs = [ self.changelog.rev(n) for n in nodes ]
587
588 g = self.changelog.group(linkmap)
589 cg.append(g)
590 g = self.manifest.group(linkmap)
591 cg.append(g)
592
593 for f in changed:
594 g = self.file(f).group(linkmap)
595 if not g: raise "couldn't find change to %s" % f
596 l = struct.pack(">l", len(f))
597 cg += [l, f, g]
598
599 return compress("".join(cg))
600
601 def addchangegroup(self, data):
602 data = decompress(data)
603 def getlen(data, pos):
604 return struct.unpack(">l", data[pos:pos + 4])[0]
605
606 tr = self.transaction()
607 simple = True
608
609 print "merging changesets"
610 # pull off the changeset group
611 l = getlen(data, 0)
612 csg = data[0:l]
613 pos = l
614 co = self.changelog.tip()
615 cn = self.changelog.addgroup(csg, lambda x: self.changelog.count(), tr)
616
617 print "merging manifests"
618 # pull off the manifest group
619 l = getlen(data, pos)
620 mfg = data[pos: pos + l]
621 pos += l
622 mo = self.manifest.tip()
623 mn = self.manifest.addgroup(mfg, lambda x: self.changelog.rev(x), tr)
624
625 # do we need a resolve?
626 if self.changelog.ancestor(co, cn) != co:
627 print "NEED RESOLVE"
628 simple = False
629 resolverev = self.changelog.count()
630
631 # process the files
632 print "merging files"
633 new = {}
634 while pos < len(data):
635 l = getlen(data, pos)
636 pos += 4
637 f = data[pos:pos + l]
638 pos += l
639
640 l = getlen(data, pos)
641 fg = data[pos: pos + l]
642 pos += l
643
644 fl = self.file(f)
645 o = fl.tip()
646 n = fl.addgroup(fg, lambda x: self.changelog.rev(x), tr)
647 if not simple:
648 new[fl] = fl.resolvedag(o, n, tr, resolverev)
649
650 # For simple merges, we don't need to resolve manifests or changesets
651 if simple:
652 tr.close()
653 return
654
655 # resolve the manifest to point to all the merged files
656 self.ui.status("resolving manifests\n")
657 ma = self.manifest.ancestor(mm, mo)
658 mmap = self.manifest.read(mm) # mine
659 omap = self.manifest.read(mo) # other
660 amap = self.manifest.read(ma) # ancestor
661 nmap = {}
662
663 for f, mid in mmap.iteritems():
664 if f in omap:
665 if mid != omap[f]:
666 nmap[f] = new.get(f, mid) # use merged version
667 else:
668 nmap[f] = new.get(f, mid) # they're the same
669 del omap[f]
670 elif f in amap:
671 if mid != amap[f]:
672 pass # we should prompt here
673 else:
674 pass # other deleted it
675 else:
676 nmap[f] = new.get(f, mid) # we created it
677
678 del mmap
679
680 for f, oid in omap.iteritems():
681 if f in amap:
682 if oid != amap[f]:
683 pass # this is the nasty case, we should prompt
684 else:
685 pass # probably safe
686 else:
687 nmap[f] = new.get(f, oid) # remote created it
688
689 del omap
690 del amap
691
692 node = self.manifest.add(nmap, tr, resolverev, mm, mo)
693
694 # Now all files and manifests are merged, we add the changed files
695 # and manifest id to the changelog
696 self.ui.status("committing merge changeset\n")
697 new = new.keys()
698 new.sort()
699 if co == cn: cn = -1
700
701 edittext = "\n"+"".join(["HG: changed %s\n" % f for f in new])
702 edittext = self.ui.edit(edittext)
703 n = self.changelog.add(node, new, edittext, tr, co, cn)
704
705 tr.close()
561 706
562 class ui: 707 class ui:
563 def __init__(self, verbose=False, debug=False): 708 def __init__(self, verbose=False, debug=False):
564 self.verbose = verbose 709 self.verbose = verbose
565 def write(self, *args): 710 def write(self, *args):